1- import java .awt .Toolkit ;
2- import javax .swing .JFrame ;
1+ import java .io .File ;
2+ import java .io .FileNotFoundException ;
3+ import java .util .ArrayList ;
4+ import java .util .List ;
5+ import java .util .Scanner ;
36
47/**
58 * Conway's Game of Life.
69 */
7- public class Conway {
10+ public class Conway extends Automaton {
811
912 /**
10- * Counts the number of live neighbors (without going out of bounds).
13+ * Creates a grid with a Blinker and a Glider.
14+ */
15+ public Conway () {
16+ grid = new GridCanvas (30 , 25 , SIZE );
17+ grid .flip (1 , 2 );
18+ grid .flip (2 , 2 );
19+ grid .flip (3 , 2 );
20+ grid .flip (6 , 1 );
21+ grid .flip (7 , 2 );
22+ grid .flip (7 , 3 );
23+ grid .flip (8 , 1 );
24+ grid .flip (8 , 2 );
25+ }
26+
27+ /**
28+ * Creates a grid based on a plain text file.
29+ * http://www.conwaylife.com/wiki/Plaintext
1130 *
12- * @param grid the grid
13- * @param r row index
14- * @param c column index
15- * @return number of live neighbors
31+ * @param path the path to the file
1632 */
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 ();
33+ public Conway (String path ) {
34+
35+ // open the file at the given path
36+ Scanner scan = null ;
37+ try {
38+ File file = new File (path );
39+ scan = new Scanner (file );
40+ } catch (FileNotFoundException e ) {
41+ e .printStackTrace ();
42+ System .exit (1 );
43+ }
2144
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 ++;
45+ // read file contents into memory
46+ List <String > data = new ArrayList <String >();
47+ while (scan .hasNextLine ()) {
48+ String line = scan .nextLine ();
49+ // ignore blank lines and comments
50+ if (!line .isEmpty () && !line .startsWith ("!" )) {
51+ data .add (line );
3252 }
3353 }
3454
35- // current row
36- if (c > 0 && grid .isOn (r , c - 1 )) {
37- count ++;
55+ // validate the file contents
56+ int rows = data .size ();
57+ if (rows == 0 ) {
58+ throw new IllegalArgumentException ("empty file" );
3859 }
39- if (c < cols - 1 && grid .isOn (r , c + 1 )) {
40- count ++;
60+ int cols = data .get (0 ).length ();
61+ for (String line : data ) {
62+ if (line .length () != cols ) {
63+ throw new IllegalArgumentException ("invalid file" );
64+ }
4165 }
4266
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 ++;
67+ // create the resulting grid
68+ grid = new GridCanvas (rows , cols , SIZE );
69+ for (int r = 0 ; r < rows ; r ++) {
70+ String line = data .get (r );
71+ for (int c = 0 ; c < cols ; c ++) {
72+ char x = line .charAt (c );
73+ if (x == 'O' ) {
74+ grid .flip (r , c );
75+ }
5376 }
5477 }
78+ }
5579
80+ /**
81+ * Counts the number of live neighbors around a cell.
82+ *
83+ * @param r row index
84+ * @param c column index
85+ * @return number of live neighbors
86+ */
87+ private int countAlive (int r , int c ) {
88+ int count = 0 ;
89+ count += grid .test (r - 1 , c - 1 );
90+ count += grid .test (r - 1 , c );
91+ count += grid .test (r - 1 , c + 1 );
92+ count += grid .test (r , c - 1 );
93+ count += grid .test (r , c + 1 );
94+ count += grid .test (r + 1 , c - 1 );
95+ count += grid .test (r + 1 , c );
96+ count += grid .test (r + 1 , c + 1 );
5697 return count ;
5798 }
5899
59100 /**
60- * Apply the rules of Conway's Game of Life.
101+ * Apply the update rules of Conway's Game of Life.
61102 *
62103 * @param cell the cell to update
63104 * @param count number of live neighbors
64105 */
65- public static void updateCell (Cell cell , int count ) {
106+ private static void updateCell (Cell cell , int count ) {
66107 if (cell .isOn ()) {
67108 if (count < 2 ) {
68109 // Any live cell with fewer than two live neighbors dies,
@@ -88,18 +129,16 @@ public static void updateCell(Cell cell, int count) {
88129
89130 /**
90131 * Simulates one round of Conway's Game of Life.
91- *
92- * @param grid the grid
93132 */
94- public static void update (Grid grid ) {
95- int cols = grid .getCols ();
133+ public void update () {
96134 int rows = grid .getRows ();
135+ int cols = grid .getCols ();
97136
98137 // count neighbors before changing anything
99138 int [][] counts = new int [rows ][cols ];
100139 for (int r = 0 ; r < rows ; r ++) {
101140 for (int c = 0 ; c < cols ; c ++) {
102- counts [r ][c ] = countAlive (grid , r , c );
141+ counts [r ][c ] = countAlive (r , c );
103142 }
104143 }
105144
@@ -109,45 +148,9 @@ public static void update(Grid grid) {
109148 updateCell (grid .getCell (r , c ), counts [r ][c ]);
110149 }
111150 }
112- }
113151
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- }
152+ // update the display
153+ grid .repaint ();
151154 }
152155
153156}
0 commit comments