CS 161 Lab G - Game of Life
Due Thurs Mar 14 at 11:59pm
Overview
First off, happy Pi Day!
In this lab, you will investigate Conway's "Game of Life", which isn't actually a game, but is very interesting. The Game of Life is played on a square grid of cells, each of which may be "alive" or "dead". Given one state of the grid, you update the grid to a new state (a new "generation") based on the number of neighbors of each cell. Read the above-linked article for the rules; the quick version is that living cells stay living with 2 or 3 neighbors, and dead cells become alive with exactly three neighbors.
Here are a couple of pictures of the game in progress:
After evolving for a while, the board usually settles into a state somewhat like this:
In this week's lab, you will implement the Game of Life and experiment with it.
This lab will be completed in pairs. Be sure to review the pair programming guidelines. You also must work with a different partner than you have before!
Objectives
- To practice working with 2-dimensional arrays: declaring them, instantiating them, and accessing them
- To review using for loops (particularly when working with arrays) and conditionals.
Necessary Files
You will need to download and extract the BlueJ project from the LabG.zip file. This project will supply you with the following classes:
-
Life
This class represents the grid in which the cells live and die. It updates the state of the board and draws it. You will need to make significant changes to this class. -
LifeFrame
This class creates a graphical frame to hold the Life board (just like with the Bouncing Balls lab). It also controls the animation of the balls by telling the board to repaint itself over and over again, and has some buttons you can use to control the game. You do not need to modify this class. -
LifeTester
A tester for the program. You can use this to test your code, or you can simply create a new instance of LifeFrame by right-clicking on the class in BlueJ.
Details
In this lab, you will not need to write any new classes! However, you will need to modify the Life
class in order to make things work.
-
The
Life
class does not have an instance variable to keep track of the board. Add an appropriate two-dimensional array instance variable called "board
" to track the state of the cells. What type would be appropriate? What values will represent either "living" or "dead"? (Hint: a cell is either "living" or "not living"...) Make the arrayBOARD_WIDTH
byBOARD_HEIGHT
; use the existing constants when declaring the size of the array.- At this point, you should fill in the
isAlive()
helper method so that it returns whether a cell is alive or not, based on your board.
- At this point, you should fill in the
- Fill in the constructor so it initializes all the cells as dead. You will need to go through every cell and set them to be dead.
- Write a method called
fillRandom
that fills yourboard
with with random values. You will need to go through every cell in the array, and pick randomly whether it starts alive or dead. (This is like flipping a coin!). Note that theRandom
class has anextBoolean()
method that you might find handy. - Now modify the constructor so that it calls the
fillRandom()
helper method. This should make it so when you run your tester, you can see your random cells. -
Now we need to do something with these cells. Fill in the method
nextGeneration()
that updates the state of the board by:- Declaring a new two-dimensional array of the same dimensions as
board
- Iterating over all cells in
board
, and for each cell, determining whether the cell should be living or dead in the next state. You should use thecountNeighbors
helper method (described below) to count the number of living neighbors for the purpose of updating the cell in the new array. - When that is done, assign the new array to your
board
instance variable. This replaces your instance variable with the new, updated board.
- Declaring a new two-dimensional array of the same dimensions as
- Fill in the
countNeighbors
helper method to count the number of living cells neighboring a given cell. This method should return an integer representing the number of living neighbors. There are eight possible neighbors for a cell in the "middle" of the grid, and fewer neighbors for cells near the edge -- this method will need to account for that. - With that working, you can run
LifeTester
, hit "Go" and see your board evolve! Try running it multiple times. Does everything die out? Or does it keep going for a long time? Does it eventually "settle" into a steady state? Or alternate between two closely related states? -
After a while watching that, you will notice several shapes and patterns that seem to appear often. Take a look at
the section of the Wikipedia page
on patterns in Life. Do you see the list of Oscillators? Write a new method
makeBlinker
that modifies the board to include at least one blinker.- Note that you will need to make sure that all the cells around your blinker are dead!
- Call this method from your constructor (either with or without the fillRandom() call). You should be able to se it blink!
- Also write a new method
makeStillLife
that modifies the board to include at least one Still Life (as described on the Wikipedia page). -
Now try to create a glider or spaceship and watch it cross the screen. Make a
makeGlider
method that makes live cells in the shape of the glider, and call this method from your constructor.- Try flipping the glider horizontally or vertically to make it move in a different directions.
- Note that by giving your makeGlider() a set of parameters on where to "start",
- Now, if you are anything like me, you will goof around for a while with various patterns, just watching what happens. Make sure you don't run out of time!
-
For your final submission: submit your Life class. The constructor should call methods that add in (at least) the following:
- A blinker pattern
- A still life pattern
- Two gliders that eventually collide!
Feel free to add anything else you find interesting — an R-pentomino, a glider gun, or any other cool pattern you find on the Wikipedia page. Or make up your own. Make a picture. Draw your name. Have fun.
- As always, be sure to fill out the lab partner evaluation survey on Moodle after you turn in your work!
Submitting
- Once you are sure that your program works, make sure that both your and your partner's names are in a class comment at the top of the file. Then submit your program to the submissions folder.
- Upload the your modified
Life.java
class to the LabG folder on the submission folder on hedwig. Make sure you upload your work to the correct folder! The lab is due at midnight on the day of the lab. - Again, please fill out the lab partner evaluation on Moodle. Help me! I'm trapped inside the math & CS webserver. I can't get out! Is anyone reading this? Anyone? Help!
Grading
This assignment will be graded on approximately the following criteria:
- You declare and initialize an appropriate board array. [10%]
- Your updateBoard method works as specified. [30%]
- Your countNeighbors method works as specified. [20%]
- Your constructor starts the Life object with blinkers, still lifes, and gliders as described above. [25%]
- You have used good programming style and documentation [10%]
- You completed your lab partner evaluation [5%]