Last active
July 22, 2019 07:26
-
-
Save Eclairemoy/bdeb3fe85ee1757d02a3c8c6a3cfd9ee to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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