Skip to content

Instantly share code, notes, and snippets.

@Eclairemoy
Last active July 22, 2019 07:26
Show Gist options
  • Save Eclairemoy/bdeb3fe85ee1757d02a3c8c6a3cfd9ee to your computer and use it in GitHub Desktop.
Save Eclairemoy/bdeb3fe85ee1757d02a3c8c6a3cfd9ee to your computer and use it in GitHub Desktop.
import java.util.*;
public class GameOfLife {
// GAME OF LIFE
// Starts with a grid of square cells, each of which is in one of two possible states, alive or dead
// Every cell interacts with its 8 neighbors, which are the cells that are horizontally, vertically,
// or diagonally adjacent. At each step in time, the following transitions occur:
// Any live cell with fewer than two live neighbors dies, as if by underpopulation.
// Any live cell with two or three live neighbors lives on to the next generation.
// Any live cell with more than three live neighbors dies, as if by overpopulation.
// Any dead cell with three live neighbours becomes a live cell, as if by reproduction.
public static int generation = 1;
public static void main (String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("This is an implementation of John Conway's 'Game of Life' :)");
printPrompt("generations");
int numOfGenerations = Integer.parseInt(scan.nextLine().trim());
printPrompt("rows");
int rows = scanInput(scan.nextLine().trim(), scan, "rows");
printPrompt("columns");
int columns = scanInput(scan.nextLine().trim(), scan, "columns");
int[][] board = createBoard(rows, columns);
getNextGeneration(board, numOfGenerations);
}
public static void printPrompt(String type) {
String textToPrint = "Enter the number of " + type + " you want to generate";
switch(type) {
case "generations":
textToPrint = textToPrint + ": ";
break;
default:
textToPrint = textToPrint + " (must be > 2): ";
break;
}
System.out.println(textToPrint);
}
private static void printBoard(int[][] grid) {
for (int i = 0; i < grid.length; i++)
{
for (int j = 0; j < grid[0].length; j++)
{
if (grid[i][j] == 0)
System.out.print(" - ");
else
System.out.print(" + ");
}
System.out.println();
}
System.out.println();
}
public static int scanInput(String input, Scanner scan, String type) {
boolean isGreater = checkSize(input);
while (!isGreater) {
System.out.println("Number of " + type + " must be > 2. Please try again: ");
input = scan.nextLine().trim();
isGreater = checkSize(input);
}
return Integer.parseInt(input);
}
public static boolean checkSize(String input) {
if (Integer.parseInt(input) > 2){
return true;
} else {
return false;
}
}
// Draw and print the matrix
public static int[][] createBoard(int rows, int cols) {
int[][] board = new int[rows][cols];
System.out.println("Generation " + generation);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
board[i][j] = (int) Math.round(Math.random());
}
}
printBoard(board);
return board;
}
public static int getLivingNeighbors(int livingNeighbors, int i, int j, int[][] newBoard) {
//offset the rows
for(int k=-1; k<=1; k++) {
//offset the columns
for(int l=-1; l<=1; l++) {
// if the row offset is less than upper bound
if((i+k <0) ||
// if the row offset is more than lower bound
(i+k > newBoard.length-1) ||
// if the column offset is less than the left bound
(j+l <0) ||
// if the column offset is more than the right bound
(j+l > newBoard[i].length-1))
continue;
// add the neighbor when it is alive
livingNeighbors+= newBoard[i+k][j+l];
}
}
// remove the self counted
livingNeighbors-= newBoard[i][j];
return livingNeighbors;
}
public static void setAliveOrDead(int livingNeighbors, int[][] board, int i, int j) {
switch(livingNeighbors) {
case 0:
case 1:
// if less than two neighbors are alive set it to dead
board[i][j] = 0;
break;
case 2:
// if two neighbors are alive, whether living or dead it will remain the same
board[i][j] = board[i][j];
break;
case 3:
// if exactly three neighbors are alive, either stays alive if already alive
// or is set to alive if dead
board[i][j] = 1;
break;
default:
// if there are more than three neighbors alive set to dead
board[i][j] = 0;
}
}
/* Check all neighbors
* If live c neighbors < 2 mark dead c
* If 2 <= live c neighbors <= 3 stay alive
* If live c neighbors > 3 mark dead c
* If dead c neighbors == 3 mark alive
*/
public static int[][] getNextGeneration(int[][] board, int numOfGenerations) {
if (generation < numOfGenerations) {
generation += 1;
System.out.println("Generation " + generation);
int[][] newBoard = new int[board.length][board[0].length];
for(int i=0; i<board.length; i++) {
newBoard[i] = Arrays.copyOf(board[i], board[i].length);
}
int livingNeighbors;
//loop over the rows
for(int i=0; i<newBoard.length; i++) {
//loop over the columns
for(int j=0; j<newBoard[0].length; j++) {
//set the living neighbors to 0
livingNeighbors = getLivingNeighbors(0, i, j, newBoard);
setAliveOrDead(livingNeighbors, board, i, j);
}
}
printBoard(board);
board = getNextGeneration(board, numOfGenerations);
}
return board;
}
}
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class GameOfLifeTest {
private int[][] newBoard = {{0, 1, 0},
{0, 0, 1},
{1, 1, 1},
{0, 0, 0}};
@Test
void testCheckSize() {
boolean actual = App.checkSize("9");
assertTrue(actual);
}
@Test
void testCreateBoardHeight() {
int[][] board = App.createBoard(4, 3);
int expected = 4;
int actual = board.length;
assertEquals(expected, actual);
}
@Test
void testCreateBoardLength() {
int[][] board = App.createBoard(4, 3);
int expected = 3;
int actual = board[0].length;
assertEquals(expected, actual);
}
@Test
void testGetLivingNeighbors() {
int livingNeighbors = 0;
int i = 1;
int j = 1;
int expected = 5;
int actual = App.getLivingNeighbors(livingNeighbors, i, j, newBoard);
assertEquals(expected, actual);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment