Game of Life : Implementation in Java
|John Conway’s Game of Life : Implementation in Java
Game Rules :
1. Any live cell with fewer than two live neighbors dies, as if caused by under-population.
2. Any live cell with two or three live neighbors lives on to the next generation.
3. Any live cell with more than three live neighbors dies, as if by overcrowding.
4. Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction.
5. In any other state cell dies or remains quiescent/dead.
@return the state of the given cell on the basis of rules
package com.gol; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader;\ import java.util.StringTokenizer; import sun.util.locale.StringTokenIterator; public class GameOfLife { /* * There are 8 immediate neighbors of any given location in board, if all boundary conditions met * given location : [row, col] * * * [r-1, c-1] [r-1, c] [r-1, c+1] * * [r, c-1] <---[r,c]---> [r, c+1] * * [r+1, c-1] [r+1, c] [r+1, c+1] * * We can count neighbor either using 8 if else or using loops as well. * I think loop is better option, it will take care of boundary condition as well, * otherwise in case of if-else we have to go through all 8 if-else irrespective of the given loc. * eg : [0,0] * Assuming row and col cannot be -ve i.e less then zero(<0) * @return the numbers of live cell in the neighbor of given cell * Time : both loops executes 9 times if row and col both are >0 */ public int getNeighbourCount(boolean board[][], int rc, int cc, int row, int col){ int r = rc==0 ? 0 : rc-1; // to check boundary condition int c = cc==0 ? 0 : cc-1; int i, j, liveCount=0; for (i=r; i<=r+1 && i<row; i++) { for (j=c; j<=c+1 && j<col; j++) { if (i==row && j==col) { continue; // no need to count for the given location on the board } if (board[i][j]){ //counting live neighbors only liveCount++; } } } return liveCount; } /* * Game Rules : * 1. Any live cell with fewer than two live neighbors dies, as if caused by under-population. * 2. Any live cell with two or three live neighbors lives on to the next generation. * 3. Any live cell with more than three live neighbors dies, as if by overcrowding. * 4. Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction. * 5. In any other state cell dies or remains quiescent/dead. * @return the state of the given cell on the basis of rules */ public boolean getState(boolean cellState, int liveCount){ if (cellState) {//live cell rules-1,2,3 if (liveCount<2)return false; if (liveCount==2 || liveCount==3)return true; if (liveCount>3)return false; }else{ // dead cell rules-4 if (liveCount==3)return true; } return false; //otherwise return the existing state, means state will not change or if there is rule 5 return false } /* * Input 1 : Board row and col * Input 2 : Live cell location in board */ public Board getInput() throws IOException{ System.out.println("Input 1 : Board row and col"); System.out.println("Input 2 : Live cell location in board, comma seprated list"); InputStreamReader in = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(in); String rowStr = br.readLine(); int row = Integer.parseInt(rowStr); String colStr = br.readLine(); int col = Integer.parseInt(colStr); String liveCellLoc = br.readLine(); // comma separated list StringTokenizer st = new StringTokenizer(liveCellLoc, ","); int size = st.countTokens(); int liveCell[] = new int[size]; int i=0; while(st.hasMoreElements()) { liveCell[i] = Integer.parseInt((String)st.nextElement()); i++; } Board board = new Board(row, col); board.constructBoard(liveCell); return board; } public void start(Board board){ int i, j, liveCount; int count=0; while(true){ for (i=0; i<board.row; i++) { for (j=0; j<board.col; j++) { liveCount = getNeighbourCount(board.board, i, j, board.row, board.col); board.board[i][j] = getState(board.board[i][j], liveCount); } } //System.out.println("\r"); System.out.print(boardToString(board.board, board.row, board.col)); //System.out.flush(); //count++; } } private String boardToString(boolean[][] board, int row, int col) { StringBuffer sb = new StringBuffer(); int i,j; for (i=0; i<row; i++) { for (j=0; j<col; j++) { if (board[i][j]){ sb.append("*"); //append * for live state }else{ sb.append("-"); // append space for dead state; } } sb.append("\n"); } //System.out.println(sb.toString()); return sb.toString(); } class Board{ private int row; private int col; private boolean[][]board; public Board(int row, int col){ this.row = row; this.col = col; board = new boolean[row][col]; } public void constructBoard(int []liveCell){ int i,r,c,loc; for (i=0; i<liveCell.length; i++) { loc = liveCell[i]; r = loc/col; c = loc%col; board[r]=true; } } } public static void main(String[] args) throws IOException { GameOfLife gol = new GameOfLife(); Board board = gol.getInput(); gol.start(board); } } // 2nd Solution using if-else to get neighbor count for any given location. package com.gol; import java.io.*; public class GOL{ public static String boardToString (boolean[][] board, int xsize, int ysize){ StringBuffer sb= new StringBuffer(); // used to print out the board at the end for (int i=0;i<xsize;i++){ for (int j=0;j<ysize;j++){ if (board [i][j]){ sb.append('*'); }else{ sb.append(' '); } } sb.append("\n"); } return sb.toString(); } public static boolean[][] strToBoolMatrix (String str, int xsize, int ysize){ boolean [][] board = new boolean[xsize][ysize]; // converts an input string into the for (int i=0;i<xsize; i++){ // boolean[][] used internally for (int j=0; j<ysize; j++){ board[i][j] = str.charAt((i*xsize)+j) != '0'; } } return board; } public static int mod (int x, int m){ // deals with java's % returning negative vals for m = Math.abs(m); // negative inputs return (x % m + m) % m; } public static int getNeighborCount(boolean[][] board, int x, int y, int xsize, int ysize){ int nc = 0; // this function rather messily counts up the neighbors if (board[mod(x+1,xsize)][y]){ nc++; } if (board[mod(x+1,xsize)][mod(y+1, ysize)]){ nc++; } if (board[x][mod(y+1,ysize)]){ nc++; } if (board[x][mod(y-1,ysize)]){ nc++; } if (board[mod(x+1,xsize)][mod(y-1,ysize)]){ nc++; } if (board[mod(x-1,xsize)][y]){ nc ++; } if (board[mod(x-1,xsize)][mod(y-1,ysize)]){ nc ++; } if (board[mod(x-1,xsize)][mod(y+1,ysize)]){ nc ++; } return nc; } public static boolean getDot(boolean[][] board, int x, int y, int xsize, int ysize){ // this function applies the rules of the game on one square return board[x][y] && getNeighborCount(board, x,y,xsize,ysize) == 2 || getNeighborCount(board,x,y,xsize,ysize) == 3; } public static void main(String[] args) throws java.io.FileNotFoundException, java.io.IOException{ int xsize = Integer.parseInt(args[0]); // takes board size off command line int ysize = Integer.parseInt(args[1]); int gen = Integer.parseInt(args[2]); // number of generations FileReader fr = new FileReader(args[3]); // will read in board from a file BufferedReader br= new BufferedReader(fr); StringBuffer sb = new StringBuffer(); String line = new String(br.readLine()); while(line != null){ // reading file sb.append(line); line = br.readLine(); } String s = sb.toString(); boolean[][] board = strToBoolMatrix(s,xsize,ysize); // this is the game board for (int i=0; i<gen; i++){ // loops through the generations boolean[][] next = new boolean[xsize][ysize]; // empty board for (int j=0;j<xsize;j++){ // loops through x-axis for computing the next generation for (int k=0; k< ysize; k++){ // loops through y-axis next[j][k] = getDot(board,j,k,xsize,ysize); } } board = next; // use the 'next' array as the new 'board' array } System.out.println(boardToString(board,xsize,ysize)); // prints the board } }
11 Comments
Your mode of explaining the whole thing in this paragraph is
in fact good, every one be able to easily know it, Thanks a
lot.
Thanks for your feedback.
Oh my goodness! Awesome article dude! Thank you so much,
However I am having difficulties with your RSS. I don’t know why I am unable to subscribe
to it. Is there anyone else getting identical RSS issues?
Anyone who knows the solution can you kindly respond?
Thanks!!
Thanks.. I am looking into RSS issue let u know once its fixed
I’m gone to convey my little brother, that he
should also visit this blog on regular basis to
take updated from most recent information.
Thanks
Hey! Do you know if they make any plugins to help with Search Engine
Optimization? I’m trying to get my blog to rank for some targeted
keywords but I’m not seeing very good gains. If you know of any please share.
Thank you!
I see you don’t monetize your blog, don’t waste your
traffic, you can earn extra bucks every month because you’ve got high quality content.
If you want to know how to make extra $$$, search for: Ercannou’s essential adsense alternative
Awesome! Its truly awesome piece of writing, I have got much clear idea concerning from this
article.