home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
games
/
volume2
/
mines.shr
/
board.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-11-20
|
4KB
|
180 lines
/*
* manage the board state
*
* Copyright (c) 1987 Tom Anderson; 20831 Frank Waters Road;
* Stanwood, WA 98282. All rights reserved.
*/
static char copyright[] = "Copyright 1987 Tom Anderson";
#include <stdio.h>
#include <strings.h>
#include <sys/types.h>
#include "mines.h"
Square MainBoard[SIDE_SIZE][SIDE_SIZE];
BoardCoordinate PlayerLocation;
BOOL GameOver;
/*
* set up the playing surface at the beginning of the game
*/
void
InitBoard(level)
int level; /* number of mines */
{
register int i, j, minesPlaced, cutoff;
register Square * sqp;
int pass = 0;
BOOL connected;
/*
* retry mine placement until a route can be had from the entry to
* the exit (this needs work)
*/
do {
/*
* zero the board
*/
for (i = 0 ; i < SIDE_SIZE ; i++) {
for (j = 0 ; j < SIDE_SIZE ; j++) {
sqp = &MainBoard[i][j];
sqp->traversed = sqp->mined = sqp->occupied
= sqp->unsafe = sqp->safe = FALSE;
}
}
/*
* make several passes over the board, placing mines at
* a probability calculated to require about 3 passes on the average
*/
cutoff = level / 3 + 1;
for (minesPlaced = 0 ; minesPlaced < level ; ) {
for (i = 0 ; i < SIDE_SIZE ; i++) {
for (j = 0 ; j < SIDE_SIZE ; j++) {
if ((random() % (SIDE_SIZE * SIDE_SIZE)) < cutoff
&& ! MainBoard[i][j].mined
&& minesPlaced < level
&& ! (i <= 1 && j <= 1)
&& ! (i == SIDE_SIZE-1 && j == SIDE_SIZE-1)) {
MainBoard[i][j].mined = TRUE;
minesPlaced++;
}
}
}
}
connected = TRUE; /* ignore impossible mazes for now */
} while ( ! connected);
PlayerLocation.x = PlayerLocation.y = 0;
MainBoard[0][0].occupied = MainBoard[0][0].traversed = TRUE;
GameOver = FALSE;
}
/*
* describe the state of the board square at x, y
*/
Square *
GetSquare(bloc)
BoardCoordinate * bloc;
{
return (&MainBoard[bloc->y][bloc->x]);
}
/*
* toggle a square's marking as being probably safe or unsafe
*/
void
MarkSquare(suspect, safe)
BoardCoordinate * suspect;
BOOL safe;
{
register Square * sqp = &MainBoard[suspect->y][suspect->x];
if (sqp->traversed)
return;
if (safe) {
sqp->safe = ! sqp->safe;
sqp->unsafe = FALSE;
} else {
sqp->unsafe = ! sqp->unsafe;
sqp->safe = FALSE;
}
DrawSquare(suspect);
}
/*
* try to move to a certain board coordinate
*/
void
DoMove(dest)
BoardCoordinate * dest;
{
register int y, x;
register Square * sqp;
/*
* if not adjacent to or equal to our current position
* or the destination has been marked unsafe, ignore the move
*/
if (abs(dest->x - (x = PlayerLocation.x)) > 1
|| abs(dest->y - (y = PlayerLocation.y)) > 1
|| (dest->x == PlayerLocation.x && dest->y == PlayerLocation.y)
|| MainBoard[dest->y][dest->x].unsafe)
return;
/*
* step off our current square
*/
MainBoard[y][x].occupied = FALSE;
DrawSquare(&PlayerLocation);
sqp = &MainBoard[dest->y][dest->x];
/*
* if we stepped on a mine, blow him up
*/
if (sqp->mined) {
GameOver = TRUE;
Message("You just exploded");
DrawBoard();
}
/*
* else if this is home, render congratulations
*/
else if (dest->x == SIDE_SIZE-1 && dest->y == SIDE_SIZE-1) {
PlayerLocation = * dest;
sqp->traversed = sqp->occupied = TRUE;
GameOver = TRUE;
Message("You made it!");
DrawBoard();
}
/*
* else move onto the new square
*/
else {
PlayerLocation = * dest;
sqp->traversed = sqp->occupied = TRUE;
DrawSquare(dest);
Message(MineWarningMessage());
}
}
/*
* return a pointer to the warning message
*/
char *
MineWarningMessage()
{
static char warning[128];
register int x, y;
int minesFound;
minesFound = 0;
for (x = PlayerLocation.x - 1 ; x <= PlayerLocation.x + 1 ; x++) {
for (y = PlayerLocation.y - 1 ; y <= PlayerLocation.y + 1 ; y++) {
if (x >= 0 && x < SIDE_SIZE && y >= 0 && y < SIDE_SIZE && MainBoard[y][x].mined)
minesFound++;
}
}
sprintf(warning, "%d mine(s) nearby", minesFound);
return(warning);
}