Java Forum / General / November 2005
game of life
CPSCmajor - 18 Nov 2005 03:20 GMT Hello, My assignment is to write a program that simulates the game of life with a multidimensional array over 25 generations. I got the initial configurations entered in, but I can't think of how to make the method for the future generations work. The rules are that if a living counter (X in my program) is surrounded by 2 or 3 neighbors, it survives. Each counter surrounded by 4 or more dies, and so does each counter with 1 or no neighbors. A birth occurs in each empty cell that is adjacent exactly to 3 cells. I am not asking for someone to write the code for me...so please don't misunderstand me. I just need help on how to write a method or way to check for these conditions for each of the different configurations without having to go through and actually code each generation out. Any ideas are greatly appreciated, this is due Monday...Thanks!
Here is my code so far, and there are 12 configurations.
import java.awt.*; import javax.swing.*; import java.awt.geom.*; import java.util.*;
public class GameOfLife { private String[][] board; private static final int ROWS = 30; private static final int COLUMNS = 30; // Constructs an empty board. public GameOfLife() { board = new String[ROWS][COLUMNS]; for (int i = 0; i < ROWS; i++) for (int j = 0; j < COLUMNS; j++) board[i][j] = " "; } /** Sets a field in the board. The field must be unoccupied. @param i the row index @param j the column index */ public void set(int i, int j) { if (board[i][j].equals(" ")) board[i][j] = "X"; // Sets up the configuration }
/** Creates a string representation of the board, such as | | | | | | @return the string representation */ public String toString() { String r = ""; for (int i = 0; i < ROWS; i++) { r = r + "|"; for (int j = 0; j < COLUMNS; j++) r = r + board[i][j]; r = r + "|\n"; } return r; } /** *This was where I attempted to start the method to check for the generations which I *realized would involve coding for every single one. */ public void nextGen(int i, int j) { int x; for (x = 0; x <= 25; x++) { if (board[i][j].equals("X")) if (board[i][j-1].equals("X") && board[i][j+1].equals("X") && board[i-1][j].equals("X") && board[i-1][j-1].equals("X") && board[i-1][j+1].equals("X") && board[i+1][j].equals("X") && board[i+1][j-1].equals("X") && board[i+1][j+1].equals("X"))
}
} public static void main(String[] args) { GameOfLife g = new GameOfLife(); // Creates a new Game of Life Scanner s = new Scanner(System.in); System.out.print("Enter a configuration: "); // Allows for the user to choose the setup position int config = s.nextInt(); int i = 12; int j = 12; int board[][] = new int[ROWS][COLUMNS]; System.out.print(g.toString());
if (config == 1) // Sets up configuration a { for (board[i][j] = 1; j <= 15; j++) g.set(i, j); System.out.print(g.toString()); } else if (config == 2) // Sets up configuration b { for (board[i][j] = 1; j <= 16; j++) g.set(i, j); System.out.print(g.toString()); } else if (config == 3) // Sets up configuration c { for (board[i][j] = 1; j <= 17; j++) g.set(i, j); System.out.print(g.toString()); } else if (config == 4) // Sets up configuration d { g.set(i-1, j+1); System.out.print(g.toString());
g.set(i, j+2); System.out.print(g.toString());
g.set(i, j); System.out.print(g.toString());
g.set(i+1,j+1); System.out.print(g.toString()); } else if (config == 5) // Sets up configuration e { g.set(i-1, j+1); System.out.print(g.toString());
for (board[i][j] = 1; j <= 14; j++) g.set(i, j); System.out.print(g.toString()); } else if (config == 6) // Sets up configuration f { g.set(i, j+4); g.set(i, j+5); g.set(i, j+6); System.out.print(g.toString()); for (board[i][j] = 1; j <= 14; j++) g.set(i, j); System.out.print(g.toString()); } else if (config == 7) // Sets up configuration g { g.set(i, j+5); g.set(i, j+6); g.set(i, j+7); g.set(i, j+8); System.out.print(g.toString()); for (board[i][j] = 1; j <= 15; j++) g.set(i, j); System.out.print(g.toString()); } else if (config == 8) // Sets up configuration h { g.set(i-2, j+1); g.set(i-1, j+2); System.out.print(g.toString());
for (board[i][j] = 1; j <= 14; j++) g.set(i, j); System.out.print(g.toString()); } else if (config == 9) // Sets up configuration i { g.set(i-1, j+1); g.set(i-1, j+2); g.set(i-1, j+3); System.out.print(g.toString());
for (board[i][j] = 1; j <= 14; j++) g.set(i, j); System.out.print(g.toString()); } else if (config == 10) // Sets up configuration j { g.set(i-1, j); g.set(i-1, j+2); g.set(i+1, j); g.set(i+1, j+2); System.out.print(g.toString());
for (board[i][j] = 1; j <= 14; j++) g.set(i, j); System.out.print(g.toString()); } else if (config == 11) // Sets up configuration k { g.set(i-2, j); g.set(i-1, j); g.set(i-2, j+2); g.set(i-1, j+2); System.out.print(g.toString());
for (board[i][j] = 1; j <= 14; j++) g.set(i, j); System.out.print(g.toString()); } else if (config == 12) // Sets up configuration l { g.set(i-1, j); g.set(i-1, j+1); g.set(i+1, j+2); g.set(i+1, j+3); g.set(i+2, j+2); g.set(i+2, j+3); System.out.print(g.toString());
for (board[i][j] = 1; j <= 13; j++) g.set(i, j); System.out.print(g.toString()); } } }
Niels Dybdahl - 18 Nov 2005 09:22 GMT > My assignment is to write a program that simulates the game of life > with a multidimensional array over 25 generations. I got the initial [quoted text clipped - 9 lines] > generation out. Any ideas are greatly appreciated, this is due > Monday...Thanks! Loop from -1 to +1 in both x and y-directions for each cell and count the number of neighbors. Use two arrays. One for the current generation and one for the next and swap them when you have calculated the next. Take care at the borders.
Niels Dybdahl
CPSCmajor - 20 Nov 2005 19:10 GMT Hey, I don't know how to write a loop for that, so I guess I will just have to code in for what it is supposed to display...is there a method to pause or slow down executions, so that one can see what is going on. I found the TimerTask class but I didn't work with what I was trying to do. Any other ideas?
Thanks.
> > My assignment is to write a program that simulates the game of life > > with a multidimensional array over 25 generations. I got the initial [quoted text clipped - 17 lines] > > Niels Dybdahl CPSCmajor - 20 Nov 2005 22:13 GMT Hey I figured out how to write the loop, but I am getting an out of bounds exception that I have tried to fix w/ no luck...
public int countNeighbors(String[][] currentBoard, int x, int y) { int neighbors = 0; if("X".equals(currentBoard[x-1][y-1]) && x < 30 && y < 30) neighbors++; if("X".equals(currentBoard[x-1][y]) && x < 30 && y < 30) neighbors++; if("X".equals(currentBoard[x-1][y+1]) && x < 30 && y < 30) neighbors++; if("X".equals(currentBoard[x][y-1]) && x < 30 && y < 30) neighbors++; if("X".equals(currentBoard[x][y+1]) && x < 30 && y < 30) neighbors++; if("X".equals(currentBoard[x+1][y-1]) && x < 30 && y < 30) neighbors++; if("X".equals(currentBoard[x+1][y]) && x < 30 && y < 30) neighbors++; if("X".equals(currentBoard[x+1][y+1]) && x < 30 && y < 30) neighbors++; return neighbors; }
I don't understand how putting the x < 30 and y < 30 doesn't fix it...Any ideas??
> Hey, > I don't know how to write a loop for that, so I guess I will just have [quoted text clipped - 26 lines] > > > > Niels Dybdahl Jim Korman - 21 Nov 2005 01:46 GMT >Hey I figured out how to write the loop, but I am getting an out of >bounds exception that I have tried to fix w/ no luck... [quoted text clipped - 23 lines] >I don't understand how putting the x < 30 and y < 30 doesn't fix >it...Any ideas?? Look close at the Exception. I'll bet that you're throwing the exception on x == 0 and y == 0.
Jim
Roedy Green - 21 Nov 2005 02:57 GMT > int neighbors = 0; > if("X".equals(currentBoard[x-1][y-1]) && x < 30 && y < 30) [quoted text clipped - 14 lines] > neighbors++; > return neighbors; since every expression contain x< 30 && y < 30, you want to factor that out. Further, if this is a subscript bounds check, you want it before [x+1] is evaluated.
e.g.
if ( x < 30 && y < 30 ) { if("X".equals(currentBoard[x-1][y-1]) neighbors++; ... }
Without seeing the rest of your code, I suspect you may get some substript out of bounds even then.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
CPSCmajor - 21 Nov 2005 04:24 GMT Yep you were right, now i get an out of bounds exception on 30....
public int countNeighbors(String[][] currentBoard, int x, int y) { int neighbors = 0; if (x > 0 && x < 30 && y > 0 && y < 30) { if ("X".equals(currentBoard[x-1][y-1])) neighbors++; if ("X".equals(currentBoard[x-1][y])) neighbors++; if ("X".equals(currentBoard[x-1][y+1])) neighbors++; if ("X".equals(currentBoard[x][y-1])) neighbors++; if ("X".equals(currentBoard[x][y+1])) neighbors++; if ("X".equals(currentBoard[x+1][y-1])) neighbors++; if ("X".equals(currentBoard[x+1][y])) neighbors++; if ("X".equals(currentBoard[x+1][y+1])) neighbors++; } return neighbors; }
Roedy Green - 21 Nov 2005 07:29 GMT >an out of bounds exception on 30 that is because you check index x+1 and also y+1.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Roedy Green - 21 Nov 2005 07:42 GMT > if ("X".equals(currentBoard[x-1][y-1])) > neighbors++; [quoted text clipped - 12 lines] > if ("X".equals(currentBoard[x+1][y+1])) > neighbors++; If I were doing this I would generate all these combos roughly like this:
for ( int xoff =-1, xoff<=1; xoff++) { xnear = x+xoff; if ( 0 <= xnear && xnear <= 30 ) { for ( int yoff =-1, yoff<=1; yoff++) { ynear = y + yoff; if ( 0 <= year && ynear <= 30 ) { if ( "X".equals(currentBoard[xnear][ynear]) { neighbours ++; } } } } }
or better still like this:
for ( int xnear=Math.max(0,x-1); xnear<= Math.min(x+1,30); xnear++) { for (int ynear=Math.max(0,y-1); ynear<= Math.min(y+1,30); ynear++) { if ( "X".equals(currentBoard[xnear][ynear]) { neighbours ++; } } }
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Roedy Green - 21 Nov 2005 09:27 GMT On Mon, 21 Nov 2005 07:42:18 GMT, Roedy Green <my_email_is_posted_on_my_website@munged.invalid> wrote, quoted or indirectly quoted someone who said :
> for ( int xnear=Math.max(0,x-1); xnear<= Math.min(x+1,30); >xnear++) [quoted text clipped - 8 lines] > } > } this gives you a count of neighbours one too big since it counts the center cell as a neighbour.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
wolfgang zeidler - 21 Nov 2005 20:19 GMT > Yep you were right, now i get an out of bounds exception on 30.... > [quoted text clipped - 11 lines] > return neighbors; > } As I remember gol *every* cell has 8 neighbours, i.e. e.g. the left cell [7] [0] has this neighbours: [6,29] [6,0] [6,1] [7,29] [7,1] [8,29] [8,0] [8,1]
Some untested/uncompiled lines:
boolean [] [] living = new boolean [30] [30];
void initLiving () { // you did it? I think you did it ... } void updateLiving () { int [] [] livingNeighbours = new int [30] [30]; // may be static livingNeighbours [ 0] [ 0] = countLN ( 29, 0, 1, 29, 0, 1 ); // top left livingNeighbours [ 0] [29] = ... livingNeighbours [29] [ 0] = ... livingNeighbours [29] [29] = ... for ( int y = 1; y < 29; y++ ) { // left border without corners: livingNeighbours [y] [ 0] = countLN ( 29, 0, 1, y-1, y, y+1 ); // right border without corners: livingNeighbours [y] [29] = countLN ( 28, 29, 0, y-1, y, y+1 ); } for ( int x = 1; x < 29; x++ ) { // top border without corners: livingNeighbours [ 0] [x] = countLN ( x-1, x, x+1, 29, 0, 1 ); // bottom border without corners: livingNeighbours [29] [x] = countLN ( x-1, x, x+1, 28, 29, 0 ); } // and now the inner cells: for ( int y = 1; y < 29; y++ ) for ( int x = 1; x < 29; x++ ) livingNeighbours [y] [x] = countLN ( x-1, x, x+1, y-1, y, y+1 ); // finally: set living to the next generation: for ( int y = 0; y < 30; y++ ) for ( int x = 0; x < 30; x++ ) living [y] [x] = livingNeighbours [y] [x] == 3 || livingNeighbours [y] [x] == 2 && living [y] [x]; }
int countLN ( int w, int x, int e, int n, int y, int s ) { // counts: // [n,w] [n,x] [n,e] // [y,w] [y,e] // [s,w] [s,x] [s,e] // where n means north, w means west, ... int c = 0 if ( living [n] [w] ) c++ ... // 7 lines more return c }
regards, wz
p.s.: It may be a good idea to replace "30" with ROWS or COLUMNS, "29"/"28" ...
 Signature http://wzwz.de/mail
Roedy Green - 21 Nov 2005 20:22 GMT On Mon, 21 Nov 2005 21:19:22 +0100, wolfgang zeidler <dieses-postfach-wird-niemals-geleert@arcor.de> wrote, quoted or indirectly quoted someone who said :
>As I remember gol *every* cell has 8 neighbours, the bottom left cell has 3 neighbours.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
CPSCmajor - 22 Nov 2005 02:13 GMT Hey all, I got rid of the out of bounds exception, and now the rest of the program doesn't work :( ! All that it will do is display the initial configuration and then make it disappear. I don't know what else to try to fix it. Any ideas?
Here is the code:
import java.awt.*; import javax.swing.*; import java.awt.geom.*; import java.util.*;
public class GameOfLife { private int neighbors = 0; private String[][] currentBoard; private String[][] newBoard; private static final int ROWS = 30; private static final int COLUMNS = 30; // Constructs an empty board. public GameOfLife() { currentBoard = new String[ROWS][COLUMNS]; for (int i = 0; i < ROWS; i++) for (int j = 0; j < COLUMNS; j++) currentBoard[i][j] = " "; newBoard = new String[ROWS][COLUMNS]; for (int i = 0; i < ROWS; i++) for (int j = 0; j < COLUMNS; j++) newBoard[i][j] = " "; } /** Sets a field in the board @param i the row index @param j the column index */ public void set(int i, int j) { if (currentBoard[i][j].equals(" ")) currentBoard[i][j] = "X"; // Sets up the configuration } public void set2(int i, int j) { if (newBoard[i][j].equals(" ")) newBoard[i][j] = "X"; // Sets up for future generations } /** Creates a string representation of the board, such as | | | | | | @return the string representation */ public String toString() { String r = ""; for (int i = 0; i < ROWS; i++) { r = r + "|"; for (int j = 0; j < COLUMNS; j++) r = r + currentBoard[i][j]; r = r + "|\n"; } return r; } public String toString2() { String r = ""; for (int i = 0; i < ROWS; i++) { r = r + "|"; for (int j = 0; j < COLUMNS; j++) r = r + newBoard[i][j]; r = r + "|\n"; } return r; } /** * This is a method that counts the number of neighbors surrounding an X. * @param x the row in the grid * @param y the column in the grid * @return the number of neighbors */ public int countNeighbors(String[][] currentBoard, int x, int y) { if (x > 0 && x < 30 && y > 0 && y < 30) { if ("X".equals(currentBoard[x-1][y-1])) neighbors++; if ("X".equals(currentBoard[x-1][y])) neighbors++; if ("X".equals(currentBoard[x-1][y+1])) neighbors++; if ("X".equals(currentBoard[x][y-1])) neighbors++; if ("X".equals(currentBoard[x][y+1])) neighbors++; if ("X".equals(currentBoard[x+1][y-1])) neighbors++; if ("X".equals(currentBoard[x+1][y])) neighbors++; if ("X".equals(currentBoard[x+1][y+1])) neighbors++; } return neighbors; } /** * This is a method that uses the rules to determine what the next generation will look like. * @param String[][] currentBoard * @return the board with the next generation on it */ public String[][] nextGen(String[][] currentBoard) { String[][] newBoard = new String [ROWS][COLUMNS]; newBoard = currentBoard; for(int x = 0; x < currentBoard.length; x++) { for(int y = 0; y < currentBoard[x].length; y++) { int n = neighbors;
if ("X".equals(currentBoard[x][y])) { // Determines death if (n == 0 || n == 1 || n <= 4) { newBoard[x][y] = " "; } } else { // Determines births if (n == 3) { newBoard[x][y] = "X"; } } } } return newBoard; } public static void main(String[] args) { GameOfLife g = new GameOfLife(); // Creates a new Game of Life Scanner s = new Scanner(System.in); System.out.print("Enter a configuration: "); // Allows for the user to choose the setup position int config = s.nextInt(); int i = 12; int j = 12; String board[][] = new String[ROWS][COLUMNS]; System.out.print(g.toString());
if (config == 1) // Sets up configuration a { for (board[i][j] = " "; j <= 15; j++) { g.set(i, j); System.out.print(g.toString()); } g.countNeighbors(board, i, j); System.out.print(g.nextGen(board)); System.out.print(g.toString());
/** int x = 12; int y = 12; g.set2(x,y); g.set2(x,y+3); System.out.print(g.toString());
g.set(x-1, y+1); g.set(x-1,y+2); g.set(x+1, y+1); g.set(x+1, y+2); System.out.print(g.toString()); g.set2(x,x+1); g.set2(x,x+2); System.out.print(g.toString()); g.set(x, y); g.set(x,y+3); System.out.print(g.toString()); */ } else if (config == 2) // Sets up configuration b { for (board[i][j] = " "; j <= 16; j++) { g.set(i, j); System.out.print(g.toString()); } g.countNeighbors(board, i, j); g.nextGen(board); System.out.print(g.toString2()); /** g.set2(i, j); System.out.print(g.toString());
int y = 12; g.set(i, y+1); g.set(i, y+2); g.set(i, y+3); System.out.print(g.toString()); g.set2(i, y+1); g.set2(i, y+2); g.set2(i, y+3); System.out.print(g.toString()); g.set(i, y+2); System.out.print(g.toString()); g.set2(i, y+2); System.out.print(g.toString()); */ } else if (config == 3) // Sets up configuration c { for (board[i][j] = " "; j <= 17; j++) { g.set(i, j); System.out.print(g.toString()); } g.countNeighbors(board, i, j); g.nextGen(board); System.out.print(g.toString2()); } else if (config == 4) // Sets up configuration d { g.set(i-1, j+1); System.out.print(g.toString());
g.set(i, j+2); System.out.print(g.toString());
g.set(i, j); System.out.print(g.toString());
g.set(i+1,j+1); System.out.print(g.toString());
g.countNeighbors(board, i, j); g.nextGen(board); System.out.print(g.toString()); } else if (config == 5) // Sets up configuration e { g.set(i-1, j+1); System.out.print(g.toString());
for (board[i][j] = " "; j <= 14; j++) { g.set(i, j); System.out.print(g.toString()); } g.countNeighbors(board, i, j); g.nextGen(board); System.out.print(g.toString()); } else if (config == 6) // Sets up configuration f { g.set(i, j+4); g.set(i, j+5); g.set(i, j+6); System.out.print(g.toString()); for (board[i][j] = " "; j <= 14; j++) { g.set(i, j); System.out.print(g.toString()); } g.countNeighbors(board, i, j); g.nextGen(board); System.out.print(g.toString()); } else if (config == 7) // Sets up configuration g { g.set(i, j+5); g.set(i, j+6); g.set(i, j+7); g.set(i, j+8); System.out.print(g.toString()); for (board[i][j] = " "; j <= 15; j++) { g.set(i, j); System.out.print(g.toString()); } g.countNeighbors(board, i, j); g.nextGen(board); System.out.print(g.toString()); } else if (config == 8) // Sets up configuration h { g.set(i-2, j+1); g.set(i-1, j+2); System.out.print(g.toString());
for (board[i][j] = " "; j <= 14; j++) g.set(i, j); System.out.print(g.toString()); } else if (config == 9) // Sets up configuration i { g.set(i-1, j+1); g.set(i-1, j+2); g.set(i-1, j+3); System.out.print(g.toString());
for (board[i][j] = " "; j <= 14; j++) { g.set(i, j); System.out.print(g.toString()); } g.countNeighbors(board, i, j); g.nextGen(board); System.out.print(g.toString()); } else if (config == 10) // Sets up configuration j { g.set(i-1, j); g.set(i-1, j+2); g.set(i+1, j); g.set(i+1, j+2); System.out.print(g.toString());
for (board[i][j] = " "; j <= 14; j++) { g.set(i, j); System.out.print(g.toString()); } g.countNeighbors(board, i, j); g.nextGen(board); System.out.print(g.toString()); } else if (config == 11) // Sets up configuration k { g.set(i-2, j); g.set(i-1, j); g.set(i-2, j+2); g.set(i-1, j+2); System.out.print(g.toString());
for (board[i][j] = " "; j <= 14; j++) { g.set(i, j); System.out.print(g.toString()); } g.countNeighbors(board, i, j); g.nextGen(board); System.out.print(g.toString()); } else if (config == 12) // Sets up configuration l { g.set(i-1, j); g.set(i-1, j+1); g.set(i+1, j+2); g.set(i+1, j+3); g.set(i+2, j+2); g.set(i+2, j+3); System.out.print(g.toString());
for (board[i][j] = " "; j <= 13; j++) { g.set(i, j); System.out.print(g.toString()); } g.countNeighbors(board, i, j); g.nextGen(board); System.out.print(g.toString()); } } }
CPSCmajor - 24 Nov 2005 00:59 GMT anyone have any ideas?? thanks.
> Hey all, > I got rid of the out of bounds exception, and now the rest of the [quoted text clipped - 367 lines] > } > } hicks@bigmailbox.net - 24 Nov 2005 11:10 GMT > anyone have any ideas?? thanks. > [quoted text clipped - 3 lines] > > configuration and then make it disappear. I don't know what else to try > > to fix it. Any ideas? This logic is wrong
for (board[i][j] = " "; j <= 15; j++) { g.set(i, j); System.out.print(g.toString()); } g.countNeighbors(board, i, j);
Why are you calling countNeighbors() at this point? Wouldn't it make more sense to call this in the nextGen() method, where you're iterating over the entire board? Basically, in the nextGen() method, every time you go through the following loop, neighbors == 0.
... for (int y = 0; y < currentBoard[x].length; y++) { int n = neighbors; ...
You need
... for (int y = 0; y < currentBoard[x].length; y++) { countNeighbors(currentBoard, x, y); int n = neighbors; ...
Patrick May - 24 Nov 2005 11:41 GMT > anyone have any ideas?? thanks. My first idea is to ask you to please stop top posting. ;-)
> I got rid of the out of bounds exception, and now the rest of the > program doesn't work :( ! All that it will do is display the initial > configuration and then make it disappear. I don't know what else to > try to fix it. Any ideas? [ . . . ]
> public static void main(String[] args) > { [quoted text clipped - 18 lines] > System.out.print(g.nextGen(board)); > System.out.print(g.toString()); [ . . . ]
> } [ . . . ]
The good news is that your code is behaving exactly as it should. The bad news is that the behavior is not what you _want_. If you look carefully at the snippet I've quoted, you are:
1. setting up a board configuration 2. printing it 3. counting the number of neighbors forsome reason 4. printing the next generation 5. printing the board again 6. stopping
Presumably you want to do something like:
1. set board configuration 2. loop some number of times while 2a. printing the board 2b. updating the board 3. stop
Does that help?
One other note: Your for loops will be more understandable if you initialize the increment counter within the loop, e.g.:
for (j = 12;j <= 15;j++)
Regards,
Patrick
------------------------------------------------------------------------ S P Engineering, Inc. | The experts in large scale distributed OO | systems design and implementation. pjm@spe.com | (C++, Java, Common Lisp, Jini, CORBA, UML)
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|