diff --git a/src/edu/stuy/goldfish/Goldfish.java b/src/edu/stuy/goldfish/Goldfish.java index 20484b9..d627b8c 100644 --- a/src/edu/stuy/goldfish/Goldfish.java +++ b/src/edu/stuy/goldfish/Goldfish.java @@ -15,6 +15,7 @@ public class Goldfish { _render = new Render(width, height, _grid, RULES); } + /* Main method for running the simulator. */ public void run() { setup(_render.rule); while (true) { @@ -33,6 +34,7 @@ public class Goldfish { } } + /* Advance the grid one step using the given algorithm. */ private void doLogic(String rule) { if (rule.equals("Conway")) _grid = Conway.run(_grid); @@ -44,6 +46,7 @@ public class Goldfish { _grid = BriansBrain.run(_grid); } + /* Return the max number of states a patch can be in for the given rule. */ public static int getMaxStates(String rule) { if (rule.equals("Conway")) return Conway.states; @@ -56,6 +59,7 @@ public class Goldfish { return 2; } + /* Generate a default shape for the grid based on the given rule. */ private void setup(String rule) { if (rule.equals("Conway")) Conway.setup(_grid); diff --git a/src/edu/stuy/goldfish/Grid.java b/src/edu/stuy/goldfish/Grid.java index 4c44e94..7ae3be1 100644 --- a/src/edu/stuy/goldfish/Grid.java +++ b/src/edu/stuy/goldfish/Grid.java @@ -23,6 +23,7 @@ public class Grid { this(x, y, true); } + /* Take an x coordinate, and return x′ such that 0 <= x′ < width. */ private int normalizeX(int x) { while (x >= getWidth()) x -= getWidth(); @@ -31,6 +32,7 @@ public class Grid { return x; } + /* Take a y coordinate, and return y′ such that 0 <= y′ < height. */ private int normalizeY(int y) { while (y >= getHeight()) y -= getHeight(); @@ -39,20 +41,25 @@ public class Grid { return y; } + /* Return the width of the grid. */ public int getWidth() { return _grid[0].length; } + /* Return the height of the grid. */ public int getHeight() { return _grid.length; } + /* Return the patch at (x, y). x and y need not be within range of the + grid. */ public Patch getPatch(int x, int y) { x = normalizeX(x); y = normalizeY(y); return _grid[y][x]; } + /* Set the patch at (x, y) to p. */ public void setPatch(int x, int y, Patch p) { x = normalizeX(x); y = normalizeY(y); diff --git a/src/edu/stuy/goldfish/Patch.java b/src/edu/stuy/goldfish/Patch.java index 7285915..e6959bd 100644 --- a/src/edu/stuy/goldfish/Patch.java +++ b/src/edu/stuy/goldfish/Patch.java @@ -15,22 +15,27 @@ public class Patch { this(new Grid(), 0, 0, 0); } + /* Return the grid corresponding to this patch. */ public Grid getGrid() { return _grid; } + /* Return this patch's x coordinate in the grid. */ public int getX() { return _xcor; } + /* Return this patch's y coordinate in the grid. */ public int getY() { return _ycor; } + /* Return this patch's state. */ public int getState() { return _state; } + /* Set this patch's state. */ public void setState(int state) { _state = state; } @@ -39,6 +44,9 @@ public class Patch { return "" + ((_state == 0) ? "." : _state); } + /* Return the number of immediate neighbors, excluding diagonals, that have + the given state. Will not continue checking patches if the number of + matching patches exceeds the given max value. */ public int get4Neighbors(int state, int max) { int neighbors = 0; for (int i = 0; i < 4; i++) { @@ -61,6 +69,9 @@ public class Patch { return neighbors; } + /* Return the number of immediate neighbors that have the given state. Will + not continue checking patches if the number of matching patches exceeds + the given max value. */ public int get8Neighbors(int state, int max) { int neighbors = 0; for (int i = 0; i < 8; i++) { @@ -91,14 +102,18 @@ public class Patch { return neighbors; } + /* Return the number of immediate neighbors, excluding diagonals, that have + the given state. */ public int get4Neighbors(int state) { return get4Neighbors(state, 4); } + /* Return the number of immediate neighbors that have the given state. */ public int get8Neighbors(int state) { return get8Neighbors(state, 8); } + /* Return a new patch identical to this one, but in a different grid. */ public Patch clone(Grid grid) { return new Patch(grid, _xcor, _ycor, _state); } diff --git a/src/edu/stuy/goldfish/Render.java b/src/edu/stuy/goldfish/Render.java index 36a5e92..296174a 100644 --- a/src/edu/stuy/goldfish/Render.java +++ b/src/edu/stuy/goldfish/Render.java @@ -75,6 +75,7 @@ public class Render extends Canvas implements Runnable, MouseListener, this(256, 256); } + /* Set the grid's scale factor so smaller grids appear larger. */ private void setScale() { if (height <= 128 || width <= 128) { Render.scale = 4; @@ -85,6 +86,7 @@ public class Render extends Canvas implements Runnable, MouseListener, } } + /* Set up the window frame with various buttons. */ private void setFrame() { JMenuBar menuBar = new JMenuBar(); JMenu menuAlgo = new JMenu("Algorithms"); @@ -162,6 +164,7 @@ public class Render extends Canvas implements Runnable, MouseListener, _frame.setVisible(true); } + /* Actually draw the grid to the screen. */ private void update() { int state; int states = Goldfish.getMaxStates(rule); @@ -173,6 +176,7 @@ public class Render extends Canvas implements Runnable, MouseListener, } } + /* Acquire a lock so two threads don't modify the grid at the same time. */ public void acquireLock(int thread) { int other = (thread == 0 ? 1 : 0); _flags[thread].set(true); @@ -185,12 +189,14 @@ public class Render extends Canvas implements Runnable, MouseListener, } } + /* Release the lock when a thread is finished modifying the grid. */ public void releaseLock(int thread) { int other = (thread == 0 ? 1 : 0); _turn.set(other); _flags[thread].set(false); } + /* Main method to render the grid at its current state. */ public void run() { BufferStrategy bs; Graphics g; @@ -209,6 +215,7 @@ public class Render extends Canvas implements Runnable, MouseListener, bs.show(); } + /* Maintain a maximum FPS. */ public void sleep() { long since = System.currentTimeMillis() - _lastTick; if (since < 1000 / fps_now) { @@ -221,15 +228,18 @@ public class Render extends Canvas implements Runnable, MouseListener, _lastTick = System.currentTimeMillis(); } + /* Set the grid to be rendered. */ public void setGrid(Grid g) { _grid = g; } + /* Draw a certain color at (x, y) to the screen. */ public void draw(int x, int y, int color) { if (_pixels[x + y * width] != color) _pixels[x + y * width] = color; } + /* Set the state of all patches in the grid to zero. */ public void clear() { acquireLock(1); for (int i = 0; i < _grid.getWidth(); i++) { @@ -240,6 +250,7 @@ public class Render extends Canvas implements Runnable, MouseListener, releaseLock(1); } + /* Set each patch in the grid to a random state. */ public void randomize() { acquireLock(1); for (int i = 0; i < _grid.getWidth(); i++) { @@ -250,6 +261,7 @@ public class Render extends Canvas implements Runnable, MouseListener, releaseLock(1); } + /* Handle a mouse event by modifying the patch the mouse is over. */ private void mouseDraw(MouseEvent e) { int states = Goldfish.getMaxStates(rule); if (e.getX() < 0 || e.getY() < 0 || e.getX() / scale >= width || e.getY() / scale >= height) @@ -269,37 +281,45 @@ public class Render extends Canvas implements Runnable, MouseListener, e.consume(); } + /* Called when the mouse is dragged over a pixel. */ @Override public void mouseDragged(MouseEvent e) { mouseDraw(e); } + /* Called whenever the mouse is clicked. */ @Override public void mouseClicked(MouseEvent e) { } + /* Called whenever the mouse enters the window. */ @Override public void mouseEntered(MouseEvent e) { } + /* Called whenever the mouse exits the window. */ @Override public void mouseExited(MouseEvent e) { } + /* Called whenever the mouse is pressed. */ @Override public void mousePressed(MouseEvent e) { mouseDraw(e); } + /* Called whenever the mouse is released from being pressed. */ @Override public void mouseReleased(MouseEvent e) { _drawState = -1; } + /* Called whenever the mouse is moved, pressed or not. */ @Override public void mouseMoved(MouseEvent e) { } + /* Hook to handle button presses and menu choices. */ @Override public void actionPerformed(ActionEvent event) { if ("pause".equals(event.getActionCommand())) {