DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T b

⟦47cb68fcb⟧ TextFile

    Length: 4101 (0x1005)
    Types: TextFile
    Names: »board.c«

Derivation

└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
    └─⟦this⟧ »EUUGD18/Sun/Mines/board.c« 

TextFile

/*
 * 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);
}