Results 1 to 4 of 4
Thread: A more efficient Game of Life
 03272009, 12:33 AM #1Member
 Join Date
 Mar 2009
 Posts
 4
 Rep Power
 0
A more efficient Game of Life
Hello, this is my first post to Java Forums, so hopefully all goes well.
I've finished implementing the code for a 2D boolean arraybased implementation for John Conway's Game Of Life. The program functions properly (withouterrors) under all conditions, however I would like to improve it's effiicency.
I've pasted the section of the code in question below. This will probably make most experienced programmers laugh or cry, but I am beginner, so that's to be expected.
What I'm looking for is some detailed and specific ways to improve the code to make it less stressful on the CPU, and make it easier to read. In particular, I'm looking for ways to get rid of the excessive if statements for neighbor checking, and to reduce the number of cells checked by the nextGeneration methods (to only cells that will be subject to surviving, dying, or being vivified).
ALIVE and DEAD are boolean constants that correspond to true and false respectively.
MAX_ROWS and MAX_COLS are int constants defining he limits of the grid (array size).
Java Code:// copyMap: // Precondtions: None. // Postcondtion: 'map' is a deep copy of 'sourceMap'. // private void copyMap(boolean sourceMap[][]) { for(int r = 0; r < MAX_ROWS; r++){ for(int c = 0; c < MAX_COLS; c++){ map[r][c] = sourceMap[r][c]; } } } // clearMap: // Precondtions: None. // Postcondtion: Sets all cells of the 'targetMap' to DEAD. // private void clearMap(boolean targetMap[][]) { for(int r = 0; r < MAX_ROWS; r++){ for(int c = 0; c < MAX_COLS; c++){ targetMap[r][c] = DEAD; } } } // getFlatNeighborCount: // Precondtions: 0 <= row < MAX_ROWS and 0 <= col < MAX_COLS. // Postcondtion: A count of all LIVE neighbors of the cell at [row, col] is // returned where its neighbors are all the ADJACENT cells // including those // a) In the rows BELOW and ABOVE the cell (if any exist). // b) In the columns LEFT and RIGHT of the cell (if any exist). // Thus, a cell adjacent to a board edge (or corner) has // fewer neighbors than other cells. // private int getFlatNeighborCount(int row, int col){ int count = 0; if(row  1 >= 0 && map[row  1][col]){ count++; } if(row + 1 < MAX_ROWS && map[row + 1][col]){ count++; } if(col  1 >= 0 && map[row][col  1]){ count++; } if(col + 1 < MAX_COLS && map[row][col + 1]){ count++; } if((row  1 >= 0 && col  1 >= 0) && map[row 1][col 1]){ count++; } if((row  1 >= 0 && col + 1 < MAX_COLS) && map[row  1][col + 1]){ count++; } if((row + 1 < MAX_ROWS && col  1 >= 0) && map[row + 1][col 1]){ count++; } if((row + 1 < MAX_ROWS && col + 1 < MAX_COLS) && map[row + 1][col + 1]){ count++; } return count; } // nextGenerationForFlatGrid: // Precondtions: None // Postcondtion: The next generation of live and dead cells is calculated using // a) the FLAT neighbor counts. // b) the current birth, survival and death count rules. // c) the rules are applied to the counts obtained from the current // generation's configuration of live and dead cells. // The current 'map' is updated to the next generation's configuration // of live and dead cells. // d) the global variable 'generation' is increased by 1 // public void nextGenerationForFlatGrid() { for(int row = 0; row < MAX_ROWS; row++){ for(int col = 0; col < MAX_COLS; col++){ int neighborCount = getFlatNeighborCount(row, col); if(!map[row][col] && neighborCount == 3){ newMap[row][col] = ALIVE; } else if(map[row][col] && (neighborCount == 2  neighborCount == 3)){ newMap[row][col] = ALIVE; } else if(map[row][col] && neighborCount <= 1){ newMap[row][col] = DEAD; } else if(map[row][col] && neighborCount >= 4){ newMap[row][col] = DEAD; } } } copyMap(newMap); clearMap(newMap); generation++; } // ==> 5. Implement the game of life for torus grid. /**getTorusNeighborCount * Preconditions: 0 <= row < MAX_ROWS and 0 <= col < MAX_COLS. * Postconditions: The count is increased for each living adjacent neighbor. * This counts only neighbors located on adjacent edges of the grid. * The count is returned when finished. */ public int getTorusNeighborCount(int row, int col){ int count = 0; if((row == MAX_ROWS  1) && map[0][col]){ count++; } if((row == MAX_ROWS  1 && col > 0) && map[0][col  1]){ count++; } if((row == MAX_ROWS  1 && col < MAX_COLS  1) && map[0][col + 1]){ count++; } if(row == 0 && map[MAX_ROWS  1][col]){ count++; } if((row == 0 && col > 0) && map[MAX_ROWS  1][col  1]){ count++; } if((row == 0 && col < MAX_COLS  1) && map[MAX_ROWS  1][col + 1]){ count++; } if((col == MAX_COLS  1) && map[row][0]){ count++; } if((col == MAX_COLS  1 && row > 0) && map[row  1][0]){ count++; } if((col == MAX_COLS  1 && row < MAX_ROWS  1) && map[row + 1][0]){ count++; } if((col == 0) && map[row][MAX_COLS  1]){ count++; } if((col == 0 && row > 0) && map[row  1][MAX_COLS  1]){ count++; } if((col == 0 && row < MAX_ROWS  1) && map[row + 1][MAX_COLS  1]){ count++; } if((row == 0 && col == 0) && map[MAX_ROWS  1][MAX_COLS  1]){ count++; } if((row == MAX_ROWS  1 && col == 0) && map[0][MAX_COLS  1]){ count++; } if((row == 0 && col == MAX_COLS  1) && map[MAX_ROWS  1][0]){ count++; } if((row == MAX_ROWS  1 && col == MAX_COLS  1) && map[0][0]){ count++; } return count; } /** nextGenerationForTorusGrid() * Precondition: None * Postcondition: The grid is updated utilizing the FLAT and TORUS neighbor counts. * The same birth, survival and death rules apply as with the next FLAT generation. * The generation variable is increased by 1. * */ public void nextGenerationForTorusGrid() { for(int row = 0; row < MAX_ROWS; row++){ for(int col = 0; col < MAX_COLS; col++){ int neighborCount = getFlatNeighborCount(row, col) + getTorusNeighborCount(row, col); if(!map[row][col] && neighborCount == 3){ newMap[row][col] = ALIVE; } else if(map[row][col] && (neighborCount == 2  neighborCount == 3)){ newMap[row][col] = ALIVE; } else if(map[row][col] && neighborCount <= 1){ newMap[row][col] = DEAD; } else if(map[row][col] && neighborCount >= 4){ newMap[row][col] = DEAD; } } } copyMap(newMap); clearMap(newMap); generation++; }
 03272009, 01:03 AM #2Senior Member
 Join Date
 Sep 2008
 Posts
 564
 Rep Power
 8
you can tack some of your ifstatements together to ifelse ifelse statements. no reason to check if row == max_rows if we already confirmed row == 0, and so forth. you can also nest them, so you don't have to keep checking if row == 0 until we find out that col == max_cols.
allinall, improvements on your code will help you towards better coding behavior that will make larger programs you make be more efficient. but this one is too simple to experience a notable lag. unless your board is insanely large.
 03272009, 01:20 AM #3Member
 Join Date
 Mar 2009
 Posts
 4
 Rep Power
 0
Ahh, that's true. When I wrote this I simply split the grid up into sections where neighbors would be, and wrote an if statement for each possibility.
I didn't consider the else's since I wanted to make sure the program didn't miss any case. I usually write ifelse's for efficiency too.
Thanks!
 03272009, 04:08 AM #4Member
 Join Date
 Mar 2009
 Posts
 4
 Rep Power
 0
Ok, here's my reworked code for the flat and torus neighbor counts.
I nested my statements for the flat and torus, and also used Math.abs() to cut my statements for torus in half, making it easier to read.
Thanks again for the help!!
Java Code:// getFlatNeighborCount: // Precondtions: 0 <= row < MAX_ROWS and 0 <= col < MAX_COLS. // Postcondtion: A count of all LIVE neighbors of the cell at [row, col] is // returned where its neighbors are all the ADJACENT cells // including those // a) In the rows BELOW and ABOVE the cell (if any exist). // b) In the columns LEFT and RIGHT of the cell (if any exist). // Thus, a cell adjacent to a board edge (or corner) has // fewer neighbors than other cells. // private int getFlatNeighborCount(int row, int col){ int count = 0; if(row  1 >= 0){ if(map[row  1][col]){ count++; } if(col  1 >= 0 && map[row  1][col 1]){ count++; } } if(row + 1 < MAX_ROWS){ if(map[row + 1][col]){ count++; } if(col + 1 < MAX_COLS && map[row + 1][col + 1]){ count++; } } if(col  1 >= 0){ if(col  1 >= 0 && map[row][col  1]){ count++; } if(row + 1 < MAX_ROWS && map[row + 1][col  1]){ count++; } } if(col + 1 < MAX_COLS){ if(map[row][col + 1]){ count++; } if(row  1 >= 0 && map[row  1][col + 1]){ count++; } } return count; } // ==> 5. Implement the game of life for torus grid. /**getTorusNeighborCount * Preconditions: 0 <= row < MAX_ROWS and 0 <= col < MAX_COLS. * Postconditions: The count is increased for each living adjacent neighbor. * This counts only neighbors located on adjacent edges of the grid. * The count is returned when finished. */ public int getTorusNeighborCount(int row, int col){ if((row == 0  row == BOTTOM)  (col == 0  col == FAR_RIGHT)){ int count = 0; final int ROW_EDGE = Math.abs(row  BOTTOM); final int COL_EDGE = Math.abs(col  FAR_RIGHT); if(row == BOTTOM  row == 0){ if(map[ROW_EDGE][col]){ count++; } if(col > 0 && map[ROW_EDGE][col  1]){ count++; } if(col < FAR_RIGHT && map[ROW_EDGE][col + 1]){ count++; } if(map[ROW_EDGE][COL_EDGE]){ count++; } } else{ if(map[row][COL_EDGE]){ count++; } if(row > 0 && map[row  1][COL_EDGE]){ count++; } if(row < BOTTOM && map[row + 1][COL_EDGE]){ count++; } if(map[ROW_EDGE][COL_EDGE]){ count++; } } return count; } else{ return 0; } }
Similar Threads

Efficient Perfect Number
By Lite3864 in forum New To JavaReplies: 4Last Post: 11232008, 02:07 AM 
Game of Life assignment
By javan00b in forum New To JavaReplies: 4Last Post: 04282008, 05:49 AM 
Servlet Life Cycle
By Java Tip in forum Java TipReplies: 0Last Post: 11282007, 10:57 AM
Bookmarks