Automated Grading Log for CS113 -- HW5 userid: mpwertz Name: Wertz, Matthew Log created: Thu Oct 31 13:30:35 EST 1996 SUBMISSIONS =========== mpwertz Submitted hw5-life.c at Fri Oct 18 15:02:52 1996 mpwertz Submitted hw5-board.h at Fri Oct 18 15:02:46 1996 mpwertz Submitted hw5-board.c at Fri Oct 18 15:02:37 1996 COMPILATION =========== gccx -Wall -c hw5-life.c gccx -Wall -c hw5-board.c gccx -Wall -o hw5-life hw5-life.o hw5-board.o if [ -f "hw5-life2.c" ]; then \ gccx -Wall -c hw5-board2.c; \ gccx -Wall -c hw5-life2.c; \ gccx -Wall -o hw5-life hw5-life2.o hw5-board2.o; \ fi EXECUTION TESTS ========= ===== ============================================================ hw5-life < /home/course/cs113/GradesF96/HW5/input/board3.dat Time = 0 ............................................... .............................................o. .ooooo.............oco.....................ooo. .............................................o. ............................................... Time = 1 ................................................ ..ooo...............o........................o.. ..ooo...............c........................oo. ..ooo...............o........................o.. ................................................ Time = 2 ................................................ ...o............................................ ..o.o........................................oo. .o...o.............cco......................ooo. ..o.o........................................oo. ...o............................................ ................................................ Time = 3 ................................................. ...o............................................. ..ooo...............o.......................o.o.. .oo.oo.............:c.......................o..o. ..ooo...............o.......................o.o.. ...o............................................. ................................................. Time = 4 ................................................. ..ooo............................................ .o...o.......................................o... .o...o............:oco.....................oo.oo. .o...o.......................................o... ..ooo............................................ ................................................. Time = 5 .................................................. ....o............................................. ...ooo............................................ ..o.o.o..............o.......................ooo.. .ooo.ooo...........:.c.......................o.o.. ..o.o.o..............o.......................ooo.. ...ooo............................................ ....o............................................. .................................................. Time = 6 .................................................. ...ooo............................................ ..............................................o... .o.....o.....................................o.o.. .o.....o...........:oco.....................o...o. .o.....o.....................................o.o.. ..............................................o... ...ooo............................................ .................................................. Time = 7 ................................................... .....o............................................. .....o............................................. .....o.........................................o... ......................o.......................ooo.. .ooo...ooo..........:.c......................oo.oo. ......................o.......................ooo.. .....o.........................................o... .....o............................................. .....o............................................. ................................................... Time = 8 ................................................... ................................................... ....ooo............................................ ..............................................ooo.. Data files: ========== 5 ............................................... .............................................o. .ooooo.............oco.....................ooo. .............................................o. ............................................... 8 ============================================================ SOURCE FILES ====== ===== /* * File: hw5-life.c * Author: Matthew P. Wertz * Class: CS 113, Fall 96 * Assignment: Homework 5 * Due Date: 17 October 1996 * Last modified: 17 October 1996 * ----------------------------------------------------- * * OVERVIEW: * ========= * This program uses functions from the "hw5-board.h" library * to simulate the game of life. * * Known Bugs: none. * ================= * * Error Handling: * =============== * The functions print messages to standard output when functions * are passed invalid values, such as indices in a matrix that are * out of range. * */ #include "hw5-board.h" #include "simpio.h" /* Reads in and returns the initial board */ lifeBoardT InitializeBoard (void); /* Returns the total number of cycles through * which the game of life must be played */ int GetTotalTime (void); /* Displays the current game of life board at * time time */ void DisplayBoard (lifeBoardT *board, int time); /* Simulates the game of life for time cycles. * Board contains the starting board */ void Live (lifeBoardT *board, int time); int main () { lifeBoardT board; int totalTime; board = InitializeBoard(); totalTime = GetTotalTime(); Live (&board, totalTime); DestroyBoard (&board); return 0; } /* end of main */ lifeBoardT InitializeBoard (void) { lifeBoardT board; ReadBoard (&board); return board; } /* end of InitializeBoard () */ int GetTotalTime (void) { int totalTime; totalTime = GetInteger (); return totalTime; } /* end of GetTotalTime */ void DisplayBoard (lifeBoardT *board, int time) { printf ("\n\nTime = %d",time); PrintBoard (board); } /* end of DisplayBoard */ void Live (lifeBoardT *board, int totalTime) { int time; DisplayBoard (board, 0); for (time = 1; time <= totalTime; time++) { UpdateBoard (board); /* It only prints the first five and the last * five boards. */ if (!((time > 5) && (time < totalTime - 4))) { DisplayBoard (board, time); } /* end of if */ } /* end of for */ } /* end of Live */ /* * File: hw5-board.h * Author: Matthew P. Wertz * Class: CS 113, Fall 96 * Assignment: Homework 5 * Due Date: 17 October 1996 * Last modified: 17 October 1996 * ----------------------------------------------------- * * OVERVIEW: * ========= * Declares types and functions needed to create and manipulate * the game board for the game of life. * * Known Bugs: none. * ================= * * Error Handling: * =============== * The functions print messages to standard output when functions * are passed invalid values, such as indices in a matrix that are * out of range. * */ #ifndef _board_h #define _board_h #include "genlib.h" /* * Constants * --------- * The following constants are how the cells in the game of life * are to be represented. */ #define ALIVE 'o' #define ALIVE_CENTER 'c' #define DEAD '.' #define DEAD_CENTER ':' /* * Type : lifeBoardT * ----------------- * Variables of type lifeBoardT represent a game board for the * game of life. The integer fields rows and columns represent * the number of rows and columns in the game board. cellsPtr * points to the first cell of the game board. The board is * represented by a one dimensional, dynamically allocated, * array of characters. */ typedef struct { int rows, cols; int centerIndex; char *cellsPtr; } lifeBoardT; /* * Function : ReadBoard * Usage: ReadBoard (&board); * ------------------------- * Reads in an integer representing the number of rows * in the initial gameboard. Reads in the initial game * board as characters into the cellsPtr field of the * lifeBoardT structure. Assigns the appropriate values * to the rows and cols fields. */ void ReadBoard (lifeBoardT *board); /* * Function : DestroyBoard * Usage: DestroyBoard (&board) * --------------------------- * Frees the memory allocated for board->cellsPtr */ void DestroyBoard (lifeBoardT *board); /* * Function : UpdateBoard * Usage: UpdateBoard (&board) * -------------------------- * Brings the gameboard to its next stage of life. */ void UpdateBoard (lifeBoardT *board); /* * Function : PrintBoard * Usage: PrintBoard (&board) * -------------------------- * Returns the game board to the user as output. */ void PrintBoard (lifeBoardT *board); /* * Function : IsAlive * Usage: boolean = IsAlive (&board, row, column) * ------------------------------------ * Returns true if cell (row, column) is alive. * Returns false if cell (row, column) is dead. */ bool IsAlive (lifeBoardT *board, int row, int column); /* * Function : NumNeighbors * Usage: NumNeighbors (&board, rowNum, colNum) * -------------------------------------------- * Returns the number of living neighbors around cell * (rowNum, colNum) */ int NumNeighbors (lifeBoardT *board, int rowNum, int colNum); /* * Function : CenterCellColumn * Usage: CenterCellColumn (&board) * ----------------------- * Returns the column of the center cell. */ int CenterCellColumn (lifeBoardT *board); /* * Function : CenterCellRow * Usage: CenterCellRow (&board) * ----------------------- * Returns the row of the center cell. */ int CenterCellRow (lifeBoardT *board); #endif /* * File: hw5-board.c * Author: Matthew P. Wertz * Class: CS 113, Fall 96 * Assignment: Homework 5 * Due Date: 17 October 1996 * Last modified: 17 October 1996 * ----------------------------------------------------- * * OVERVIEW: * ========= * Implements the functions necessary to create and manipulate * the game board of the game of life. The board is stored in * a dynamically allocated array of characters. * * Known Bugs: none. * ================= * * Error Handling: * =============== * The functions print messages to standard output when functions * are passed invalid values, such as indices in a matrix that are * out of range. * */ #include #include #include "simpio.h" #include "strlib.h" #include "hw5-board.h" void ReadBoard (lifeBoardT *board) { int numRows, numCols, sizeBoard; int i, cell; string line; board->rows = numRows = GetInteger(); /* read number of rows */ line = GetLine(); /* read the first line of initial board */ board->cols = numCols = StringLength(line); sizeBoard = numCols * numRows; board->cellsPtr = (char *)GetBlock(sizeBoard * sizeof (char)); for (i = 0; i < numRows; i++) { for (cell=0; cell < numCols; cell++) { if ((line[cell] == ALIVE_CENTER) || /* if marks the */ (line[cell] == DEAD_CENTER)) { /* center cell */ board->centerIndex = i*numCols + cell; } /* end of if */ board->cellsPtr[i*numCols + cell] = line[cell]; } /* end of for cell */ if (i != numRows - 1) { /* if to avoid reading extra line */ line = GetLine(); } /* end of if */ } /* end of for i */ } static char *Cell (lifeBoardT *board, int row, int column) { int realRow = row - 1; /* Decrement by one because */ int realCol = column - 1; /* indeces start at 0 */ return &board->cellsPtr[board->cols * realRow + realCol]; } /* end of Index() */ bool IsAlive (lifeBoardT *board, int row, int column) { return ( *Cell(board, row, column) == ALIVE) + ( *Cell(board, row, column) == ALIVE_CENTER); } /* end of IsAlive() */ int NumNeighbors (lifeBoardT *board, int rowNum, int colNum) { int neighbors = 0; int row, col, upperRow, lowerRow, leftCol, rightCol; upperRow = rowNum - 1; /* These are the left, upper, right */ lowerRow = rowNum + 1; /* and lower limits for the cells */ leftCol = colNum - 1; /* to be checked for life */ rightCol = colNum + 1; /* * The following if else clauses resets the upper, lower, * left, and right limits of the cells to be checked for * life if the cell is on the border of the board. */ if (rowNum == 1) { upperRow = rowNum; } /* end of if */ else if (rowNum == board->rows) { lowerRow = rowNum; } /* end of else if */ if (colNum == 1) { leftCol = colNum; } /* end of if */ else if (colNum == board->cols) { rightCol = colNum; } /* end of else if */ /* for loop checks cells within previous limits for life * and sums the total number of living cells. */ for (row = upperRow; row <= lowerRow; row++) { for (col = leftCol; col <= rightCol; col++) { if ((col != colNum) || (row != rowNum)) { neighbors += IsAlive(board, row, col); } /* end of if */ } /* end of for col */ } /* end of for row */ return neighbors; } /* end of NumNeighbors() */ /* * Function : NewTop * Usage: boolean = NewTop (&board, oldCols); * ----------------------- * Returns true if the game board needs to be expanded at the * top. Resets the center index if that is the case. */ static bool NewTop (lifeBoardT *board, int oldCols) { int i; bool top; /* Checks top row for life. If life exists, a new, completely * dead row must added to the top. */ top = FALSE; i = 0; while ((!top) && (i < oldCols)) { top = (board->cellsPtr[i] == ALIVE); i++; } /* end of while top */ if (top) { board->centerIndex += board->cols; } /* end of if top */ return top; } /* end of NewTop */ /* * Function : NewLeft * Usage: boolean = NewLeft (&board, oldRows, oldCols); * ----------------------- * Returns true if the game board needs to be expanded on the * left. Resets the center index if that is the case. */ static bool NewLeft (lifeBoardT *board, int oldRows, int oldCols) { int j; bool left; /* Checks left border for life. If life exists, a new, completely dead row must added on the left. */ left = FALSE; j = 0; while ((!left) && (j < oldRows)) { left = (board->cellsPtr[j*oldCols] == ALIVE); j++; } /* end of while left */ if (left) { board->centerIndex += 1 + board->centerIndex/board->cols; } return left; } /* * Function : NewRight * Usage: boolean = NewRight (&board, oldRows, oldCols); * ----------------------- * Returns true if the game board needs to be expanded on the * right. Resets the center index if that is the case. */ static bool NewRight (lifeBoardT *board, int oldRows, int oldCols) { int j; bool right; /* Checks right border for life. If life exists, a new, completely dead row must added on the right. */ right = FALSE; j = 0; while ((!right) && (j < oldRows)) { right = (board->cellsPtr[(j+1)*oldCols - 1] == ALIVE); j++; } /* end of while right */ if (right) { board->centerIndex += board->centerIndex/board->cols - 1; } /* end of if right */ return right; } /* * Function : NewBottom * Usage: boolean = NewBottom (&board, oldRows, oldCols); * ----------------------- * Returns true if the game board needs to be expanded on the * bottom. */ static bool NewBottom (lifeBoardT *board, int oldRows, int oldCols) { int i; bool bottom; /* Checks bottom row for life. If life exists, a new, completely * dead row must added to the bottom. */ bottom = FALSE; i = 1; while ((!bottom) && (i <= oldCols)) { bottom = (board->cellsPtr[(oldRows-1)*oldCols + i] == ALIVE); i++; } /* end of while bottom */ return bottom; } /* end of NewBottom */ /* * Function : MakeTempBoard * Usage: newBoard = MakeTempBoard (&board, oldRows, oldCols); * ----------------------------------------------------------- * Returns a copy of board */ static lifeBoardT MakeTempBoard (lifeBoardT *board, int oldRows, int oldCols) { lifeBoardT tempBoard; int i, lengthArray; tempBoard.rows = oldCols; tempBoard.cols = oldRows; lengthArray = (tempBoard.rows * tempBoard.cols); tempBoard.cellsPtr = (char *)GetBlock(lengthArray*sizeof(char)); /* copies all elements from board to tempBoard */ for (i=0; i < lengthArray; i++) { tempBoard.cellsPtr[i] = board->cellsPtr[i]; } /* end of for */ return tempBoard; } /* end of MakeTempBoard */ static void ResizeBoard (lifeBoardT *board) { int j, oldRows, oldCols, difference; lifeBoardT tempBoard; bool top, bottom, left, right; oldRows = board->rows; oldCols = board->cols; top = NewTop (board, oldCols); left = NewLeft (board, oldRows, oldCols); right = NewRight (board, oldRows, oldCols); bottom = NewBottom (board, oldRows, oldCols); /* if resizing is necessary */ if ((top + bottom + left + right) > 0) { tempBoard = MakeTempBoard (board, oldRows, oldCols); board->rows += top + bottom; board->cols += left + right; DestroyBoard(board); board->cellsPtr = (char *)GetBlock(board->rows*board->cols * sizeof(char)); /* The following for goes through every element of the newly sized board. */ difference = 0; for (j=0; j < (board->cols * (board->rows-1)); j++) { /* The following if adds a row to the top of the board * if top == TRUE */ if ((j < board->cols) && (top)) { board->cellsPtr[j] = DEAD; difference++; } /* end of if */ /* The following if adds a new left border to the board * if left == TRUE */ else if ((j % (board->cols) == 0) && (left)) { board->cellsPtr[j] = DEAD; difference++; } /* end of else if */ /* The following if adds a new right border to the board * if right == TRUE */ else if (((j+1) % board->cols == 0) && (right)) { board->cellsPtr[j] = DEAD; difference++; } /* end of else if */ else { board->cellsPtr[j] = tempBoard.cellsPtr[j-difference]; } /* end of else */ } /* end of for */ /* This for adds a bottom border of dead cells to the board */ for (j = (board->cols*(board->rows-1)); j < (board->cols*board->rows);j++) { board->cellsPtr[j] = DEAD; } /* end of for */ DestroyBoard (&tempBoard); } /* end of HUGE IF */ } /* end of ResizeBoard () */ void UpdateBoard (lifeBoardT *board) { lifeBoardT tempBoard; int i, lengthArray, row, col, neighbors; tempBoard.rows = board->rows; tempBoard.cols = board->cols; lengthArray = (tempBoard.rows * tempBoard.cols); tempBoard.cellsPtr = (char *)GetBlock(tempBoard.rows * tempBoard.cols * sizeof(char)); for (i=0; i < lengthArray; i++) { tempBoard.cellsPtr[i] = board->cellsPtr[i]; } /* end of for */ /* This for identifies how many neighbors every cell on the * game board has. If the number of neighbors is three, * it sets the cell to ALIVE. If the number of neighbors is * 0,1,4,5,6,7, or 8, it sets the cell to DEAD. */ for (row = 1; row <= tempBoard.rows; row++) { for (col = 1; col <= tempBoard.cols; col++) { neighbors = NumNeighbors(&tempBoard, row, col); if ((neighbors == 2) || (neighbors == 3)) { if ((neighbors == 3) && (!IsAlive(&tempBoard, row, col))) { *Cell(board, row, col) = ALIVE; } /* end inner if */ } /* end outer if */ else { *Cell(board, row, col) = DEAD; } } /* end for col */ } /* end of for row */ /* This if else if identifies the center cell on the board */ if (board->cellsPtr[board->centerIndex] == 'o') { board->cellsPtr[board->centerIndex] = 'c'; } /* end of if */ else if (board->cellsPtr[board->centerIndex] == '.') { board->cellsPtr[board->centerIndex] = ':'; } /* end of else if */ DestroyBoard(&tempBoard); ResizeBoard (board); } /* end of UpdateBoard() */ void DestroyBoard (lifeBoardT *board) { FreeBlock (board->cellsPtr); } /* end of DestroyBoard */ void PrintBoard (lifeBoardT *board) { int i, j; printf ("\n\n"); for (i=0; i< (*board).rows; i++) { for (j=0; j < (*board).cols; j++) { printf ("%c", (*board).cellsPtr[i*(*board).cols + j]); } printf ("\n"); } } int CenterCellColumn (lifeBoardT *board) { return (board->centerIndex + 1) % board->cols; } /* end of CenterCellColumn */ int CenterCellRow (lifeBoardT *board) { return ((board->centerIndex + 1) / board->cols) + 1; } /* end of CenterCellRow */ -- END OF LOG FILE FOR mpwertz --