I have designed Conway’s Game of Life in Java, the solution follows Object Oriented design and paradigm, please review and let me know the feedback
Class Cell
Cell
has one propertyalive
and behavior to update alive statuspublic class Cell { private boolean alive; public Cell( boolean alive) { this.alive = alive; } public void updateStatus(int aliveNeighboursCount) { if (alive && aliveNeighboursCount > 3) { alive = false; } else if (alive && aliveNeighboursCount < 2) { alive = false; } else if (aliveNeighboursCount == 3 && !alive) { alive = true; } } public boolean isAlive() { return this.alive; } }
Class Grid
getAliveNeighboursCount
method finds the alive neighbor of every cell and returns the count
nextCycle
creates new cells with their alive status based neighbours count and replaces the currentcells
of theGrid
public class Grid { private Cell[][] cells; public Grid(int size, Randomizer randomizer) { this.cells = randomizer.loadCells(size); } private boolean isOutOfBound(int maxSize, int i, int j) { return (i < 0 || i == maxSize) || (j < 0 || j == maxSize); } int getAliveNeighboursCount(int xPos, int yPos) { int aliveNeighboursCount = 0; for (int i = xPos - 1; i <= xPos + 1; i++) { for (int j = yPos - 1; j <= yPos + 1; j++) { if (isOutOfBound(cells.length, i, j) || (i == xPos && j == yPos)) { continue; } aliveNeighboursCount += cells[i][j].isAlive() ? 1 : 0; } } return aliveNeighboursCount; } public void nextCycle() { Cell[][] newCells = new Cell[this.cells.length][this.cells[0].length]; for (int i = 0; i < newCells.length; i++) { for (int j = 0; j < newCells[0].length; j++) { Cell cell = new Cell(false); cell.updateStatus(getAliveNeighboursCount(i, j)); newCells[i][j] = cell; } } this.cells = newCells; } @Override public String toString() { StringBuilder gridString = new StringBuilder(); for (int i = 0; i < cells.length; i++) { for (int j = 0; j < cells[0].length; j++) { gridString.append(cells[i][j].isAlive() ? "*\t" : "-\t"); } gridString.append("\n"); } return gridString.toString(); } }
Class Randomizer
Grid
takesRandomizer
object to randomize cells based on the biased random numberimport java.util.Random; public class Randomizer { private final int aliveCellsForEveryTenCell; public Randomizer(int aliveCellsForEveryTenCell) { this.aliveCellsForEveryTenCell = aliveCellsForEveryTenCell; } private boolean getNext() { return new Random().nextInt(10) <= aliveCellsForEveryTenCell; } public Cell[][] loadCells(int size) { Cell[][] cells = new Cell[size][size]; for (int i = 0; i < size; i++) { for (int j = 0; j < cells[0].length; j++) { cells[i][j] = new Cell( getNext()); } } return cells; } }
Class Action
This class is to execute the Code
public class Action { public static void main(String[] args) throws InterruptedException { Randomizer randomizer = new Randomizer(4); Grid grid = new Grid(25, randomizer); System.out.println(grid); for (int i = 0; i < 10; i++) { Thread.sleep(1000); grid.nextCycle(); System.out.println(grid); } } }
Answer
It’s hard to judge a design when there is no information about what you want from it. If you wanted classes and methods, well you succeeded, but that’s about it. But if you, for example, wanted extensibility and robustness, then it’s a whole different thing. You added the “interview-questions” tag. Can you tell us what your interviewer was looking for?
Grid
For me the Grid
class is supposed to encapsulate and protect the array. That is broken in your design as the array is created by Randomizer
. There is very little point in trying to verify the bounds of the array in Grid
because Grid doesn’t even know the size of the array it has. There is no guarantee that Randomizer
provides what it is asked to provide because a programmer can subclass Randomizer and return data that is not compatible to what Grid
expects. You could add error checking to ensure the array returned by Randomizer has correct dimensions, but that’s “treating the symptoms, not the disease.” A better approach would be for Grid
to initialize the array itself and ask Randomizer
to place the live/dead value to the cells created by Grid using setter methods.
Randomizer
Conway’s game of life is about creating seeds that provide interesting generations. You should define the Randomizer
as an interface, called something like Seeder
, and make Grid
accept the interface instead of some concrete implementation. Then you can implement different seeders, like your RandomSeeder
.
Cell
It has no meaning outside the Grid
class. It seems to only exist as a container for the game rules, and even the rules have been split between the Grid
and the Cell
(grid being responsible for counting the neighbors and cell making the decision based on that count). Maybe it exists only for the sake of having a class?
Attribution
Source : Link , Question Author : HariHaravelan , Answer Author : TorbenPutkonen