import element.*; import java.awt.Color; public class Life { static DrawingWindow d; final static int SIZE = 10; // edge size of petri dish final static boolean OCCUPIED = true; // named constant for life final static boolean VACANT = false; // named constant for vacancy public static void initialize(boolean dish[][]) // pre: the dish has been allocated // post: the population is cleared from the dish { // we use a square dish, so n is the width and height int n = dish.length; int r,c; for (r = 0; r < n; r++) // all rows { for (c = 0; c < n; c++) // all entries within a row { dish[r][c] = VACANT; // are vacant } } paint(dish); // update the screen } public static void edit(boolean dish[][]) // pre: the dish is allocated // post: individual cells in the dish have been toggled; // mouse was dragged to stop editing { int n = dish.length; paint(dish); while (true) { // read the mouse press and release points Pt press = d.awaitMousePress(); Pt release = d.awaitMouseRelease(); // convert to row and column numbers int pr = press.y()/SIZE; int pc = press.x()/SIZE; int rr = release.y()/SIZE; int rc = release.x()/SIZE; if (pr != rr || pc != rc) { break; // dragging? stop this loop! } // not a click, so change OCCUPIED<->VACANT dish[pr][pc] = !dish[pr][pc]; // update screen paint(dish); } } public static void paint(boolean dish[][]) // pre: dish is allocated with valid contents // post: dish is represented by dots on the screen { int n = dish.length; int r,c; d.hold(); // we'll delay the update of the display d.clear(d.bounds()); // erase screen for (r = 0; r < n; r++) // every row { for (c = 0; c < n; c++) // and every cell within row { if (dish[r][c] == OCCUPIED) // is painted if occupied { d.fill(new Oval(c*SIZE,r*SIZE,SIZE,SIZE)); } } } d.release(); // update the display } public static void simulate(boolean dish[][]) // pre: dish is allocated with valid contents // post: one generation of the dish is simulated and painted { int n = dish.length; boolean work[][] = new boolean[n][n]; int r,c; int pop; for (r = 0; r < n; r++) // every row { for (c = 0; c < n; c++) // and every cell within row { pop = neighbors(dish,r,c); // count neighbors if (pop == 3 && !dish[r][c]) { work[r][c] = OCCUPIED; } else if (dish[r][c] && (pop <= 1 || pop >= 4)) { work[r][c] = VACANT; } else { work[r][c] = dish[r][c]; } } } // copy over the work array to the dish for (r = 0; r < n; r++) { for (c = 0; c < n; c++) { dish[r][c] = work[r][c]; } } paint(dish); // update the screen } public static int neighbors(boolean dish[][], int row, int col) // pre: 0 <= row, col < dish.length // post: returns the number of OCCUPIED cells surrounding (row,col) // on torus { int n = dish.length; int r, c; int pop = 0; for (r = -1; r <= 1; r++) // for rows about row { for (c = -1; c <= 1; c++) // and columns about col { if (r != 0 || c != 0) // if not (row,col) { // count any occupied cells if (dish[(row+n+r)%n][(col+n+c)%n]==OCCUPIED) pop++; } } } return pop; } /* public static int neighbors(boolean dish[][], int row, int col) // pre: 0 <= row, col < dish.length // post: returns the number of OCCUPIED cells surrounding (row,col) // on torus { int n = dish.length; int pop = 0; if (row > 0 && col > 0 && dish[row-1][col-1]) pop++; if (row > 0 && dish[row-1][col ]) pop++; if (row > 0 && col < (n-1) && dish[row-1][col+1]) pop++; if ( col > 0 && dish[row ][col-1]) pop++; if ( col < (n-1) && dish[row ][col+1]) pop++; if (row < (n-1) && col > 0 && dish[row+1][col-1]) pop++; if (row < (n-1) && dish[row+1][col ]) pop++; if (row < (n-1) && col < (n-1) && dish[row+1][col+1]) pop++; return pop; } */ public static void main(String args[]) { d = new DrawingWindow(400,400); int n = d.bounds().width()/SIZE; boolean dish[][] = new boolean[n][n]; initialize(dish); // clear dish while (true) { edit(dish); // make changes while (!d.mousePressed()) // life goes on... { simulate(dish); } d.awaitMouseRelease(); // until click } } }