
#include "life.h"


int read_board (char *filename, char gameboard [BOARDX][BOARDY])
/* Tries to read in a "life" board from a file - if this is done
successfully, return NOERROR - if there is a problem opening the 
file return ERROR.
Note: We want our board to contain only spaces or #s and to fill
all the sections of the array - even if the lines read from the file
are too short pad the rest of the array with spaces*/
{
    FILE *fptr;               /* File pointer for the board file being read */
    char readline[MAXLEN];    /* Holds an input line from a file */
    int x, y;                 /* The x,y location we are currently reading */
    
    fptr= fopen (filename, "r");
    if (fptr == NULL) {
        printf ("Unable to open file \"%s\"\n",filename);
        return ERROR;
    }
    y= 0;

	// Start reading each line from the file
    while (fgets (readline, MAXLEN, fptr) != NULL) {
        x= 0;  // Across readline look for # signs and 
				// fill in the board
        while (x < (int)strlen(readline) && x < BOARDX) {
           if (readline[x] == '#') {
               gameboard[x][y]= '#';
           } else {
               gameboard[x][y]= ' ';
           }
           x++;
        }   // Fill in the rest of the width of that line as blank
        while (x < BOARDX) {
            gameboard [x][y]=' ';
            x++;
        }
        y++;  // Now move on to the next line
        if (y == BOARDY)  // Check if we have read all the lines we can
            break;
    }
	// If we have not read ENOUGH lines then fill in the rest with blanks.
    while (y < BOARDY) {
        for (x= 0; x < BOARDX; x++)
            gameboard [x][y]= ' ';
        y++;
    }
    fclose (fptr);
    return NOERROR;
}


void print_board (char gameboard[BOARDX][BOARDY])
/* Prints the status of the board to screen.  */
{
	int i;
	int j;

	//  Loop around the y then the x printing the board
	for (j= 0; j < BOARDY; j++) {
		for (i= 0; i < BOARDX; i++) {
			putchar (gameboard[i][j]);
		}
		putchar('\n');
	}

}

void update_board (char gameboard[BOARDX][BOARDY])
/* Updates the game board according to the life rules.  Note that we
must take a complete copy of the old board first  */
{
    char tmpboard[BOARDX][BOARDY];
	int i;
	int j;
	int no_near;
	// Take a copy of the board  
	// tmpboard now stores the old board
	for (i= 0; i < BOARDX; i++) {
		for (j= 0; j < BOARDY; j++) {
			tmpboard[i][j]= gameboard[i][j];
		}
	}
	for (i= 0; i < BOARDX; i++) {
		for (j= 0; j < BOARDY; j++) {
			// Calculate how many neighbours the cell had
			// Using the copy of the board
			no_near= calc_neighbours(i,j,tmpboard);  
			if (no_near < 2) {
				gameboard[i][j]= ' ';
			} else if (no_near > 3) {
				gameboard[i][j]= ' ';
			} else if (no_near == 3) {
				gameboard[i][j]= '#';
			} else {
				gameboard[i][j]= tmpboard[i][j];
			}
		}
	}
	

}

int calc_neighbours (int x, int y, char gameboard[BOARDX][BOARDY])
/* Returns the number of neighbours for a particular x, y location on
the board including checking if we are at the edge of the board */
{
	int no_neighbours= 0;
	// Check the eight adjacent cells
	no_neighbours+= cell_at_pos(x-1,y-1, gameboard);
	no_neighbours+= cell_at_pos(x-1,y, gameboard);
	no_neighbours+= cell_at_pos(x-1,y+1, gameboard);
	no_neighbours+= cell_at_pos(x,y-1, gameboard);
	no_neighbours+= cell_at_pos(x,y+1, gameboard);
	no_neighbours+= cell_at_pos(x+1,y-1, gameboard);
	no_neighbours+= cell_at_pos(x+1,y, gameboard);
	no_neighbours+= cell_at_pos(x+1,y+1, gameboard);


    return no_neighbours;
}

int cell_at_pos(int x, int y, char gameboard[BOARDX][BOARDY])
/* Returns 1 if there is a cell at x,y and 0 if it is out of range
 or if there is no cell */
{
	// First check if x and y are in range
    if (x < 0 || x >= BOARDX)
		return 0;
	if (y < 0 || y >= BOARDY)
		return 0;
	// Now check if there is a cell at this position
	if (gameboard[x][y] == '#')
		return 1;
	return 0;

}

