Can Computers Think?
Introduction to Computer Science

CSC 106
Union College
Winter 2010

Programming Project 3 - due Friday, February 19, at the end of the day

Working in teams

The same rules apply as for the first programming projects. You can work on this project in teams of at most two people. If you do decide to work on this project with somebody else, please let me know by Thursday in class that you are working together. Then submit a joint solution. Note: that you cannot work with the same partner on more than two programming projects. That is, if you worked with the same partner on the first two programming projects, you will have to find somebody else to work with for this project.

If you work with a partner, please use pair-programming techniques similar to what we do in the lab. That way you ensure that both partners are contributing and that both partners understand your solution and why and how it works. Do not split up work.

You should not collaborate with anybody outside of your team. Plagiarism of code is equally bad as plagiarism of other written material. And as with other written material, you have to credit any source that you use. You are welcome to discuss the problems with other people and to talk about general solution strategies. However, to be safe, you should never look at somebody else's code or let anybody else see your code. And you should never write down any code in those discussions. If you get completely stuck, please come to see me and I will point you in the right direction.

The goal

For this project, you will implement Conway's Game of Life. We talked about it in class. To review the rules for how a new generation is based on the last generation see the Wikipedia page about Conway's game of life.

Step 0: Code to start from

Download the following two files and save them in the same place/folder:

As for the grid exercises that we did in class, the file gol_display.py contains the code necessary for visualizing the game of life grid. Note how the file gol_getting_started.py imports the function run_game from gol_display.py. The function run_game is very similar to the function run_display from the grids exercise, but it has one more parameter. The value for this additional parameter should be the name of the function that calculates what the next generation of the grid will look like. In gol_getting_started.py this function is called next_gen. At the moment, this function doesn't do anything useful. It will be your job to provide the code.

To run the program in gol_getting_started.py you need to call the function play_gol. When you run it right now, you just see a green circle on a blue background. The green circle is the start/stop button. When you press it, the function run_game starts calling the function that calculates the next generation every few hundred miliseconds; when you press it again, it stops calling the next generation function. Right now, this is not really useful because we don't even have a grid, yet. So, that's your first step.

Step 1: Create a grid of dead cells

Complete the function create_grid, such that it creates a new grid of the desired size indicated by the parameters. All cells in that grid should be dead. That is, the grid should be represented as a list of lists, and the inner lists should be filled with 0's.

(Hint: this is very similar to what you did for the grid exercise that you worked on in class. Study the solution to the grid exercise, if you are having problems.)

You should now be able to run your program and you should see a grid of purple squares.

Step 2: Make the grid clickable

When the user clicks on a cell that cell should change its status: dead cell should become alive and life cells should die.

(Again, very similar to what you did for the grid exercise.)

You should now be able to run your program and you should see a grid of purple squares and when you click on a cell, it should turn orange and when you click on it again, it should turn purple again.

Step 3: Count the life neighbors of a cell

To be able to calculate the next generation, we need to count how many life neighbors each cell has. So, one important subtask is to count how many life neighbors a given cell has. We will use the function life_neighbors to carry out this task.

Complete the function life_neighbors to count how many life neighbors the specified cell has. The function takes three parameters: the grid and the row and column identifying the cell we are interested in. The function should return one number, which is the number of life neighbors of the cell identified by the row and column number.

Watch out for the edges of the grid! If the given cell is at the edge, it should take the cells at the opposite edge to be adjacent. For example in the following picture, all of the dark red cells are considered to be adjacent to the green cell.

GOL - counting neighbors

How can you test this function? Eventually, it will be called by the function next_gen for every cell of the grid. But we don't have that function, yet. Therefore, to test life_neighbors, you have to write some special code just for testing it. Specifically, here is what you can do. Comment out the two lines of code that are already in next_gen and instead copy the following code into next_gen:

    n1 = life_neighbors(grid,0,0)
    n2 = life_neighbors(grid,0,1)
    n3 = life_neighbors(grid,1,1)
    print "The cell at row 0 and col 0 has ",n1," life neigbors."
    print "The cell at row 0 and col 1 has ",n2," life neigbors."
    print "The cell at row 1 and col 1 has ",n3," life neigbors."
    print
    return grid

Then you can run your program, click on some cells to make them alive, and then click on the green button to start "evolving". We are not actually evolving anything, yet, and your visualization should not change, so you can quicly click on the green button again to stop it. But in the Python shell window you should see a print out which tells you how many life neighbors three specific cells have. Try different configurations of life cells and make sure that your function counts them correctly.

Step 4: Compute the next generation

Now you are ready to apply the function life_neighbors to every cell in the grid. Set the corresponding cell in the new grid should be set to be alive or dead according to the rules:

Have fun trying out some different starting configurations. See the Wikipedia page for inspiration.

Step 5: Submit on Blackboard

Submit your .py files on Blackboard. There is a link in the "Assignments" section.