home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume2 / mines.shr / board.c < prev    next >
C/C++ Source or Header  |  1987-11-20  |  4KB  |  180 lines

  1. /*
  2.  * manage the board state
  3.  *
  4.  * Copyright (c) 1987 Tom Anderson; 20831 Frank Waters Road;
  5.  * Stanwood, WA  98282.   All rights reserved.
  6.  */
  7. static char copyright[] = "Copyright 1987 Tom Anderson";
  8.  
  9. #include <stdio.h>
  10. #include <strings.h>
  11. #include <sys/types.h>
  12.  
  13. #include "mines.h"
  14.  
  15. Square MainBoard[SIDE_SIZE][SIDE_SIZE];
  16. BoardCoordinate PlayerLocation;
  17. BOOL GameOver;
  18.  
  19. /*
  20.  * set up the playing surface at the beginning of the game
  21.  */
  22. void
  23. InitBoard(level)
  24.     int level;            /* number of mines */
  25. {
  26.     register int i, j, minesPlaced, cutoff;
  27.     register Square * sqp;
  28.     int pass = 0;
  29.     BOOL connected;
  30.  
  31.     /* 
  32.      * retry mine placement until a route can be had from the entry to
  33.      * the exit (this needs work)
  34.      */
  35.     do {
  36.     /*
  37.      * zero the board 
  38.      */
  39.     for (i = 0 ; i < SIDE_SIZE ; i++) {
  40.         for (j = 0 ; j < SIDE_SIZE ; j++) {
  41.         sqp = &MainBoard[i][j];
  42.         sqp->traversed = sqp->mined = sqp->occupied 
  43.             = sqp->unsafe = sqp->safe = FALSE;
  44.         }
  45.     }
  46.     /*
  47.      * make several passes over the board, placing mines at
  48.      * a probability calculated to require about 3 passes on the average
  49.      */
  50.     cutoff = level / 3 + 1;
  51.     for (minesPlaced = 0 ; minesPlaced < level ; ) {
  52.         for (i = 0 ; i < SIDE_SIZE ; i++) {
  53.         for (j = 0 ; j < SIDE_SIZE ; j++) {
  54.             if ((random() % (SIDE_SIZE * SIDE_SIZE)) < cutoff
  55.             && ! MainBoard[i][j].mined
  56.             && minesPlaced < level
  57.             && ! (i <= 1 && j <= 1)
  58.             && ! (i == SIDE_SIZE-1 && j == SIDE_SIZE-1)) {
  59.             MainBoard[i][j].mined = TRUE;
  60.             minesPlaced++;
  61.             }
  62.         }
  63.         }
  64.     }
  65.     connected = TRUE;    /* ignore impossible mazes for now */
  66.     } while ( ! connected);
  67.     PlayerLocation.x = PlayerLocation.y = 0;
  68.     MainBoard[0][0].occupied = MainBoard[0][0].traversed = TRUE;
  69.     GameOver = FALSE;
  70. }
  71.  
  72. /*
  73.  * describe the state of the board square at x, y
  74.  */
  75. Square *
  76. GetSquare(bloc)
  77.     BoardCoordinate * bloc;
  78. {
  79.     return (&MainBoard[bloc->y][bloc->x]);
  80. }
  81.  
  82. /*
  83.  * toggle a square's marking as being probably safe or unsafe
  84.  */
  85. void
  86. MarkSquare(suspect, safe)
  87.     BoardCoordinate * suspect;
  88.     BOOL safe;
  89. {
  90.     register Square * sqp = &MainBoard[suspect->y][suspect->x];
  91.  
  92.     if (sqp->traversed)
  93.     return;
  94.     if (safe) {
  95.     sqp->safe = ! sqp->safe;
  96.     sqp->unsafe = FALSE;
  97.     } else {
  98.     sqp->unsafe = ! sqp->unsafe;
  99.     sqp->safe = FALSE;
  100.     }
  101.     DrawSquare(suspect);
  102. }
  103.  
  104.  
  105. /*
  106.  * try to move to a certain board coordinate
  107.  */
  108. void 
  109. DoMove(dest)
  110.     BoardCoordinate * dest;
  111. {
  112.     register int y, x;
  113.     register Square * sqp;
  114.  
  115.     /*
  116.      * if not adjacent to or equal to our current position
  117.      * or the destination has been marked unsafe, ignore the move 
  118.      */
  119.     if (abs(dest->x - (x = PlayerLocation.x)) > 1
  120.     || abs(dest->y - (y = PlayerLocation.y)) > 1
  121.     || (dest->x == PlayerLocation.x && dest->y == PlayerLocation.y)
  122.     || MainBoard[dest->y][dest->x].unsafe)
  123.     return;
  124.     /*
  125.      * step off our current square
  126.      */
  127.     MainBoard[y][x].occupied = FALSE;
  128.     DrawSquare(&PlayerLocation);
  129.     sqp = &MainBoard[dest->y][dest->x];
  130.     /*
  131.      * if we stepped on a mine, blow him up
  132.      */
  133.     if (sqp->mined) {
  134.     GameOver = TRUE;
  135.     Message("You just exploded");
  136.     DrawBoard();
  137.     }
  138.     /*
  139.      * else if this is home, render congratulations
  140.      */
  141.     else if (dest->x == SIDE_SIZE-1 && dest->y == SIDE_SIZE-1) {
  142.     PlayerLocation = * dest;
  143.     sqp->traversed = sqp->occupied = TRUE;
  144.     GameOver = TRUE;
  145.     Message("You made it!");
  146.     DrawBoard();
  147.     }
  148.     /*
  149.      * else move onto the new square
  150.      */
  151.     else {
  152.     PlayerLocation = * dest;
  153.     sqp->traversed = sqp->occupied = TRUE;
  154.     DrawSquare(dest);
  155.     Message(MineWarningMessage());
  156.     }
  157. }
  158.  
  159. /*
  160.  * return a pointer to the warning message
  161.  */
  162. char *
  163. MineWarningMessage()
  164. {
  165.     static char warning[128];
  166.     register int x, y;
  167.     int minesFound;
  168.  
  169.     minesFound = 0;
  170.     for (x = PlayerLocation.x - 1 ; x <= PlayerLocation.x + 1 ; x++) {
  171.     for (y = PlayerLocation.y - 1 ; y <= PlayerLocation.y + 1 ; y++) {
  172.         if (x >= 0 && x < SIDE_SIZE && y >= 0 && y < SIDE_SIZE && MainBoard[y][x].mined)
  173.         minesFound++;
  174.     }
  175.     }
  176.     sprintf(warning, "%d mine(s) nearby", minesFound);
  177.     return(warning);
  178. }
  179.  
  180.