Name: Siddiqui, Matheen ============================================================ hw4-koch < koch.in This program draws a koch fractal snowflake to the graphics window. It asks for the initial length of a side, and the degree of the fractal. The length must be a positive number, as the absolute value of the length entered, is used. Degree must be between 0 and 5 inclusive. If you enter values greater then 5, 5 is used, and if you enter Values less than zero, zero is used. Enter the length of one side : Enter degree of snowflake (max = 5): Graphics in siddiqui.ps ============================================================ hw4-madlib < madlib.in This program will take a file specified by the user and ask you to enter certain types of words that will fill in certain types of words form the original file. The results will be put into a file called madFile Its contents will be printed. Enter the name of the madlib file: assignment: word: word: Here is what your wrote:: A TEST This is a test of HOMEWORK 4. The line above had one substitution. This one has none. And this line has two substitutions: BACON and EGGS. The text just printed is in the file: madFile ============================================================ hw4-life life.bd1 This program will print rounds of the game of life for the board given in the passed data file. The data file contains the number of rows followed by the number of columns of the initial board followed by the number of rounds to simulate and the number of rounds at the begining and end to display. Imidatey after the last line is a return and then the board in a table format. The first 4 of 100 rounds of the game: ----------|round = 0|----------- ..... ..o.. .oOo. ..o.. ----------|round = 1|----------- ..... .ooo. .o:o. .ooo. ----------|round = 2|----------- ....... ...o... ..o.o.. .o.:.o. ..o.o.. ...o... ----------|round = 3|----------- ....... ...o... ..ooo.. .oo:oo. ..ooo.. ...o... The last 4 rounds of the game: ---------|round = 97|-------------- ........... .....o..... .....o..... .....o..... ........... .ooo.:.ooo. ........... .....o..... .....o..... .....o..... ---------|round = 98|-------------- ........... ........... ....ooo.... ........... ..o.....o.. ..o..:..o.. ..o.....o.. ........... ....ooo.... ........... ---------|round = 99|-------------- ........... .....o..... .....o..... .....o..... ........... .ooo.:.ooo. ........... .....o..... .....o..... .....o..... ---------|round = 100|-------------- ........... ........... ....ooo.... ........... ..o.....o.. ..o..:..o.. ..o.....o.. ........... ....ooo.... ........... ============================================================ hw4-life life.bd2 This program will print rounds of the game of life for the board given in the passed data file. The data file contains the number of rows followed by the number of columns of the initial board followed by the number of rounds to simulate and the number of rounds at the begining and end to display. Imidatey after the last line is a return and then the board in a table format. The first 3 of 9 rounds of the game: ----------|round = 0|----------- ........... ........... ........... ........... ........... ........... ...ooOoo... ........... ........... ........... ........... ........... ----------|round = 1|----------- ........... ........... ........... ........... ........... ....ooo.... ....oOo.... ....ooo.... ........... ........... ........... ........... ----------|round = 2|----------- ........... ........... ........... ........... .....o..... ....o.o.... ...o.:.o... ....o.o.... .....o..... ........... ........... ........... The last 3 rounds of the game: ---------|round = 7|-------------- ........... ........... .....o..... .....o..... .....o..... ........... .ooo.:.ooo. ........... .....o..... .....o..... .....o..... ........... ---------|round = 8|-------------- ........... ........... ........... ....ooo.... ........... ..o.....o.. ..o..:..o.. ..o.....o.. ........... ....ooo.... ........... ........... ---------|round = 9|-------------- ........... ........... .....o..... .....o..... .....o..... ........... .ooo.:.ooo. ........... .....o..... .....o..... .....o..... ........... ============================================================ hw4-life life.bd3 This program will print rounds of the game of life for the board given in the passed data file. The data file contains the number of rows followed by the number of columns of the initial board followed by the number of rounds to simulate and the number of rounds at the begining and end to display. Imidatey after the last line is a return and then the board in a table format. The first 2 of 5 rounds of the game: ----------|round = 0|----------- ....... .ooOoo. ....... ....... ----------|round = 1|----------- ..ooo.. ..oOo.. ..ooo.. ....... The last 3 rounds of the game: ---------|round = 3|-------------- ....o.... ...ooo... ..oo:oo.. ...ooo... ....o.... ......... ---------|round = 4|-------------- ...ooo... ..o...o.. ..o.:.o.. ..o...o.. ...ooo... ......... ---------|round = 5|-------------- .....o..... ....ooo.... ...o.o.o... ..ooo:ooo.. ...o.o.o... ....ooo.... .....o..... ........... SOURCE FILES ====== ===== /* * File: hw4-koch.c * Author: Matheen Siddiqui * Class: cs113 * Assignment: homework 4 * Due Date: October 16, 1996 * Last modified: October 16, 1996 * ----------------------------------------------------- * * USAGE: hw4-koch (no command line argumants) * ====== * * OVERVIEW: * ========= This program will draw koch snoflakes to a graphics window. It will ask for initial length of a side and the degree of the snoflake. * * Algorithm Notes: * ================ The program makes uses of turtle graphics and uses a recursive function to draw the snowflake. * * Error Handling: * =============== If a degree larger then the maximum allowed degree is used the maximum degree is used. If a degree less then 0 is entered, zero is used as the degeree. * */ /*--------------------Includes------------------*/ #include #include "turtle.h" #include "simpio.h" #include "genlib.h" #include /*-------------------CONSTANTS---------------*/ /* ANGLE_EQ_TRI : The size of the angle in an equilateral triangle DISP_FACTOR: The factor used to determine vertical displament of snowflake used for centering. FRACT_LINE: The fraction of a line used to draw a smaller koch line used in the recusrive call. HALF_REC: degrees in half a revoluiton, 180 TURN_TRI_PATH: the degrees to turn if you want the turtle to move in a equilatal triangular path. MAX_DEGREE: The maximum degree of the koch snoflake */ #define ANGLE_EQ_TRI 60 #define DISP_FACTOR 2.0 / 3.0 #define FRACT_LINE 1.0 / 3.0 #define HALF_REV 180.0 #define TURN_TRI_PATH 120.0 const int MAX_DEGREE = 5; /* * Function: InstuctUser * Usage: InstructUser(); * ------------------------------------ * Prints instruction on the use of the program to standard output. */ void InstructUser(void); /* * Function: GetParameters * Usage: GetParameters( &length, °ree ) * ------------------------------------------------------ * This function gets the length of a side of the koch * snowflake,contained in double length, and the degree of the * snowflake, contained in the int degree, from the standard input. You pass * the address of or pointer to the locations that hold the length * and degree. * If a degree larger than MAX_DEGREE is entered, MAX_DEGREE is used. * If a degree less than 0 is entered, 0 is used. */ void GetParameters(double *lengthPtr, int *degreePtr); /* * Function: DrawKochSnowflake * Usage: DrawKochSnowflake( length, degree ) * --------------------------------------- * This function draws a koch snowflake which has a zero degree side of size * length, a double, and degree of magintude degree, an int, at * the center of the graphics window. The window must be initialized * by InitTurtle, prior to use of this function. */ void DrawKochSnowflake(double length, int degree); /* * Function: DrawKochLine * Usage: DrawKochLine( length, degree ) * --------------------------------------- * Draws a koch line of initial size length,(double) and degree degree, ( int ) * from the current location and in the current direction of the * turtle. After the line is draw the turtle is facing its initial direction, * and is at the end of the newly draw koch line. */ void DrawKochLine(double length, int degree); /*-----------------MAIN------------------*/ int main(void) { double length = 1; /*the zero degree length of a side of the snowflake*/ int degree = 1; /*the degree of the koch snowflake*/ InstructUser(); /*intiailze turtle graphics*/ InitTurtle(); /*get the parameters from the user*/ GetParameters(&length, °ree); /*draw the snowflake*/ DrawKochSnowflake(length,degree); exit(0); } /* end of main*/ /* * Function: InstuctUser * ------------------------------------ */ void InstructUser(void) { printf("This program draws a koch fractal snowflake to the graphics\n" "window. It asks for the initial length of a side, and the\n" "degree of the fractal. The length must be a positive number,\n" "as the absolute value of the length entered, is used.\n" "Degree must be between 0 and %d inclusive. If you enter\n", MAX_DEGREE); printf("values greater then %d, %d is used, and if you enter\n", MAX_DEGREE, MAX_DEGREE); printf("Values less than zero, zero is used.\n\n"); } /* * Function GetParameters * ---------------------------------------- * this function uses GetReal and GetIneger to get input */ void GetParameters(double *lengthPtr, int *degreePtr) { /*read in values for length */ printf("Enter the length of one side : "); *lengthPtr = abs(GetReal()); /*get the degree*/ printf("Enter degree of snowflake (max = %i): ",MAX_DEGREE); *degreePtr = GetInteger(); /*if degree is out of range , than extremities are assigned to it*/ if (*degreePtr > MAX_DEGREE) { *degreePtr = MAX_DEGREE; printf("\nYour degree is too large. Using %d instead.\n",*degreePtr); } else if (*degreePtr < 0) { *degreePtr = 0; printf("\nYour degree is too small. Using %d instead.\n",*degreePtr); } } /* * Function: DrawKochSnowflake * ------------------------------------------- * this function draws the snow flake by moving the turtle to * the a location that will center the snowflake, and drawing * the sides of the snowflake by calling DrawKochLine. * The path can be thought of as traversing around an equilateral * triangle, put instead of drawing regular lines, koch lines are drawn. */ void DrawKochSnowflake(double length, int degree) { /* place turtle 2/3 the length of a side above the center * of the screen to center snowflake */ PlaceTurtle( GetWindowWidth() / 2, GetWindowHeight() / 2 + length * DISP_FACTOR ); /*point turtle down the first side of the triangular path*/ TurnRight(GetCurrentDirection() + ANGLE_EQ_TRI); /*travers first side, leaving a Koch line*/ DrawKochLine( length, degree ); /*position turtle for next side, and draw path*/ TurnRight( TURN_TRI_PATH ); DrawKochLine( length, degree ); /*draw final side*/ TurnRight( TURN_TRI_PATH ); DrawKochLine( length, degree ); } /*end of DrawKochSnowflake*/ /* * function: DrawKochLine * ------------------------------------------- * This function is a recurisive funtion, with a base * case of a koch line of degree zero, which is just a regular line. * Other cases are reduced by drawing smaller koch lines in the * pattern of a koch line. That is, the first third of a line is draw as * a smaller koch line, then the turtle is turned and the petruding two * segments of the line are drawn as smaller koch lines, * then the last third of the line is draw. */ void DrawKochLine(double length, int degree) { /*base case, a line of degree 0 is just a line*/ if ( degree == 0 ) { DrawTurtle( length ); } else { /*draw first fraction of line, a smaller koch line*/ DrawKochLine( FRACT_LINE * length, degree - 1 ); /*turn left */ TurnLeft( ANGLE_EQ_TRI ); /*draw petruding triangluar part of the line*/ /*first side of triangular part*/ DrawKochLine( FRACT_LINE * length , degree - 1); TurnRight( HALF_REV - ANGLE_EQ_TRI ); /*second side*/ DrawKochLine( FRACT_LINE * length , degree - 1); /*turn turtle to face down the initial direction of line*/ TurnLeft( ANGLE_EQ_TRI ); /*draw last part of line*/ DrawKochLine( FRACT_LINE * length, degree - 1 ); } } /* end of DrawKochLine*/ /*-------End of File --------*/ /* * File: hw4-madlib.c * Author: Matheen Siddiqui * Class: cs113 * Assignment: homework 4 * Due Date: October 16, 1996 * Last modified: October 16, 1996 * ----------------------------------------------------- * * USAGE: hw4-madlib ( no command line args) * ====== * * OVERVIEW: * ========= This program takes a madlib file and asks the user to fill in the words marked off in the template. A new file is created called OUTP_FILE This new file is the same as the original, but the marked words are filled in with what the user specified. A madlife file is a reguluar text file, but the words descriptions should be surrouned by START_WORD and END_WORD. * * Algorithm Notes: * ================ * This program makes use of the file functions in stdio.h The chars of the template file are copyed into the outp file, until a marker of a word to be replaced is encountered, in which case chars are printed to the screen, and the word entered by the user is put in the file. * */ /*------------------Includes------------------*/ #include #include "genlib.h" #include "simpio.h" #include #include /*-----------------Constants---------------*/ /* START_WORD is the starting mark for a word to be filled by user * END_WORD is the ending char for a word to be entered by user * OUTP_FILE is the name of the file that has with the words replaced * ERROR_CREATE is an error message printed in a file couldn't be created * ERROR_OPEN is an error message printed if a file couldn't be opened * ERROR_EOF is the error message printed if the eof was reached unexpectedly */ #define START_WORD '<' #define END_WORD '>' #define OUTP_FILE "madFile" #define ERROR_OPEN "\nERROR: unable to openfile\n" #define ERROR_CREATE "\nERROR: unable to create file\n" /* * Function: InstuctUser * Usage: InstructUser(); * ------------------------------------ * Prints instruction on the use of the program to standard output. */ void InstructUser(void); /* * Function: CreateMadlib * Usage: madfile = CreateMadlib( filename ); * ------------------------------------ * This function returns the name of the file, (a string), created after the * words in the template madlib file, specified by its name filename * (also a string), have been replaced */ string CreateMadlib( string fileName ); /* * Function: PrintFile * Usage: PrintFile( fileName ) * ------------------------------------ * Prints the contents of the file called fileName, (string) to the * standard output. */ void PrintFile( string fileName ); /*----------------MAIN--------------------*/ int main( int argc, string argv[] ) { string fileName, /*the name of the madlib source file*/ outpFileName; /*the name of the file after subsitituions*/ InstructUser(); /*get file from user*/ printf("Enter the name of the madlib file: "); fileName = GetLine(); /*make file with replacements*/ outpFileName = CreateMadlib( fileName ); /*printfile*/ printf("\n\nHere is what your wrote::\n\n"); PrintFile( outpFileName ); /*tell user of the file*/ printf("\n\nThe text just printed is in the file: %s\n", outpFileName ); /*free mem*/ free( fileName ); exit(0); } /* * Function: InstuctUser * ------------------------------------ */ void InstructUser( void ) { printf("This program will take a file specified by the user\n" "and ask you to enter certain types of words that will fill in\n" "certain types of words form the original file.\n" "The results will be put into a file called %s\n" "Its contents will be printed.\n\n\n", OUTP_FILE ); } /* * Function: CreateMadlib: * ----------------------------------- * Repeteadly reads from the inputfile and writes to either screen or * output file. It initial writes to the output file. * If the start of a word that is to be is replaced is encountered, * the letters are written to screen until the END_WORD char. Then * a word is read from stdin and put in the output file, and chars * are writen to the file again. */ string CreateMadlib( string fileName ) { FILE *inpFile, /*the input madlib file*/ *outpFile, /*the madlib file with the blanks filled*/ *curFile; /*the current file writing to*/ string outpFileName, /*name of madlib file*/ word; /*replacement word , read from user*/ int ch; /*temporay int to store things read from file*/ /*creat output filename, by copying filename ,and adding the extension*/ outpFileName = (string) GetBlock( strlen( fileName) + 1); strcpy( outpFileName, OUTP_FILE ); /*open the file */ inpFile = fopen( fileName, "r" ); /*handle error if file doesnt open corectly*/ if( inpFile == NULL ) { printf(ERROR_OPEN); exit(-1); } /*create output file*/ outpFile = fopen( outpFileName, "w" ); /*handle error*/ if ( outpFile == NULL ) { printf(ERROR_CREATE); exit(-1); } /*initialy write to file*/ curFile = outpFile; /*read from file until EOF is reached*/ while ( (ch = getc( inpFile )) != EOF ) { switch( ch ) { /*if true have reached the beginig of a word to substitue*/ case START_WORD: /*now write to screen*/ curFile = stdout; break; case END_WORD: /*reached end of word discription*/ /*get substitute word and write to file again*/ printf(": "); word = GetLine(); /*put that word in the output file*/ fprintf(outpFile, "%s", word ); /*free memory*/ free( word ); /*write to file now*/ curFile = outpFile; break; default: /*write other chars to current to file*/ putc( ch, curFile ); } } /* end outer while */ /*close files*/ fclose( inpFile ); fclose( outpFile ); return ( outpFileName ); } /* end of CreateMadlib*/ /* * Function: PrintFile * -------------------------------------- * opens the file and repeatedly read a char * from it and prints it to standard output, until * the end of file is reached */ void PrintFile( string fileName ) { FILE *inFile ; int ch; /*open file*/ inFile = fopen( fileName, "r" ); /*handle error*/ if ( inFile == NULL ) { printf(ERROR_OPEN); exit(-1); } /*read and print until EOF reached*/ while( (ch = getc( inFile )) != EOF ) { printf("%c", ch ); } /*close*/ fclose( inFile ); } /* end PrintFile*/ /*----- End of file -------*/ /* * File: hw4-life.c * Author: Matheen Siddiqui * Class: cs113 * Assignment: homework 4 * Due Date: October 16, 1997 * Last modified: October 16, 1997 * ----------------------------------------------------- * * USAGE: hw4-life lifedatafile * ====== This program takes the name of the life data file, which contains data on the dimensions of the board as well as the what rounds to display and the initial status of the life board. The first two numbers on the file are the number of rows followed by the number of columns, of the initial life board. Then on the next line is the number rounds to display, followed by the total number of rounds to print at the start and finish of the simulation (half at begining and half at the end). Then there is one return and the life board is on following lines. * * OVERVIEW: * ========= This program displays starting and ending rounds of the game of life, given the inital status of the life board in a file described above. * * Algorithm Notes: * ================ The data sturcture to hold the life board, is a single array treated as a doulbe. In addition there is a border of size EDGE_ROW on the top and bottom of the board as well as a boarder of size EDGE_COL on the sides of the virtual 2d array. The cells on this border can be written to and are considered when calculating subsequent rounds. But they are not displayed, the center region of this array is then considered the visible area. In this program there is a separation between the visible array and the actual array. Functions that access the visibile array will treat the upper left as 0,0 as apossed to its actual location which depends the border size. The functions used to change cells in the visible array will return true if a live cell is placed in this boarder. Board can then be rediminsionlized to include the border cells, and create a new boarder. * * Enhancements: * ============= The program uses the idea of an infinite board. So life can grow beyond the edges of the board, and when that happens the board is redimensionalized. * */ /*--------------------Includes-------------------*/ #include #include "genlib.h" #include "simpio.h" #include /*-------------------Constants------------------*/ /* LIVE_CELL is the symbol for a living cell DEAD_CELL is the symbol for a dead cell CENTER_LIVE is the symbol for the living center cell CENTER_DEAD is the symbol for the dead center cell NUM_OVER_CROWD is the lower limit of living neighbor a cell must have if it dies from over crowding NUM_EXPOSER is the upper limit on the number of living neighbors a cell will have if it dies of exposer NUM_BIRTH is the number of neighbors a dead cell must have if it must be reborn EDGE_ROW is the number of rows used as the top and bottom boarders EDGE_COL is the number of columns used as the left and right boarders */ #define LIVE_CELL 'o' #define DEAD_CELL '.' #define CENTER_LIVE 'O' #define CENTER_DEAD ':' #define NUM_OVER_CROWD 4 #define NUM_EXPOSURE 1 #define NUM_BIRTH 3 #define EDGE_ROW 1 #define EDGE_COL 1 /*-------------------Type defines-------------------*/ /* cellT is the type of a single cell boardTypeT is the type of the board that holds the cell lifeBoardT is a type, that is a sturct holding complete information on a life board, dimension etc. */ typedef char cellT; typedef cellT* boardTypeT; typedef struct { int numRow, /*the number of visible rows in the board*/ numCol; /*the number of the visiible columns in the board*/ int actRow, /*the actual number of rows in the board*/ actCol; /*the actual number of columns in the board*/ int numEdgeRow, /*the extra rows and colums*/ numEdgeCol; /*used for the board*/ boardTypeT board; } lifeBoardT; /*--------------------Prototypes------------------*/ /* * Function: InstructUser * Usage: InstructUser(); * ------------------------------------ * prints instructions to stdout */ void InstructUser( void ); /* * Function : SimulateGame * Usage: SimulateGame( lifeBoard_ptr, roundsToSimulate, roundsToDisplay); * ------------------------------------ * This function simulates the game of life for an intial life board pointed to by lifeBoard_ptr (lifeBoardT*). the int roundsToSimulate holds the number of rounds to simulate, and the first and last roundsToDisplay/2 rounds are displayed */ void SimulateGame(lifeBoardT *lifeBoard_ptr, int roundsToSimulate,int roundsToDisplay); /* * Function : ReadGameFile * Usage: lifeBoard_ptr = ReadGameFile( fileName, &roundSim, &roundDisplay) * ------------------------------------ * This function returns a pointer to a life board (lifeBoard*) * contianed in the file called fileName (string). * The address of the ints roundSim and * roundDisplay are passed, so they will contain the number of rounds * to simulate and number of rounds to display after the call. */ lifeBoardT* ReadGameFile( string fileName, int *roundSim_ptr, int *roundDisplay_ptr ); /* * Function : DisplayBoard * Usage: DislayBoard( lBoard_ptr ) * ------------------------------------ * this function displays the contents of the visible portion of * the life board pointed to by lBoard_ptr (lifeBoardT*) */ void DisplayBoard( lifeBoardT *lBoard_ptr ); /* * Function : UpdateBoard * Usage: UpdateBoard( lBoard_ptr ) * ------------------------------------ * This function calculates the new status of each cell int the life board * board pointed by lBoard_ptr (lifeBoard*) after one * round in the game of life. After the update the boards dimentions * may be different, if new life is created beyond the current visible, * area of the board. */ void UpdateBoard( lifeBoardT *lBoard_ptr ); /* * Function : FateCell * Usage: newCell = FateCell( lBoard_ptr, row, col ); * ------------------------------------ * This function will tell what the cell, located at the * row row (int) and column col (int) of the visible portion of the * life board pointed to by lBoard_ptr (lifeBoardT*), becomes in the next * round. a cellT is returned and it will be LIVE_CELL * DEAD_CELL, CENTER_LIVE, or CENTER_DEAD, depending on what happens * to the cell acording to the rules of life. */ cellT FateCell( lifeBoardT *lBoard_ptr, int row, int col); /* * Function : CountNeighbors * Usage: numNeigh = CountNeighbors( lBoard_ptr, row, col ); * ------------------------------------ * This function will return the number of living neighbors * a cell at row row and column col (both int) of the visible portion of * the life board pointed to lBoard_ptr (lifeBoardT*) * the has. */ int CountNeighbors( lifeBoardT *lBoard_ptr, int row, int col ); /* * Functions : PlaceCell SetBoard * Usage: reSize = PlaceCell( lBoard_ptr, row, col, item );' SetBoard( lBoard_ptr, row, col, item ); * ------------------------------------ * PlaceCell will place item (cellT) at the location row row and column * col (both int) of the visible portion of * the life board pointed to lBoard_ptr (lifeBoardT*). * It returns TRUE if the a live cell was placed outside the * visible area of the lBoard_ptr. FALSE is returned otherwise. * You can Place a cell outside of the visible area, as long as it * is in the buffer. (so you could make a call like PlaceCell(-1,-1). * * SetBoard places item (cellT) at the row col postion of board pointed to by * lBoard_ptr(lifeBoard*), but the position is messured in terms of * the actual array (off screen buffer is included). */ bool PlaceCell( lifeBoardT* lBoard_ptr, int row, int col, char item ); void SetBoard( lifeBoardT* lBoard_ptr, int row, int col, char item ); /* * Function : GetBoard GetCell * Usage: GetBoard( lBoard_ptr, row, col ); GetCell( lBoard_ptr, row, col ); * ------------------------------------ * GetBoard and GetCell return the type of cell (cellT) at the * location row col (ints). GetBoard finds the status of the location in the * actual array, while GetCell finds that of the visible array. * With GetCell you can access elemnts just outside the range of the array, * if there is a buffer. So GetCell(-1,1) would return the cell in the buffer, * at that location. * * Both return DEAD_CELL if a location outside the actual array is * specified. */ cellT GetBoard( lifeBoardT* lBoard_ptr, int row, int col); cellT GetCell( lifeBoardT* lBoard_ptr, int row, int col); /* * Function : IsAlive * Usage: alive = IsAlive( lBoard_ptr, row, col ); * ------------------------------------ * This function returns TRUE if the cell at row * row and column col (both int) of the visible portion of * the life board pointed to lBoard_ptr (lifeBoardT*), is alive. * FALSE otherwise. */ bool IsAlive( lifeBoardT* lBoard_ptr, int rows, int col); /* * Function : AllocateBoard * Usage: newBoardPtr = AllocateBoard( row , col ); * ------------------------------------ * This function returns a pointer to a board of visible dimensions row, col * and is initialized such that each cell is a DEAD_CELL. */ lifeBoardT* AllocateBoard( int rows, int col ); /* * Function : ReSize * Usage: Resize( lBoard_ptr ); * ------------------------------------ * This function rediminsialzes the board pointed to by lBoard_ptr(lifeBoard*) * by adding numEdgeRow to the top and bottom of the double array * and numEdgeCOl columns on each side. The information * in the board remains centered. Thus, the cells in the offscreen * buffer become part of the visible array and a new buffer is created. */ void ReSize( lifeBoardT* lBoard_ptr ); /* * Function: CopyBoard * Usage: CopyBoard( destBoard_ptr, srcBoard_ptr, shiftR, shiftC ); * ------------------------------------ * This function copys the board at srcBoard_ptr to the board at * destBoard_ptr (both lifeBoardT*). The boards don't have to be * of the same dimension. shitfR and shiftC give the displacements in * the row and column when copying so you can have srcBoard_ptr placed * in a certain location of destBoard_ptr. */ void CopyBoard( lifeBoardT *destBrd_ptr, lifeBoardT* srcBrd_ptr, int shiftR, int shiftC ); /* Function: MoveBoard * Usage: MoveBoard( dest_ptr, orig_ptr ); * -------------------------------- * This function moves the lifeBoard pointed to by orig_ptr and moves * it to the boad pointed to by dest_ptr, (both lifeBoardT*). In the * proccess orig is is completely destroyed, and the old board part * of dest_ptr is freed. */ void MoveBoard( lifeBoardT* dest_ptr, lifeBoardT* orig_ptr ); /* Function: KillBoard * Usage: KillBoard( board_ptr ); * ------------------------------- * frees board pointed to by board_ptr(lifeBoardT*); */ void KillBoard( lifeBoardT* board_ptr ); /*---------------------------Main------------*/ int main(int argc, string argv[]) { lifeBoardT *lifeBoard_ptr; int roundDisplay, /*number of round to display at start and end of game*/ roundSim; /*rounds to simulate*/ string fileName; /*name of life data file*/ InstructUser(); /* if syntax is wrong, exit with error message */ if (argc != 2) { Error("You didn't pass a file\nSyntax: %s ", argv[0]); } fileName = argv[1]; /*read file and simulate game*/ lifeBoard_ptr = ReadGameFile(argv[1], &roundSim, &roundDisplay); SimulateGame( lifeBoard_ptr, roundSim, roundDisplay); /*get read of board*/ KillBoard( lifeBoard_ptr ); exit(0); } /*end of main*/ /* * Function: InstructUser * ------------------------------------ */ void InstructUser( void ) { printf("This program will print rounds of the game of life\n" "for the board given in the passed data file.\n" "The data file contains the number of rows followed\n" "by the number of columns of the initial board\n" "followed by the number of rounds to simulate and the\n" "number of rounds at the begining and end to display.\n" "Imidatey after the last line is a return and then the\n" "board in a table format.\n\n" ); } /* * Function :SimulateGame * ------------------------------------ * Calls DisplayBoard and UpadateBoard. * This function calculates all rounds, but only dislays those * at the start and end. */ void SimulateGame(lifeBoardT *lifeBoard_ptr, int roundsToSimulate,int roundsToDisplay) { int i, /*loop counter*/ numFirst, /*the number of grids to display at the begining*/ startLast; /* the starting index of the last bunch to display*/ /*initilize what rounds to display*/ numFirst = roundsToDisplay / 2; startLast = roundsToSimulate - roundsToDisplay / 2 + 1; /*if odd take off an extra round at the end*/ if ( roundsToDisplay % 2 != 0 ) { startLast--; } /*display first bunch of rounds*/ printf("The first %d of %d rounds of the game:\n\n", numFirst, roundsToSimulate ); for( i = 0 ; i < numFirst; i++ ) { printf("----------|round = %d|-----------\n" , i); DisplayBoard( lifeBoard_ptr ); UpdateBoard( lifeBoard_ptr ); } /* i doesnt need to be reinitilzed, since this loop is * continuation of the last*/ /*calculate rounds till the ending rounds*/ for( ; i < startLast; i++ ) { UpdateBoard( lifeBoard_ptr ); } /*print last bunch of rounds*/ /*again i doesn't need to be reinitialized*/ printf("The last %d rounds of the game:\n\n", roundsToDisplay - numFirst ); for( ; i <= roundsToSimulate; i++ ) { printf("---------|round = %d|--------------\n", i ); DisplayBoard( lifeBoard_ptr ); UpdateBoard( lifeBoard_ptr ); } } /*end of SimulateGame*/ /* * Function : ReadGameFile * ------------------------------------ * uses stdio.h to read the game file * It reads a row of cells at a time (in a string) and * then assigns each cell of the board. */ lifeBoardT* ReadGameFile( string fileName, int *roundSim_ptr, int* roundDisplay_ptr ) { int rows, col, /*row and colums of the visible area of board*/ r, c; /*loop counter vars*/ lifeBoardT *tpBoard_ptr; /*game board to hold data in file*/ FILE *inFile; /*pointer to the board data file*/ string rowCell; /*one row of the board data*/ /*open the file, handling error on open*/ inFile = fopen( fileName,"r" ); if (inFile == NULL ) { printf("ERROR opening file"); exit(-1); } /*read the number of rows and columns as well as rounds to simulate and display*/ fscanf( inFile,"%d", &rows ); fscanf( inFile,"%d", &col ); fscanf( inFile, "%d", roundSim_ptr ); fscanf( inFile, "%d", roundDisplay_ptr ); /*allocate board*/ tpBoard_ptr = AllocateBoard( rows, col ); /*allocate room for a row*/ rowCell = (string) GetBlock( col + 1 ); /* set the cells in the visible area of the board * to the values assigned in the file */ for( r = 0; r < rows ; r++ ) { /*read in a row of cells*/ fscanf(inFile," %s ", rowCell ); /*assign row of cells to the board*/ for( c = 0 ; c < col; c++ ) { PlaceCell( tpBoard_ptr, r, c, rowCell[c] ); } } /*free allocated mem*/ free( rowCell ); return tpBoard_ptr; } /*end of ReadGameFile*/ /* * Function : DisplayBoard * ------------------------------------ * Uses nested for to accss all elements of the visible region of life Board * and print them to screen */ void DisplayBoard( lifeBoardT *lBoard_ptr ) { int r, c; /*loop counters*/ /* print visible region of board so limits of * the loop var are numRow and numCol */ for( r = 0; r < lBoard_ptr->numRow ; r++ ) { for( c = 0 ; c < lBoard_ptr->numCol; c++ ) { printf("%c", GetCell( lBoard_ptr, r,c )); } /*blank return*/ printf("\n"); } } /*end DisplayBoard*/ /* * Function : UpdateBoard * ------------------------------------ * First create a new board then put the fate of each cell of the old * board at the location of the new board. Also include the cells in the * offscreen buffer. Then resize if neccary. */ void UpdateBoard( lifeBoardT *lBoard_ptr ) { int r, c; /*loop counters*/ lifeBoardT *newLBoard_ptr; /*the new life board*/ bool sameSize = TRUE; /*tells if the new board needs to be resized*/ int startR, endR, /*the limits of loop varriables*/ startC, endC; /*or range to update*/ newLBoard_ptr = AllocateBoard( lBoard_ptr->numRow, lBoard_ptr -> numCol ); /* for loops go from -1 to one out of the array to see if * a new cell will be born outside the visible part of the board. * If a new cell is born PlaceCell will return true, signifying that * a cell was writtin out of the vissible part of the array, thus * the bool sameSize gets false so it the array will be resized. */ startR = -1; endR = lBoard_ptr->numRow +1; startC = -1; endC = lBoard_ptr->numCol + 1; for( r = startR; r < endR ; r++ ) { for( c = startC; c < endC ; c++ ) { if (PlaceCell( newLBoard_ptr, r, c , FateCell(lBoard_ptr,r,c ) )) { sameSize = FALSE; } } } /*end outer for*/ /* resize the board if neccisary*/ if( !sameSize ) { ReSize( newLBoard_ptr ); } /* move board * give the board pointer the information*/ MoveBoard( lBoard_ptr, newLBoard_ptr ); } /*end of UpdateBoard*/ /* * Function : FateCell * ------------------------------------ * Calls IsAlive and NumNeighbor to determine status in next round. * tp vars deadCell and liveCell, are used to handle the case * where the current cell is a center cell. */ cellT FateCell( lifeBoardT *lBoard_ptr, int row, int col) { cellT deadCell = DEAD_CELL, /* symbol for a dead cell*/ currCell, /* the current status of cell*/ liveCell = LIVE_CELL; /*symbol for a live cell*/ int numNeighbors; /* if the current cell is a center cell, then deadCell and liveCell * are assigned the CENTER_DEAD and CENTER_LIVE respectively, to * ensure a center cell is returned */ currCell = GetCell( lBoard_ptr, row, col ); if ( currCell == CENTER_DEAD || currCell == CENTER_LIVE ) { deadCell = CENTER_DEAD; liveCell = CENTER_LIVE; } /*find number of neighbors*/ numNeighbors = CountNeighbors( lBoard_ptr , row ,col ); /*now return dead or alive depending on the rules of life*/ if ( IsAlive( lBoard_ptr, row,col) ) { /* if die of over crowding or exposure return deadCell * otherwise live cell is returned*/ if ( numNeighbors >= NUM_OVER_CROWD || numNeighbors <= NUM_EXPOSURE ) { return deadCell; } else { return liveCell; } } else if ( numNeighbors == NUM_BIRTH ) { /*return live cell if a cell can be born*/ return liveCell; } else { return deadCell; /*cell remains dead*/ } } /*end of FateCell*/ /* * Function : CountNeighbors * ------------------------------------ * loops around a cell and counts number of live * cells using IsAlive */ int CountNeighbors( lifeBoardT *lBoard_ptr, int row, int col ) { int r,c, /*loop vars*/ numLive = 0, /*the number of live cells around cell at row col*/ startR, endR, /*the limits of loop varriables*/ startC, endC; /*or locations in the array to check for life*/ /* the neighbors of a current cell are * one unit away for the cell, so the limits of the * nested loop are row/col +/- 1*/ startR = row -1; endR = row +1; startC = col - 1; endC = col + 1; /* loop and check for live neighboars, but don't count * the cell who youre finding neighbors for as a neighbor*/ for( r = startR; r <= endR; r++ ) { for( c = startC; c <= endC; c++ ) { /*second part of conditional ensures current cell isn't counted *as alive*/ if ( IsAlive( lBoard_ptr, r, c ) && !(r == row && c == col) ) { numLive++; } } } /*outer for*/ return numLive; } /* end of CountNeighbors*/ /* * Function : PlaceCell * ------------------------------------ * recalculates row and col acording to the size of the * buffer and uses SetBoard * */ bool PlaceCell( lifeBoardT* lBoard_ptr, int row, int col, char item ) { bool needResize = FALSE; /*if it writes to a live cell to part off the visible area then true needs to be returned to tell calling function to resize*/ if ( row >= lBoard_ptr-> numRow|| row < 0 || col >= lBoard_ptr -> numCol || col < 0 ) { if (item == LIVE_CELL || item == CENTER_LIVE) { needResize = TRUE; } else { needResize = FALSE; } } /* shift row and col accordingly to set the position in the * actual array*/ SetBoard( lBoard_ptr, row + lBoard_ptr -> numEdgeRow, col + lBoard_ptr -> numEdgeCol, item ); return needResize; } /*end of PlaceCell*/ /* * Function : SetBoard * ------------------------------------ * Uses the offset formual to find the position of * the element to be set, in the single array used as * a double array. */ void SetBoard( lifeBoardT* lBoard_ptr, int row, int col, char item ) { lBoard_ptr->board[ (lBoard_ptr->actCol)*row + col ] = item; } /* * Function : GetBoard * ------------------------------------ * Asumses cells out of the Actual Array are dead. * other cells are in a single array and the postion is * found using the offset formula. */ cellT GetBoard( lifeBoardT* lBoard_ptr, int row, int col) { /*if out of bounds of the actual array, the cell is dead*/ if ( row < 0 || row >= lBoard_ptr->actRow || col < 0 || col >= lBoard_ptr->actCol ) { return DEAD_CELL; } return lBoard_ptr->board[ (lBoard_ptr->actCol)* row + col ]; } /*end of GetBoard*/ /* * Function : GetCell * ------------------------------------ * calculates position in actual array acording to the * size of the buffer, and calls GetBoard */ cellT GetCell( lifeBoardT* lBoard_ptr, int row, int col) { /*convert the location to the position of the double array with the buffer boarder*/ return GetBoard( lBoard_ptr, row + lBoard_ptr->numEdgeRow , col + lBoard_ptr->numEdgeCol ); } /*end of GetCell*/ /* * Function : IsAlive * ------------------------------------ * Calls GetCell and compares it to LIVE_CELL and CENTER_LIVE */ bool IsAlive( lifeBoardT* lBoard_ptr, int rows, int col) { cellT cell; cell = GetCell( lBoard_ptr, rows, col ); return cell == LIVE_CELL || cell == CENTER_LIVE; } /*end of IsAlive*/ /* * Function : AllocateBoard * ------------------------------------ * Calls malloc to create a single array to represent a double. * rows and col are the dimension of the visible area, so * the buffer border must be allocated to. */ lifeBoardT* AllocateBoard( int rows, int col ) { lifeBoardT *tp; /*newly made liveboard */ int lengthArr , /*length of the single array that holds the board*/ i; /*loop var*/ /* length of the single array with the buffer. EDGE_ROW/COL * is the size of the border so a factor of 2 is used to * get the actual size*/ lengthArr = (rows + 2*EDGE_ROW ) * ( col + 2*EDGE_COL ); /*alocate the lifeBoard and the board itself*/ tp = (lifeBoardT*) GetBlock( sizeof( lifeBoardT )); tp->board = (boardTypeT) GetBlock( sizeof( cellT ) * lengthArr ); /*assign row and column size of visible area*/ tp->numRow = rows; tp->numCol = col; /* assgin the actual row and column size*/ tp-> actRow = rows + 2* EDGE_ROW; tp-> actCol = col + 2* EDGE_COL; /* assign the border size*/ tp->numEdgeRow = EDGE_ROW; tp->numEdgeCol = EDGE_COL; /*initilize all of them to dead*/ for( i = 0 ; i < lengthArr; i++ ) { tp->board[i] = DEAD_CELL; } return tp; } /*end of AllocateBoard*/ /* * Function : ReSize * ------------------------------------ */ void ReSize( lifeBoardT* lBoard_ptr ) { /*will be the new life board*/ lifeBoardT *tpBoard_ptr; /* allocate this board to be bigger by then the last, * numRowEdge/ColEdgeo,describe how to "zoom out" of * current board so a factor of 2 is used*/ tpBoard_ptr = AllocateBoard( lBoard_ptr->numRow + 2*lBoard_ptr->numEdgeRow, lBoard_ptr->numCol + 2*lBoard_ptr->numEdgeCol); /* copy the old boards information into the center * of the new one*/ CopyBoard( tpBoard_ptr, lBoard_ptr, lBoard_ptr->numEdgeRow, lBoard_ptr->numEdgeCol ); /*get rid of old board and put in new one*/ MoveBoard( lBoard_ptr, tpBoard_ptr ); } /*end of ReSize*/ /* * Function : CopyBoard * ------------------------------------ * copys srcbord into dest element by element. Since * GetBoard returns a dead cell if the row col location requested * is off the actual board, the range of the srcBord doesn't * need to be check explicitly here */ void CopyBoard( lifeBoardT *destBrd_ptr, lifeBoardT* srcBrd_ptr, int shiftR, int shiftC ) { int r, c; /*loop counters*/ /* go through each element of destBrd_ptr and assign it * a value from the srcBoard, using the shifts to place * the old board into the new one properly*/ for( r = 0; r < destBrd_ptr->actRow; r++ ) { for( c = 0 ; c < destBrd_ptr->actCol; c++ ) { SetBoard( destBrd_ptr, r, c, GetBoard( srcBrd_ptr, r -shiftR, c -shiftC )); } } } /*end of CopyBoard*/ /* Function: MoveBoard * -------------------------------- * uses free and changes pointers */ void MoveBoard( lifeBoardT* dest_ptr, lifeBoardT* orig_ptr ) { free( dest_ptr -> board ); *dest_ptr = *orig_ptr; free( orig_ptr ); } /* Function: KillBoard * ------------------------------- */ void KillBoard( lifeBoardT* board_ptr ) { free( board_ptr -> board ); free( board_ptr ); } /* end of file */ -- END OF LOG FILE FOR siddiqui --