-
help help, ... :) "game of life",
i had a home work about whats called "Game of Life"
i had to write 4 functions as i did below:
function 1:
Code:
public static boolean isInside(boolean[][] cells, int x, int y) {
if ((cells.length < x) && (cells[0].length < y))
return false;
return true;
}
function 2:
Code:
public static boolean checkCell(boolean[][] cells, int x, int y) {
if (cells[x][y] == true)
return true;
return false;
}
function 3:
Code:
public static int numberOfNeighbors(boolean[][] cells,int x,int y) {
int count=0,j=0,i=1,marker=0;
if (isInside(cells,i,j))
{
while (marker < 3)
{
if ((checkCell(cells,x+j,y)) && (cells[x+j][y] != cells[x][y]))
count++;
if (checkCell(cells,x+j,y+i))
count++;
if (checkCell(cells,x+j,y-i))
count++;
j=1;
if (marker == 2)
j=-1;
marker++;
}
}
return count;
}
and the important function 4:
Code:
public static boolean[][] nextGeneration(boolean[][] cells) {
for (int i=0;i<cells.length;i++)
for (int j=0;j<cells[0].length;j++)
if (isInside(cells,i,j))
{
if (numberOfNeighbors(cells,i,j) == 3)
{
cells[i][j] = true;
}
if ((checkCell(cells,i,j)) && ((numberOfNeighbors(cells,i,j) == 3) || (numberOfNeighbors(cells,i,j) == 2)))
{
cells[i][j] = true;
}
else
{
cells[i][j] = false;
}
}
return cells;
}
,
,
i have to save this file and copy the *.class file to a directory with the prepared files:
GameOfLife.html,CellSpace.class,GameOfLife.class.
the problem is when i copy the file and i run the GameOfLife.html.
which opens this window:
http://www.ariel.ac.il/cs/pf/bmboaz/...ameOfLife.html
and works just above.
but when i put on 3 squares and press "start"
the error i get is:
Code:
Exception in thread "Thread-11" java.lang.ArrayIndexOutOfBoundsException: -1
at NextGeneration.checkCell(NextGeneration.java:19)
at NextGeneration.numberOfNeighbors(NextGeneration.java:38)
at NextGeneration.nextGeneration(NextGeneration.java:60)
at CellSpace.next(CellSpace.java:102)
at GameOfLife.run(GameOfLife.java:96)
at java.lang.Thread.run(Unknown Source)
line 19 = if (cells[x][y] == true)
line 38 = if (checkCell(cells,x+j,y-i))
line 60 = if (numberOfNeighbors(cells,i,j) == 3)
-
Re: help help, ... :) "game of life",
Congratulations on writing a well thought out post.
The exception message says the array index is out of bounds and shows it's actual value is -1. Therefore, the value for either x or y passed into the checkCell() method is incorrect. BTW What is the purpose of this method, as the array already contains boolean values the method does nothing useful - you could just as easily replace the call to this method with cells[x][y]
The best approach to solve your problem is to work through your code in the numberOfNeighbours() method using a pen and paper to note down the values of i, j, x & y at each line of code.
I haven't really looked at the code (no time) but the normal problem associated with this sort of search is what happens when the cell you are looking at is at the edge of the grid ie it has no neighbours on one side (or on two sides if it's in a corner).
-
Re: help help, ... :) "game of life",
Quote:
Originally Posted by
sanfor
i had a home work about whats called "Game of Life"
This wouldn't happen to be for Andre's class would it? ;) This used to be an old favorite assignment he would give every other semester.
Code:
public static boolean checkCell(boolean[][] cells, int x, int y) {
if (cells[x][y] == true)
return true;
return false;
}
Just a piece of advice on this function: cells[x][y] IS a boolean value, there is no need to check it against true. The check is a.) redundant and b.) should be (true == cells[x][y]) anyway so that you don't accidentially use a single = and assign it the value instead of checking it.
Quote:
Originally Posted by
sanfor
Code:
while (marker < 3)
{
if ((checkCell(cells,x+j,y)) && (cells[x+j][y] != cells[x][y]))
count++;
if (checkCell(cells,x+j,y+i))
count++;
if (checkCell(cells,x+j,y-i))
count++;
j=1;
if (marker == 2)
j=-1;
marker++;
}
Code:
public static boolean[][] nextGeneration(boolean[][] cells) {
for (int i=0;i<cells.length;i++)
for (int j=0;j<cells[0].length;j++)
if (isInside(cells,i,j))
{
if (numberOfNeighbors(cells,i,j) == 3)
{
cells[i][j] = true;
}
if ((checkCell(cells,i,j)) && ((numberOfNeighbors(cells,i,j) == 3) || (numberOfNeighbors(cells,i,j) == 2)))
{
cells[i][j] = true;
}
else
{
cells[i][j] = false;
}
}
return cells;
}
,
line 19 = if (cells[x][y] == true)
line 38 = if (checkCell(cells,x+j,y-i))
line 60 = if (numberOfNeighbors(cells,i,j) == 3)
Your problem most likely is happening when you reach the end of the array. What you are doing is calling numberOfNeighbors() when i and j are at the last element of the array. However, if you notice in your while loop you are calling check cell on X+J and just below your IF statements you make J = 1. The next time you call checkCell on X+1 you have now gone past the array length.
-
Re: help help, ... :) "game of life",
There is a problem with your isInside function.
In order to verify that an index is inside the bounds of an array, it should be both smaller than the length of the array, and larger than 0. Notice that the error was about an index of -1.
In other words - the index should be after the start and before the end of the array.
Also notice that you put wrong conditionals. All conditions should be OR'ed together because it is sufficient that the index should be out of bounds in one direction, and not all of them together, to have the index outside of the array.
Imagine a box that in order to get out of it, you can be above it, or in front of it, but you do not have to be both above it and in front of it.
Your condition should look something like this:
Code:
public static boolean isInside(boolean[][] cells, int x, int y) {
if ((cells.length < x) || (x < 0) || (cells[0].length < y) || (y < 0))
return false;
return true;
}
If you want to AND conditions together, you should check if the index is inside all of the boundaries, instead of check if it outside at least one of the boundaries.
This will not solve your problem, because you are still trying to access a place out side of the array, but now this error will be caught in the right place.
Can you post where you tried to access that array?
-
Re: help help, ... :) "game of life",
Quote:
Originally Posted by
guyafe
................
Your condition should look something like this:
Code:
public static boolean isInside(boolean[][] cells, int x, int y) {
if ((cells.length < x) || (x < 0) || (cells[0].length < y) || (y < 0))
return false;
return true;
}
.........
Can you post where you tried to access that array?
i got your point :) 1 outbound enough to get error.
i corrected it
-
Re: help help, ... :) "game of life",
Quote:
Originally Posted by
guyafe
There is a problem with your
isInside function.
In order to verify that an index is inside the bounds of an array, it should be both smaller than the length of the array,
and larger than 0. Notice that the error was about an index of -1.
In other words - the index should be after the start and before the end of the array.
Also notice that you put wrong conditionals. All conditions should be OR'ed together because it is sufficient that the index should be out of bounds in one direction, and not all of them together, to have the index outside of the array.
Imagine a box that in order to get out of it, you can be above it,
or in front of it, but you do not have to be both above it
and in front of it.
Your condition should look something like this:
Code:
public static boolean isInside(boolean[][] cells, int x, int y) {
if ((cells.length < x) || (x < 0) || (cells[0].length < y) || (y < 0))
return false;
return true;
}
If you want to AND conditions together, you should check if the index is
inside all of the boundaries, instead of check if it
outside at least one of the boundaries.
This
will not solve your problem, because you are still trying to access a place out side of the array, but now this error will be caught in the right place.
Can you post where you tried to access that array?
Quote:
Originally Posted by
ProgramThis
This wouldn't happen to be for Andre's class would it? ;) This used to be an old favorite assignment he would give every other semester.
Code:
public static boolean checkCell(boolean[][] cells, int x, int y) {
if (cells[x][y] == true)
return true;
return false;
}
Just a piece of advice on this function: cells[x][y] IS a boolean value, there is no need to check it against
true. The check is a.) redundant and b.) should be (true == cells[x][y]) anyway so that you don't accidentially use a single = and assign it the value instead of checking it.
Your problem most likely is happening when you reach the end of the array. What you are doing is calling numberOfNeighbors() when i and j are at the last element of the array. However, if you notice in your while loop you are calling check cell on X+J and just below your IF statements you make J = 1. The next time you call checkCell on X+1 you have now gone past the array length.
Quote:
Originally Posted by
keang
Congratulations on writing a well thought out post.
The exception message says the array index is out of bounds and shows it's actual value is -1. Therefore, the value for either x or y passed into the checkCell() method is incorrect. BTW What is the purpose of this method, as the array already contains boolean values the method does nothing useful - you could just as easily replace the call to this method with cells[x][y]
The best approach to solve your problem is to work through your code in the numberOfNeighbours() method using a pen and paper to note down the values of i, j, x & y at each line of code.
I haven't really looked at the code (no time) but the normal problem associated with this sort of search is what happens when the cell you are looking at is at the edge of the grid ie it has no neighbours on one side (or on two sides if it's in a corner).
,
,
,
,
thanks guys
i see all of you say that i have the same problem with .. the -1
someone told me to do this:
before:
Code:
public static boolean checkCell(boolean[][] cells, int x, int y) {
if (cells[x][y] == true)
return true;
return false;
}
after:
Code:
public static boolean checkCell(boolean[][] cells, int x, int y) {
if (isInside(cells,x,y))
{
if (cells[x][y] == true)
return true;
}
return false;
}
-
Re: help help, ... :) "game of life",
Yap, but you can also narrow it to the following:
Code:
public static boolean checkCell(boolean[][] cells, int x, int y) {
return isInside(cells, x, y) && cells[x][y];
}
If isInside will return false, Java wouldn't check the following conditions, so you wouldn't get any exception. Next cells[x][y] is a boolean variable, and the result of the entire statement is boolean, so you can just return it.
You don't have to check if something is true and then return true. You can just return that something.
-
Re: help help, ... :) "game of life",
Quote:
Originally Posted by
ProgramThis
This wouldn't happen to be for Andre's class would it? ;) This used to be an old favorite assignment he would give every other semester.
Code:
public static boolean checkCell(boolean[][] cells, int x, int y) {
if (cells[x][y] == true)
return true;
return false;
}
Just a piece of advice on this function: cells[x][y] IS a boolean value, there is no need to check it against
true. The check is a.) redundant and b.) should be (true == cells[x][y]) anyway so that you don't accidentially use a single = and assign it the value instead of checking it.
Your problem most likely is happening when you reach the end of the array. What you are doing is calling numberOfNeighbors() when i and j are at the last element of the array. However, if you notice in your while loop you are calling check cell on X+J and just below your IF statements you make J = 1. The next time you call checkCell on X+1 you have now gone past the array length.
look at this for exampe:
http://i50.tinypic.com/2efkokl.jpg
when i start with
CELL[2][2]
it works
-
Re: help help, ... :) "game of life",
see guys
the problem keeps coming from the "checkcell" or "the calling for checkcell"
after i changed few things:
Code:
public class NextGeneration {
public static void main(String[] args) {
}
Code:
public static boolean isInside(boolean[][] cells, int x, int y) {
if ((cells.length < x) || (x < 0) || (cells[0].length < y) || (y < 0))
return false;
return true;
}
Code:
public static boolean checkCell(boolean[][] cells, int x, int y) {
return isInside(cells, x, y) && cells[x][y];
}
Code:
public static int numberOfNeighbors(boolean[][] cells,int x,int y) {
int count=0,j=0,i=1,marker=0;
while (marker < 3)
{
if ((checkCell(cells,x+j,y)) && (cells[x+j][y] != cells[x][y]))
count++;
if (checkCell(cells,x+j,y+i))
count++;
if (checkCell(cells,x+j,y-i))
count++;
j=1;
if (marker == 2)
j=-1;
marker++;
}
return count;
}
Code:
public static boolean[][] nextGeneration(boolean[][] cells) {
for (int i=0;i<cells.length;i++)
for (int j=0;j<cells[0].length;j++)
if (isInside(cells,i,j))
{
if (numberOfNeighbors(cells,i,j) == 3)
{
cells[i][j] = true;
}
if ((checkCell(cells,i,j)) && ((numberOfNeighbors(cells,i,j) == 3) || (numberOfNeighbors(cells,i,j) == 2)))
{
cells[i][j] = true;
}
else
{
cells[i][j] = false;
}
}
return cells;
}
}
now i get:
Code:
Exception in thread "Thread-10" java.lang.ArrayIndexOutOfBoundsException: 25
at NextGeneration.checkCell(NextGeneration.java:19)
at NextGeneration.numberOfNeighbors(NextGeneration.java:31)
at NextGeneration.nextGeneration(NextGeneration.java:55)
at CellSpace.next(CellSpace.java:102)
at GameOfLife.run(GameOfLife.java:96)
at java.lang.Thread.run(Unknown Source)
i start to get frustrated
-
Re: help help, ... :) "game of life",
Quote:
Originally Posted by
sanfor
see guys
the problem keeps coming from the "checkcell" or "the calling for checkcell"
Code:
Exception in thread "Thread-10" java.lang.ArrayIndexOutOfBoundsException: 25
at NextGeneration.checkCell(NextGeneration.java:19)
at NextGeneration.numberOfNeighbors(NextGeneration.java:31)
at NextGeneration.nextGeneration(NextGeneration.java:55)
at CellSpace.next(CellSpace.java:102)
at GameOfLife.run(GameOfLife.java:96)
at java.lang.Thread.run(Unknown Source)
i start to get frustrated
What is the length of your array? Is it 24 by chance? Like I said, you are doing a j = 1 in numberOfNeighbors, and then calling checkCell on (x+j,y). When you do this and you are checking the last row of the array you are going to go out of bounds.
-
Re: help help, ... :) "game of life",
i finally got it
no more eerrors with the function i did
i had to change:
Code:
if ((cells.length < x) || (x < 0) || (cells[0].length < y) || (y < 0))
to
Code:
if ((cells.length <= x) || (x < 0) || (cells[0].length <= y) || (y < 0))
-
Re: help help, ... :) "game of life",
Of course!
I embarrassed that I missed it :)
In Java (And in any other discent programming language) arrays are indexed from 0 to (length - 1), So array[length of array] is the first reference that is out of bounds.
-
Re: help help, ... :) "game of life",
so far i am doing just great..
i don't have errors.. scripts works fine
but i have a small problem
look..
instead of running in with java applet and stuff
i created array from the main function.. to test it first in "eclipse" .. much easier
and to let you understand itmore :)
the code works alright
but when i enter:
Code:
cell[1][2] = true;
cell[1][1] = true;
cell[1][0] = true;
and print it through the main function:
Code:
false false false false false
false false false false false
false false false false false
true true true false false
false false false false false
and when i run the
Code:
cell = nextGeneration(cell);
i get this:
Code:
false false false false false
false false false false false
false (true) false false false
false false false false false
false (true) false false false
which is wrong, why?
because i have to get it like this:
Code:
false false false false false
false false false false false
false (true) false false false
false (true) false false false
false (true) false false false
public class NextGeneration {
Code:
public static void main(String[] args) {
boolean[][] cell = new boolean[5][5];
for (int i=0;i<cell.length;i++)
for (int j=0;j<cell[0].length;j++)
cell[i][j] = false;
cell[1][2] = true;
cell[1][1] = true;
cell[1][0] = true;
for (int i=cell.length-1;i>=0;i--)
{
for (int j=0;j<cell[0].length;j++)
{
System.out.print(cell[i][j]+" ");
}
System.out.println();
}
System.out.println(numberOfNeighbors(cell,1,1)+" "+ checkCell(cell,1,1));
cell = nextGeneration(cell);
for (int i=cell.length-1;i>=0;i--)
{
for (int j=0;j<cell[0].length;j++)
{
System.out.print(cell[i][j]+" ");
}
System.out.println();
}
}
Code:
public static boolean isInside(boolean[][] cells, int x, int y) {
if ((cells.length <= x) || (x < 0) || (cells[0].length <= y) || (y < 0))
return false;
return true;
}
Code:
public static boolean checkCell(boolean[][] cells, int x, int y) {
return isInside(cells, x, y) && cells[x][y];
}
Code:
public static int numberOfNeighbors(boolean[][] cells,int x,int y) {
int count=0,j=0,i=1,marker=0;
while (marker < 3)
{
if ((checkCell(cells,x+j,y)) && (cells[x+j][y] != cells[x][y]))
count++;
if (checkCell(cells,x+j,y+i))
count++;
if (checkCell(cells,x+j,y-i))
count++;
j=1;
marker++;
if (marker == 2)
j=-1;
}
return count;
}
Code:
public static boolean[][] nextGeneration(boolean[][] cells) {
boolean[][] cell = new boolean[cells.length][cells[0].length];
for (int i=0;i<cells.length;i++)
for (int j=0;j<cells[0].length;j++)
cell[i][j] = false;
for (int i=0;i<cells.length;i++)
for (int j=0;j<cells[0].length;j++)
{
if ((checkCell(cells,i,j)) && (numberOfNeighbors(cells,i,j) > 2))
{
cell[i][j] = true;
}
if (numberOfNeighbors(cells,i,j) == 3)
{
cell[i][j] = true;
}
else
{
cell[i][j] = false;
}
}
return cell;
}
}
-
Re: help help, ... :) "game of life",
Why not? It works well.
In order for a cell to survive, it must have more than 2 neighbours.
Cell [1][1] has only 2: One at the right and one at the left, so it dies, according to your rules.
As I recall, in the game of life, 2 neighbours are enough for a cell to survive, so you should cahnge your >2 to >=2.
Few more things:
Use documentation. I usually write a remark for each line. You can't imagine how helpful this is.
Keep consistent with your variables: In main function i is used for rows and j is used for columns, and in numberOfNeighbours it is the other way around. It makes your code confusing.
Using redable naming is much better. Instead of i and j use row and column. Variables' names should be long and understandable.
Inside nextGeneration there is an array named cells and an array named cell. This is very confusing. Use names such as oldCells and newCells.
Your numberOfNeighbours function is a bit cumbersome. Try something like this:
Code:
public static boolean[][] numberOfNeighbours(boolean[][] cells, int x, int y){
int numberOfNeighbours = -1; //This is because we will count the current cell as a neighbour, so we should start from -1
//looping over all cells arround current
for(int deltaX = -1 ; deltaX <= 1 ; deltaX++){ //We are starting from one row above, moving to current row and then to the row below
for(int deltaY = -1 ; deltaY <= 1 ; deltaY++){ //We are starting from one column to the left, moving to furren and then to the right
if isInside(cells, x + deltaX, y + deltaY) && cells[x + deltaX][y + deltaY]{
numberOfNeighbours++; //Adding one to the number of neighbours if the neighbour is alive. We WILL check the index [0][0] and obviously get true. This is the reason we started the counting from -1.
}
}
}
return numberOfNeighbours; //returning the result
}
Your code should be understandable and readable. The key word here is KISS (Keep It Simple Stupid).
Always try to program the same way you think. Your mind is much clearer than any programming language, so always first think "Hmmm, how would I count the neighbours?" You will get to the conclusion that it is the simplest to just move around the cell. Now it is easy to program such loop.
-
Re: help help, ... :) "game of life",
no man
the rules are:
1. live cell - stays alive if it has 2 or 3 LIVE neighbors
2. dead cell - becomes alive if it has "exactly" 3 live neighbors.
3. else it stays "dead" or becomes "dead"
,
and i have to change
Code:
if ((checkCell(cells,i,j)) && (numberOfNeighbors(cells,i,j) >= 2))
to
Code:
if ((checkCell(cells,i,j)) && ((numberOfNeighbors(cells,i,j) == 2) || (numberOfNeighbors(cells,i,j) == 3)))
,
,
and about the "i and j" in the main function and in "the nextgeneration" function..
i t's the oppositte because in the function it has to start [0][0] from the bottom left
but i changed it inthe main so it can be printed as the "board in the html accept"
(just to see it before uploading the file to the folder of the .html file)
(i hope you got me)
,
,
rows and columns yeah.. ihave to pick easier names for the variables.
,
i am gonna gfive it a try
then i will check your numberOfNeighbors... function