Computer Science I for majors by James Tam |
Due at 4 PM. For assignment due dates see the main schedule on the course webpage.
Starting code: /home/assignments/assigment4/code (you must use this starting code, if you write your own code it must have the equivalent capability)
Input files: /home/assignments/assigment4/inputs (your program must work with these inputs files)
Output files: /home/assignments/assigment4/outputs (the TA will compare your program output vs. the output in these files, the patterns must match in order for credit to be awarded).
You are to implement a text-based version of Conway's "Game of Life" biological simulation. Each location in the simulated world either contains: an empty space or a life form ("critter"). As each time unit (a "turn") passes in the simulation a new critter may be born into an empty square or an existing critter may die off. The rules of births and deaths will be specified in the next section.
With the pre-written There are two approaches for reading the starting information from file. There is no advantage to using one vs. another. One approach splits the task into two functions to make things easier for students to understand while the other combines the tasks into one function. Both functions return a list that has been initialized from the data in the specified file. If there is problems reading from the input file (e.g. wrong file name entered) then the list will display all exclaimations '!'.
1) Option I, using a single function: createListFileRead(). The function creates a new empty row with each iteration of the outer loop. The inner loop successively appends new data (read in from file) onto the new row.
2) Option II, using two functions: initialize() and readFromFile(). The first function creates the list row by row and then appends a default value for each element '!' to the end of each row. The second function performs all of the file input. Line by the line the text from the input file is read in and the along that line each character is used to set each element of the list.
The input file will specify the starting positions for most of the main elements in the simulation:
'*' represent an instance of a Critter.
A space represents an empty location in the world.
There are several input files in the course directory with different starting patterns of Critters that range from an empty world to complex patterns of biospheres. The more of these input files that your program can correctly process, the higher will be your grade. Each of these input files will produce a 10x10 list. Your program does not have to handle input files that produce lists of other sizes. To allow you check your work there are also output files (one per input file) that show the effect of different starting patterns. Important grading point: Your program functionality marks will only be awarded if your program produces the same results as these outputs. For example, file "1empty.txt" starts out empty and should therefore never contain a Critter in the pattern. Input file "6complex.txt" will produce a stable pattern of 4 Critters in a square by turn 20. Partial marks will not be awarded if your pattern of Critters is "close" to the pattern produced my program. Both of these requirements (producing the same patterns in your output and documenting which input files that your program correctly handles is necessary to make the marking process reasonable - don't expect the marker to spend hours tracing code to figure out if things are working). However, providing ahead of time the results that your program must display is also an advantage for you. You will know if your program is "working or not" based on the pattern match (immediate and continuous feedback). But looking at the patterns is not a substitute for implementing and employing a debugging mode. The debugging mode can be very useful for helping you determine why and how your program is malfunctioning (if you have good debugging output messages)
The input files can be found under: /home/231/assignments/assignment4/inputs. The corresponding output files can be found under: /home/231/assignments/assignment4/outputs.
Another requirement to get any credit for your assignment is that the display of the grid must be done using the display() function provided or you must write an equivalent function yourself. This grid is required because it makes the display of world easier to read and interpret for both you and the marker.
Once the information has been read into the 'world' list and copied into the 'newWorld' list your program will employ the [rules of births and deaths]. When the program first runs the list displayed on the left should display the state of the world read in from file ("before") while the one on the right displays the state of the world after births and deaths have occurred. You will need to modify the starting program so that each turn the state of the world before the turn is displayed on the left and the results of the turn (after births and deaths have occurred) are displayed on the right [Sample screenshot using the input file "5edge_cases.txt"].
After initializing the starting positions, the program will simulate the births and deaths of the critters over time on a turn-by-turn basis. The user can either hit <enter> to advanced the simulation by another turn, 'q' or 'Q' to end the simulation. [Debug mode] can be toggled by entering 'd' or 'D' when prompted to proceed to another turn. The births and deaths of critters is based solely upon the number of neighbors in neighboring squares. Each square will have from 3 - 8 neighboring squares (inner squares have 8, outer squares can have 3 at corners or 5 on the top/bottom/left/right edges). The square where the possibility of a birth or death is being examined is marked with a question mark ? in the examples below.
|
|
||||||||||||||
Bottom right corner | An inner square |
Births (square is currently empty)
A birth can occur in an empty square if that square has exactly 3 neighbors, some (non-exhaustive) examples:
* * ? *
* ? * * Deaths (square currently contains a Critter).
A Critter can die of loneliness if it has zero or only one neighbor.
?
? * A Critter can die of overcrowding if it has four or more neighbors (non-exhaustive number of examples below):
* * ? * *
* ? * * * * The Critter will remain living if it has 2 or 3 neighbors.
? * * *
Births and deaths will occur simultaneously in the simulation. How do the rules of births and deaths relate to the 10x10 world? Each turn the check for births and deaths must be made in each of the 100 squares. As was the case when reading from file the 'before' case is shown on the left and 'after' case is shown on the right.
Entering 'd' or 'D' will toggle debugging mode (on becomes off, off becomes on). The flag 'debugOn' will track whether debugging message are to appear or not:
debugOn = False
When the flag is set to 'True' debugging messages will appear, otherwise they will not:
if(debugOn == True):This global variable for the debugging flag is the sole exception on the prohibition on the use of global variables in your program. No penalty will be applied for using it but the usual penalty will be applied for other globals.
The exact content of the debugging messages is left to your descretion. As the name implies the debugging tool should be used to help you test and debug your program. Here are examples of debugging messages[1) Display of the neighbor count for each square (using data file: "5edge_cases.txt") 2) Messages specifying where births and deaths have occurred (using data file "3one_birth.txt")]. Again you are not bound to produce these exact messages in order to get credit for the debugging feature but they are provided to give you an idea of how you can use this feature to test your program.
D2L configuration:
Points to keep in mind: