Skip to content

Commit 4d835c8

Browse files
committed
separate Conway from Grid
1 parent 5f22f20 commit 4d835c8

5 files changed

Lines changed: 232 additions & 97 deletions

File tree

ch15/Cell.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,14 @@ public void setColor(Color color) {
5555
}
5656

5757
/**
58-
* @return true if the cell is on
58+
* @return true if the cell is off
5959
*/
6060
public boolean isOff() {
6161
return this.color == OFF;
6262
}
6363

6464
/**
65-
* @return true if the cell is off
65+
* @return true if the cell is on
6666
*/
6767
public boolean isOn() {
6868
return this.color == ON;

ch15/Conway.java

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
import java.awt.Toolkit;
2+
import javax.swing.JFrame;
3+
4+
/**
5+
* Conway's Game of Life.
6+
*/
7+
public class Conway {
8+
9+
/**
10+
* Counts the number of live neighbors (without going out of bounds).
11+
*
12+
* @param grid the grid
13+
* @param r row index
14+
* @param c column index
15+
* @return number of live neighbors
16+
*/
17+
public static int countAlive(Grid grid, int r, int c) {
18+
int count = 0;
19+
int cols = grid.getCols();
20+
int rows = grid.getRows();
21+
22+
// previous row
23+
if (r > 0) {
24+
if (c > 0 && grid.isOn(r - 1, c - 1)) {
25+
count++;
26+
}
27+
if (grid.isOn(r - 1, c)) {
28+
count++;
29+
}
30+
if (c < cols - 1 && grid.isOn(r - 1, c + 1)) {
31+
count++;
32+
}
33+
}
34+
35+
// current row
36+
if (c > 0 && grid.isOn(r, c - 1)) {
37+
count++;
38+
}
39+
if (c < cols - 1 && grid.isOn(r, c + 1)) {
40+
count++;
41+
}
42+
43+
// next row
44+
if (r < rows - 1) {
45+
if (c > 0 && grid.isOn(r + 1, c - 1)) {
46+
count++;
47+
}
48+
if (grid.isOn(r + 1, c)) {
49+
count++;
50+
}
51+
if (c < cols - 1 && grid.isOn(r + 1, c + 1)) {
52+
count++;
53+
}
54+
}
55+
56+
return count;
57+
}
58+
59+
/**
60+
* Apply the rules of Conway's Game of Life.
61+
*
62+
* @param cell the cell to update
63+
* @param count number of live neighbors
64+
*/
65+
public static void updateCell(Cell cell, int count) {
66+
if (cell.isOn()) {
67+
if (count < 2) {
68+
// Any live cell with fewer than two live neighbors dies,
69+
// as if by underpopulation.
70+
cell.turnOff();
71+
} else if (count > 3) {
72+
// Any live cell with more than three live neighbors dies,
73+
// as if by overpopulation.
74+
cell.turnOff();
75+
} else {
76+
// Any live cell with two or three live neighbors lives on
77+
// to the next generation.
78+
cell.turnOn();
79+
}
80+
} else {
81+
if (count == 3) {
82+
// Any dead cell with exactly three live neighbors
83+
// becomes a live cell, as if by reproduction.
84+
cell.turnOn();
85+
}
86+
}
87+
}
88+
89+
/**
90+
* Simulates one round of Conway's Game of Life.
91+
*
92+
* @param grid the grid
93+
*/
94+
public static void update(Grid grid) {
95+
int cols = grid.getCols();
96+
int rows = grid.getRows();
97+
98+
// count neighbors before changing anything
99+
int[][] counts = new int[rows][cols];
100+
for (int r = 0; r < rows; r++) {
101+
for (int c = 0; c < cols; c++) {
102+
counts[r][c] = countAlive(grid, r, c);
103+
}
104+
}
105+
106+
// update each cell based on neighbor counts
107+
for (int r = 0; r < rows; r++) {
108+
for (int c = 0; c < cols; c++) {
109+
updateCell(grid.getCell(r, c), counts[r][c]);
110+
}
111+
}
112+
}
113+
114+
/**
115+
* Sets up the grid, creates the drawing, and plays the game.
116+
*
117+
* @param args command-line arguments
118+
*/
119+
public static void main(String[] args) {
120+
121+
Grid grid = new Grid(30, 25, 20);
122+
grid.flip(1, 2);
123+
grid.flip(2, 2);
124+
grid.flip(3, 2);
125+
Drawing drawing = new Drawing(grid);
126+
127+
// set up the window frame
128+
JFrame frame = new JFrame("Conway's Game of Life");
129+
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
130+
frame.setResizable(false);
131+
frame.add(drawing);
132+
frame.pack();
133+
frame.setVisible(true);
134+
135+
// main simulation loop
136+
Toolkit toolkit = frame.getToolkit();
137+
while (true) {
138+
139+
// update the drawing
140+
update(grid);
141+
drawing.repaint();
142+
143+
// delay the simulation
144+
try {
145+
Thread.sleep(500);
146+
toolkit.sync();
147+
} catch (InterruptedException e) {
148+
// do nothing
149+
}
150+
}
151+
}
152+
153+
}

ch15/Grid.java

Lines changed: 28 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import java.awt.Graphics;
22

33
/**
4-
* 2D array of cells that represent Conway's Game of Life.
4+
* 2D array of cells representing a game board.
55
*/
66
public class Grid {
77

@@ -13,7 +13,7 @@ public class Grid {
1313
private Cell[][] array;
1414

1515
/**
16-
* Constructs a drawing of given size.
16+
* Constructs a grid of given size.
1717
*
1818
* @param rows number of rows
1919
* @param cols number of columns
@@ -49,7 +49,7 @@ public void draw(Graphics g) {
4949
}
5050

5151
/**
52-
* Toggles the cell color.
52+
* Toggles the cell on/off.
5353
*
5454
* @param r row index
5555
* @param c column index
@@ -64,115 +64,49 @@ public void flip(int r, int c) {
6464
}
6565

6666
/**
67-
* @return total height of the grid
67+
* @param r row index
68+
* @param c column index
69+
* @return true if the cell is on
6870
*/
69-
public int height() {
70-
return rows * size;
71+
public boolean isOn(int r, int c) {
72+
return array[r][c].isOn();
7173
}
7274

7375
/**
74-
* @return total width of the grid
76+
* @param r row index
77+
* @param c column index
78+
* @return the cell
7579
*/
76-
public int width() {
77-
return cols * size;
80+
public Cell getCell(int r, int c) {
81+
return array[r][c];
7882
}
7983

8084
/**
81-
* Counts the number of live neighbors (without going out of bounds).
82-
*
83-
* @param r row index
84-
* @param c column index
85-
* @return number of live neighbors
85+
* @return number of rows
8686
*/
87-
public int countAlive(int r, int c) {
88-
int count = 0;
89-
90-
// previous row
91-
if (r > 0) {
92-
if (c > 0 && array[r - 1][c - 1].isOn()) {
93-
count++;
94-
}
95-
if (array[r - 1][c].isOn()) {
96-
count++;
97-
}
98-
if (c < cols - 1 && array[r - 1][c + 1].isOn()) {
99-
count++;
100-
}
101-
}
102-
103-
// current row
104-
if (c > 0 && array[r][c - 1].isOn()) {
105-
count++;
106-
}
107-
if (c < cols - 1 && array[r][c + 1].isOn()) {
108-
count++;
109-
}
110-
111-
// next row
112-
if (r < rows - 1) {
113-
if (c > 0 && array[r + 1][c - 1].isOn()) {
114-
count++;
115-
}
116-
if (array[r + 1][c].isOn()) {
117-
count++;
118-
}
119-
if (c < cols - 1 && array[r + 1][c + 1].isOn()) {
120-
count++;
121-
}
122-
}
123-
124-
return count;
87+
public int getRows() {
88+
return rows;
12589
}
12690

12791
/**
128-
* Apply the rules of Conway's Game of Life.
129-
*
130-
* @param cell the cell to update
131-
* @param count number of live neighbors
92+
* @return number of columns
13293
*/
133-
public void updateCell(Cell cell, int count) {
134-
if (cell.isOn()) {
135-
if (count < 2) {
136-
// Any live cell with fewer than two live neighbors dies,
137-
// as if by underpopulation.
138-
cell.turnOff();
139-
} else if (count > 3) {
140-
// Any live cell with more than three live neighbors dies,
141-
// as if by overpopulation.
142-
cell.turnOff();
143-
} else {
144-
// Any live cell with two or three live neighbors lives on
145-
// to the next generation.
146-
cell.turnOn();
147-
}
148-
} else {
149-
if (count == 3) {
150-
// Any dead cell with exactly three live neighbors
151-
// becomes a live cell, as if by reproduction.
152-
cell.turnOn();
153-
}
154-
}
94+
public int getCols() {
95+
return cols;
15596
}
15697

15798
/**
158-
* Simulates one round of Conway's Game of Life.
99+
* @return total height of the grid
159100
*/
160-
public void update() {
161-
162-
// count neighbors before changing anything
163-
int[][] counts = new int[rows][cols];
164-
for (int r = 0; r < rows; r++) {
165-
for (int c = 0; c < cols; c++) {
166-
counts[r][c] = countAlive(r, c);
167-
}
168-
}
101+
public int height() {
102+
return rows * size;
103+
}
169104

170-
// update each cell based on neighbor counts
171-
for (int r = 0; r < rows; r++) {
172-
for (int c = 0; c < cols; c++) {
173-
updateCell(array[r][c], counts[r][c]);
174-
}
175-
}
105+
/**
106+
* @return total width of the grid
107+
*/
108+
public int width() {
109+
return cols * size;
176110
}
177111

178112
}

ch15/Langton.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import java.awt.Toolkit;
2+
import javax.swing.JFrame;
3+
4+
/**
5+
* Langton's Ant.
6+
*/
7+
public class Langton {
8+
9+
private int xpos;
10+
private int ypos;
11+
private int head; // 0=North, 1=East, 2=South, 3=West
12+
13+
/**
14+
* Sets up the grid, creates the drawing, and plays the game.
15+
*
16+
* @param args command-line arguments
17+
*/
18+
public static void main(String[] args) {
19+
20+
Grid grid = new Grid(30, 25, 20);
21+
Drawing drawing = new Drawing(grid);
22+
23+
// set up the window frame
24+
JFrame frame = new JFrame("Langton's Ant");
25+
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
26+
frame.setResizable(false);
27+
frame.add(drawing);
28+
frame.pack();
29+
frame.setVisible(true);
30+
31+
// main simulation loop
32+
Toolkit toolkit = frame.getToolkit();
33+
while (true) {
34+
35+
// update the drawing
36+
drawing.repaint();
37+
38+
// delay the simulation
39+
try {
40+
Thread.sleep(500);
41+
toolkit.sync();
42+
} catch (InterruptedException e) {
43+
// do nothing
44+
}
45+
}
46+
}
47+
48+
}

ch15/Main.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public static void main(String[] args) {
115115
while (true) {
116116

117117
// update the drawing
118-
grid.update();
118+
// grid.update();
119119
drawing.repaint();
120120

121121
// delay the simulation

0 commit comments

Comments
 (0)