|
bholzer
quasi-scientist



Registered: 03/22/11
Posts: 2,409
Last seen: 11 years, 11 months
|
Can't get this java code to work!!
#15146834 - 09/28/11 12:15 PM (12 years, 7 months ago) |
|
|
I'm working on a classic game of life program. I feel like I have a decent scaffold of a program, but I can't solve one issue. In the life method, there is a series of if statements that checks the contents of the array around the current position. The issue is that when the current position is an edge or corner, the program tries to refer to an out-of-bound element. Any ideas?
Code:
public class Life { public static void visualize(boolean[][] isLive, int count) { while (count > 0) { int N = isLive.length; StdDraw.setXscale(-1, N); StdDraw.setYscale(-1, N); for(int i = 0;i < N; i++) for(int j = 0; j < N; j++) { if (isLive[i][j]) { StdDraw.setPenColor(StdDraw.BLUE); StdDraw.filledSquare(j, N-i-1, .4); } else { StdDraw.setPenColor(StdDraw.BLACK); StdDraw.filledSquare(j, N -i-1, .4); } } StdDraw.show(1000); StdOut.println("This line is reached"); visualize(life(isLive, isLive.length), count-1); } } public static boolean[][] life(boolean[][] isLive, int N) { int livecount = 0; for (int t = 0; t < N; t++) for (int j = 0; j < N; j++) { if (isLive[t][j] == true) { if (isLive[t][j+1]==true) livecount ++; if (isLive[t][j-1]==true) livecount ++; if (isLive[t+1][j+1]==true) livecount ++; if (isLive[t-1][j+1]==true) livecount ++; if (isLive[t-1][j-1]==true) livecount ++; if (isLive[t+1][j]==true) livecount ++; if (isLive[t-1][j]==true) livecount ++; if (isLive[t+1][j-1]==true) livecount ++; if (livecount == 1) isLive[t][j] = false; if (livecount > 3) isLive[t][j] = false; livecount = 0; } else { if (isLive[t][j+1]==true) livecount ++; if (isLive[t][j-1]==true) livecount ++; if (isLive[t+1][j+1]==true) livecount ++; if (isLive[t-1][j+1]==true) livecount ++; if (isLive[t-1][j-1]==true) livecount ++; if (isLive[t+1][j]==true) livecount ++; if (isLive[t-1][j]==true) livecount ++; if (isLive[t+1][j-1]==true) livecount ++; if (livecount == 3) isLive[t][j] = true; livecount = 0; } } return isLive; } public static boolean [][] random(int N, double p) { boolean[][] a = new boolean[N][N]; for(int i = 0;i < N; i++) for(int j = 0; j < N; j++) a[i][j] = StdRandom.bernoulli(p); return a; }
public static void main(String[] args) { int count = Integer.parseInt(args[2]);//number of steps int N = Integer.parseInt(args[0]); //Size of grid double p = Double.parseDouble(args[1]); //probability that cell is live boolean[][] isLive = random(N, p); StdArrayIO.print(isLive); visualize(isLive, count); } }
--------------------
Use these substances wisely, they have the ability to cause life altering realizations.
|
koraks
Registered: 06/02/03
Posts: 26,729
|
Re: Can't get this java code to work!! [Re: bholzer]
#15147216 - 09/28/11 01:58 PM (12 years, 7 months ago) |
|
|
On what line does the error occur?
|
bholzer
quasi-scientist



Registered: 03/22/11
Posts: 2,409
Last seen: 11 years, 11 months
|
Re: Can't get this java code to work!! [Re: koraks]
#15147455 - 09/28/11 02:43 PM (12 years, 7 months ago) |
|
|
Quote:
koraks said: On what line does the error occur?
Sorry, should have been more specific. It occurs on the life method in the "if (isLive[t][j-1]==true) livecount ++;" statement.
Since it starts in the [0,0] index, it can't test the [t][j-1] because the j-1 is -1. Does that make sense? I don't explain code very well >.<
--------------------
Use these substances wisely, they have the ability to cause life altering realizations.
|
koraks
Registered: 06/02/03
Posts: 26,729
|
Re: Can't get this java code to work!! [Re: bholzer]
#15150935 - 09/29/11 01:34 AM (12 years, 7 months ago) |
|
|
Yes, that's a likely problem. You'll need to ensure first that j>0.
|
Seuss
Error: divide byzero



Registered: 04/27/01
Posts: 23,480
Loc: Caribbean
Last seen: 3 months, 8 days
|
Re: Can't get this java code to work!! [Re: bholzer]
#15151223 - 09/29/11 04:45 AM (12 years, 7 months ago) |
|
|
Change: "if (isLive[t][j-1]==true) livecount ++;"
to
if (j>0 && isLive[t][j-1]==true) livecount++;
-------------------- Just another spore in the wind.
|
koraks
Registered: 06/02/03
Posts: 26,729
|
Re: Can't get this java code to work!! [Re: Seuss]
#15151271 - 09/29/11 05:15 AM (12 years, 7 months ago) |
|
|
Might as well fix the same problem for t=0 as well, since you also check the t-1 position in the array once or twice.
|
Seuss
Error: divide byzero



Registered: 04/27/01
Posts: 23,480
Loc: Caribbean
Last seen: 3 months, 8 days
|
Re: Can't get this java code to work!! [Re: koraks]
#15151304 - 09/29/11 05:48 AM (12 years, 7 months ago) |
|
|
> Might as well fix the same problem for t=0 as well, since you also check the t-1 position in the array once or twice.
True. Personally, for efficiency, I would check the edge case (j=0, t=0) once, then loop through the remaining cases without the conditional (j>0 && t>0). If your array is small, it wouldn't really matter, but if your array is massive (or if you call this function a lot), removing a conditional that is unused 99.999% of the time can make a big difference in performance.
-------------------- Just another spore in the wind.
|
koraks
Registered: 06/02/03
Posts: 26,729
|
Re: Can't get this java code to work!! [Re: Seuss]
#15151448 - 09/29/11 07:09 AM (12 years, 7 months ago) |
|
|
that's right! Especially in Java, which is as slow as cart&horse to begin with.
|
bholzer
quasi-scientist



Registered: 03/22/11
Posts: 2,409
Last seen: 11 years, 11 months
|
Re: Can't get this java code to work!! [Re: koraks]
#15152001 - 09/29/11 09:55 AM (12 years, 7 months ago) |
|
|
Thanks a lot, you guys are awesome
--------------------
Use these substances wisely, they have the ability to cause life altering realizations.
|
bholzer
quasi-scientist



Registered: 03/22/11
Posts: 2,409
Last seen: 11 years, 11 months
|
Re: Can't get this java code to work!! [Re: bholzer]
#15154113 - 09/29/11 05:10 PM (12 years, 7 months ago) |
|
|
Okay guys, ran into another problem with the same code. The errors are now gone, but i'm having an issue with WHEN the current position is changed.
Let me explain. As the program moves through the array, it changes the booleans based on the elements around it. What needs to happen is the array needs to be evaluated and THEN the values need to be changed, but right now the values are changing in realtime. So say a value changes, when I get to the row below it, the current position is evaluated based on the changed value's NEW value, not the old. Here is the new code that you guys so graciously helped me with Sorry if my explanation is confusing! Code:
public static boolean[][] life(boolean[][] isLive, int N) { int livecount = 0; for (int t = 0; t < N; t++) for (int j = 0; j < N; j++) { if (isLive[t][j] == false) { if (j < N-1 && isLive[t][j+1]==true) livecount ++; if (j > 0 && isLive[t][j-1]==true) livecount ++; if (j < N-1 && t < N-1 && isLive[t+1][j+1]==true) livecount ++; if (j < N-1 && t > 0 && isLive[t-1][j+1]==true) livecount ++; if (j > 0 && t > 0 && isLive[t-1][j-1]==true) livecount ++; if (t < N-1 && isLive[t+1][j]==true) livecount ++; if (t > 0 && isLive[t-1][j]==true) livecount ++; if (t < N-1 && j > 0 && isLive[t+1][j-1]==true) livecount ++; if (livecount == 3) isLive[t][j] = true; StdOut.println(livecount); livecount = 0; } else { if (j < N-1 && isLive[t][j+1]==true) livecount ++; if (j > 0 && isLive[t][j-1]==true) livecount ++; if (j < N-1 && t < N-1 && isLive[t+1][j+1]==true) livecount ++; if (j < N-1 && t > 0 && isLive[t-1][j+1]==true) livecount ++; if (j > 0 && t > 0 && isLive[t-1][j-1]==true) livecount ++; if (t < N-1 && isLive[t+1][j]==true) livecount ++; if (t > 0 && isLive[t-1][j]==true) livecount ++; if (t < N-1 && j > 0 && isLive[t+1][j-1]==true) livecount ++; if (livecount == 1) isLive[t][j] = false; if (livecount > 3) isLive[t][j] = false; StdOut.println(livecount); livecount = 0; } } return isLive; }
--------------------
Use these substances wisely, they have the ability to cause life altering realizations.
|
Seuss
Error: divide byzero



Registered: 04/27/01
Posts: 23,480
Loc: Caribbean
Last seen: 3 months, 8 days
|
Re: Can't get this java code to work!! [Re: bholzer]
#15155062 - 09/29/11 08:29 PM (12 years, 7 months ago) |
|
|
I would copy the current array to a temp array, then loop to recalculate the current array using the data from the temp array. Finally, dispose of the temp array when done.
Optimally, if there is an ordering to the data, you can organize the data in such a way so that you don't need a temp array/copy as you iterate, but most likely this is not an option in your case.
|
bholzer
quasi-scientist



Registered: 03/22/11
Posts: 2,409
Last seen: 11 years, 11 months
|
Re: Can't get this java code to work!! [Re: Seuss]
#15155104 - 09/29/11 08:36 PM (12 years, 7 months ago) |
|
|
Quote:
Seuss said: I would copy the current array to a temp array, then loop to recalculate the current array using the data from the temp array. Finally, dispose of the temp array when done.
Optimally, if there is an ordering to the data, you can organize the data in such a way so that you don't need a temp array/copy as you iterate, but most likely this is not an option in your case.
Perfect, great solution. So simple I don't know how I skipped it Thanks a lot man!
--------------------
Use these substances wisely, they have the ability to cause life altering realizations.
|
Seuss
Error: divide byzero



Registered: 04/27/01
Posts: 23,480
Loc: Caribbean
Last seen: 3 months, 8 days
|
Re: Can't get this java code to work!! [Re: bholzer]
#15156654 - 09/30/11 05:25 AM (12 years, 7 months ago) |
|
|
If you move the chunks of code that are identical within the loop invariant outside of the conditional, you will make it much easier to maintain and debug. I also added an extra brace around the embedded "for" statement. Although this is not needed, in my experience the missing brace often leads to faulty code. I often see this when somebody else modifies the block, adding additional statements with the embedded "for" statement, but they forget to add the braces.
Code:
public static boolean[][] life(boolean[][] isLive, int N) { int livecount = 0; for (int t = 0; t < N; t++) { for (int j = 0; j < N; j++) { if (j < N-1 && isLive[t][j+1]==true) livecount ++; if (j > 0 && isLive[t][j-1]==true) livecount ++; if (j < N-1 && t < N-1 && isLive[t+1][j+1]==true) livecount ++; if (j < N-1 && t > 0 && isLive[t-1][j+1]==true) livecount ++; if (j > 0 && t > 0 && isLive[t-1][j-1]==true) livecount ++; if (t < N-1 && isLive[t+1][j]==true) livecount ++; if (t > 0 && isLive[t-1][j]==true) livecount ++; if (t < N-1 && j > 0 && isLive[t+1][j-1]==true) livecount ++; if (isLive[t][j] == false) { if (livecount == 3) isLive[t][j] = true; } else { if (livecount == 1 || livecount > 3) isLive[t][j] = false; } StdOut.println(livecount); livecount = 0; } } return isLive; }
|
bholzer
quasi-scientist



Registered: 03/22/11
Posts: 2,409
Last seen: 11 years, 11 months
|
Re: Can't get this java code to work!! [Re: Seuss]
#15157348 - 09/30/11 10:25 AM (12 years, 7 months ago) |
|
|
Awesome suess, thanks a lot for that optimization!! With everyone's help, I finally have that class working perfectly, here it is in case anyone really cares:
Code:
public static boolean[][] life(boolean[][] isLive, int N) { int livecount = 0; boolean[][] temp = new boolean[isLive.length][isLive.length]; for(int i = 0; i < isLive.length; i++){ for(int j = 0; j < isLive.length; j++){ temp[i][j] = isLive[i][j]; } } for (int t = 0; t < N; t++) { for (int j = 0; j < N; j++) { if (j < N-1 && isLive[t][j+1]==true) livecount ++; if (j > 0 && isLive[t][j-1]==true) livecount ++; if (j < N-1 && t < N-1 && isLive[t+1][j+1]==true) livecount ++; if (j < N-1 && t > 0 && isLive[t-1][j+1]==true) livecount ++; if (j > 0 && t > 0 && isLive[t-1][j-1]==true) livecount ++; if (t < N-1 && isLive[t+1][j]==true) livecount ++; if (t > 0 && isLive[t-1][j]==true) livecount ++; if (t < N-1 && j > 0 && isLive[t+1][j-1]==true) livecount ++; if (isLive[t][j] == false) { if (livecount == 3) temp[t][j] = true; StdOut.println(livecount); livecount = 0; } else { if (livecount == 1 || livecount > 3) temp[t][j] = false; StdOut.println(livecount); livecount = 0; } } } return temp; }
--------------------
Use these substances wisely, they have the ability to cause life altering realizations.
|
|