Week9
[!TIP] 🔔 温馨提示:本周练习代码在
../src/Week9中 🔗 点我跳转
Case Study: The Game of Life
The “Game” of Life
The “Game” of Life was invented by Mathematician John Horton Conway in 1970.
Unlike other games, there are no players and no winning or losing.
The game is played on an infinite square grid containing cells. Each cell is either “alive” or “dead”.

You “play” the game by setting out the initial distribution of live cells and then watching the cells evolve through “generations” as follows:
On each generation you look at the eight neighbors of each cell (adjacent horizontally, vertically, or diagonally). The cells evolve according to the following rules:
A live cell with less than two live neighbors dies (presumably of loneliness).
A live cell with more than three live neighbors also dies (presumably of overcrowding).
A live cell with two or three live neighbors survives.
A dead cell with exactly three live neighbors is brought back to life.

The appeal of the game is that its very simple rules allow very interesting and sometimes very complex patterns to develop.
Let’s look at a simple one, the “glider” or “spaceship”.
The Glider

The Gosper “Glider Gun”

More Patterns (Courtesy of Wikipedia)

Developing Software for the Game
Unlike your practical exercises, “real” software is developed by teams of programmers. Let’s imagine that we have a team on hand to develop a Java version of life.
Jenny: Lead Developer
Bill: Senior Analyst/Programmer
Alex: Junior Programmer
[!TIP]Important career advice: Real coders are never as cool or attractive as this.
First Team Meeting
At their initial meeting the team make some important decisions.
The first is that they are going to cheat.
Rather than play the game on an infinite grid, they decide to play it on a grid of finite size (70*70 cells say). Any cells outside this area are deemed to be dead.

Class Responsibility Collaboration
The next thing the team do is to draw up some Class Responsibility Collaboration (CRC) Cards.
These are a “first cut” design showing what classes will participate in the application, their responsibilities, and how they collaborate with other classes.
Responsibilities
Runs the application.
Displays the state of the game. Tells the game when to create a new generation.
Knows the rules of the game and creates new generations when requested to do so.
Stores the state of a game (i.e. which cells are live).
Collaborations
Creates instances of the Game and Display classes.
Collaborates with an instance of the Game class.
Uses instances of the Board class to store the state of the game.
Development Strategy

Jenny’s Design for the Display Class
Display
+ Display(game : Game, cellSize, generationTime : int) + start() : void
The constructor takes three arguments:
gameis a reference to the Game object to be displayed.cellSizeis the size (in pixels) of the cells in the display.generationTimeis the time (in milliseconds) that elapses between generations. Thestart()method is called in order to start the evolution of the game.
Jenny’s Requirements for The Game Class.
Jenny needs the Game class to implement the following methods.
Game
+ Game(width, height : int) + getLiveCells() : Point [] + newGeneration() : void + makeCellLive(x, y : int) : void

javafx.geometry.Point2D
Point object represents a point in two-dimensional space.
Point
- x, y : double
+ Point(x, y : double) + getX() : double + getY() : double …
Attributes representing the x and y coordinates of the point
Accessor
gettermethods for the private x and y attributesThere are other methods, but we don’t need to know about them!
Bill’s Requirements for The Board Class.
Bill needs the Board class to implement the following methods.
Board
+ Board(width, height : int) + clear() : void + getCell(x, y : int) : boolean + makeCellLive(x, y : int) : void + getLiveCells() : Point[]
Sets all cells in the board to be dead
Returns true if the cell at (x,y) is alive and false if it isn’t
These methods behave in a similar manner to the methods with the same name in the Game class.
Two Coordinate Systems
It is important to realize that the coordinate system that Jenny uses when she displays the game state is different to that used by Bill and Alex when they represent the state.
Bill and Alex are representing the system using a grid in which each square represents a cell.
The Display class displays each cell in a square whose size is determined by the cellSize parameter of its constructor. The cellSize represents the size of a cell in pixels.


The Board Class
Version 1
Alex’s first version of the Board Class uses a 2D boolean array to store the cells.

Board
- cells : boolean[][] - width, height : int
+ Board(width, height : int) …
Implementing the class Board
Implementation of the CLASS Game
GameThe population of each generation is calculated by looking at the population of the previous generation.
The
Gameclass therefore contains references to twoBoardobjects. One is the current board and the other the previous board.When a new generation is created these are swapped round so that the current board becomes the previous board.
Game
- currentBoard, oldBoard : Board
+ Game(width, height : int) + newGeneration() : void …
Implementation of the Class Main
Implementation of the CLASS Display
Display
The Board Class
Version 2
After all the classes have been implemented Alex suddenly has a brainwave.

The rest of team are not happy.
![[Pasted_image_20250525164015.png]]
A Reality Check!
In this example we have made it look as if our little team adopted a “Waterfall” approach. That is to say that they completely designed the application, before writing any code. Then they wrote the code implied by their design. And it all worked first time!
In the real world, development does not often happen as neatly as that (unless the project is very simple, or the developers are very clever).
It is often better to adopt a more iterative approach that works something like this. Given requirements for a complicated program:
Design a simpler program that meets some of the requirements you have been given.
Implement that program and check that it works.
Modify the program so that it meets more of the requirements. Check that the modified program works.
Repeat step 3 until you have met all the requirements.
Last updated