// // Cell.java // public class Cell { // OVERVIEW: A Cell is an object than represents a cellular automaton. A cell // has a current state. // // Abstraction Function // // Rep Invariant // // This cell must exist in its grid at its location: // grid == NULL or this == grid.getCellAt (mrow, mcol) // // /*@spec_public@*/ private Grid grid; private int mrow; private int mcol; /*@non_null@*/ private CellState state; //@ghost public boolean isInitialized; public Cell() // EFFECTS: Initializes this to a dead cell. { state = CellState.createDead (); } final public void init (int row, int col, /*@non_null@*/ Grid grid) // REQUIRES: init has not previously been called for this. The cell is at (row, col) on grid. // MODIFIES: this // EFFECTS: Initializes the cell at row, col on grid. //@ensures isInitialized == true; { this.mrow = row; this.mcol = col; this.grid = grid; //@assume isInitialized == true; } public boolean setState (/*@non_null@*/ CellState s) // MODIFIES: this // EFFECTS: Sets the cell's current state to s. Returns true iff the new state is different from the current state. { if (state.equals (s)) { return false; } else { state = s; return true; } } public /*@non_null@*/ CellState getState () // EFFECTS: Returns the cell's current state. { return state; } boolean isAlive() // EFFECTS: Returns true if the cell is alive, false otherwise. { return state.isAlive(); } public int getRow () // REQUIRES: init has previously been called for this. // EFFECTS: Returns the row number that this cell is located in. { return mrow; } public int getColumn () // REQUIRES: init has previously been called for this. // EFFECTS: Returns the column number that this cell is located in. { return mcol; } public /*@non_null@*/ Grid getGrid() // REQUIRES: init has previously been called for this. // EFFECTS: Returns the grid containing this cell. //@requires this.grid != null; { return grid; } public int countAliveNeighbors () // REQUIRES: init has previously been called for this. // EFFECTS: Returns a count of the cell's live neighbors. //@requires this.grid != null; { int neighbors = 0; for (int row = Math.max (0, mrow - 1); row <= Math.min (grid.numRows () - 1, mrow + 1); row++) { for (int col = Math.max (0, mcol - 1); col <= Math.min (grid.numColumns () - 1, mcol + 1); col++) { if (row != mrow || col != mcol) { // Don't count yourself if (grid.getCellAt (row, col).isAlive ()) { neighbors++; } } } } return neighbors; } public /*@non_null@*/ CellState getNextState () // REQUIRES: init has previously been called for this. // EFFECTS: Returns next state value for this. // For the underlying Cell class, the next state is always the // current state. // This method will be overloaded by cell implementations // for various cell automata rules. { return state; } }