Cellular Automata Project: Part 2,
Conway's Game of Life

For the second project deliverable, you will implement a version of Conway's Game of Life (CGoL). The key notion of CGoL is that each cell lives or dies according to these simple rules:

The main difference from your Project 1 is that we now have a two-dimensional universe of cells and instead of displaying a trace of the organisms over time, we will animate the changes across the entire two-dimensional space all at once. As before, you will need to find the neighbors of a given cell in order to determine its life status at the next time step. However, now each cell has eight (8) neighbors.

Definitions and other details

You will want to think about how to decompose the problem into simple functional chunks. You should define a type, grid, using Scheme vectors. That is, the grid should be a (vectorof (vectorof cells)), where a cell is defined by you and represents a state. You will want a function that displays a given grid. It may be helpful to think of the grid as a vector of rows, each of which is a vector of cells in columns.

Ultimately, you must write a function, cgol, that consumes a number and a grid: the number specifies how many generations to simulate, and the grid represents the initial state of the cellular automata. The number of rows and columns necessarily follows from the initial grid; this will determine the height and width of your display based on the size of a cell. The cgol function simulates the game of life for the appropriate number of generations using the initial grid. Make sure that your code works with different dimensions of initial grids. For each generation, the life-status of each cell should be checked and updated according to the rules given above, and then the grid should be redrawn.

You should include a global identifier, WRAP?. When true, the grid should wrap from edge to edge and top to bottom. That is, a cell along the bottom edge has five neigbors immediately adjacent, and three more neighbors along the top row of the gird. Likewise, the cell in the upper left corner has neighbors that include the lower right corner, the two-leftmost cells in the last row, and the right-mose cells in the top two rows. When WRAP? is false, you should perform updates as if the grid is ringed by a border of dead cells that never come to life.

Make sure that the new life-status of one cell does not interfere with the update of an adjacent cell. Use the big-bang function provided by 2htdp/universe, together with 2htdp/image teachpacks to create the animation. Cells may be rendered as either circles or squares, but the live or dead status of cells should be represented by two easily distinguished colors.

For a given cell dimension size, d, and a given grid, G, your display image would be d * (vector-length G) pixels tall, and d * (vector-length (vector-ref G 0)) pixels wide.


  1. Top-level constants. You must define top-level identifiers: CELL-SIZE for the size of a rendered cell (either diameter or square edge length); WRAP? that when true causes cells on the edge of the grid to be treated as neighbors of cells on the opposite edges.
  2. Random grid. Write a function, random-grid that consumes two numbers for row and columns and a third number for the probability of a live cell. Your function should return a grid (as defined with vectors above) that has been appropriately initialized.
  3. Updating grids. Write a function, update-CA2, that consumes a grid and produces a new grid based on the update rules applied to the given grid. As described above, the updates around the edges should reflect the current value of WRAP?.
  4. Rendering grids. Write a function, draw-CA2, that consumes a grid and returns an image. The size of the resulting image should reflect the CELL-SIZE and the number of rows and columns in the given grid.
  5. Animating the Game of Life. Write a function, cgol, that consumes a number and a grid. The number specifies how many generations to simulate, after which the animation should stop. The given grid represents the initial state of the cellular automata that is subsequently updated/animated. The number of rows and columns necessarily follows from the initial grid that is provided; this should determine the height and width of your animated display.


Do not forget to include the standard acknowledgements header at the top of your file. To grade this deliverable, I will review your code (including contracts, purpose statements, test cases, indentation, etc.), and then call cgol with a given number of steps to simulate and an initial organism of my choosing.

Submit a single file with your username followed by “P2.rkt” as the name of the file, which should contain your code fulfilling the above requirements as well as your acknowledgements.