# Algorithm problem (/w code)

joseph mcgratton
Ranch Hand
Posts: 41
hello,

im in the middle of making a program and have hit a strange problem which im sure you can me fix! :-)

-i have a grid of squares and a jbutton.
-when the button is pressed, a random number is made that decides the next step.
- step A - adjacent squares change color, direction down, or right.
- step B - adjacent squares change color, direction up, or left.

The number of squares to be changed is set at 3. Now here is the problem.
Option one, which carries out step A, works fine - 3 squares are changed color ( going up or right ). However, Option 2, which carries out step B, does not work properly. Although the code is 99% identical (the only change is the direction), only one adjacent square changes color (ie not three). here is the code to the relevant section (pls note there are no errors)..

any ideas? the only things i can think of is to rename arraylist, or "i", which i believe i have done, and has no effect.

thankyou,

joseph.
[ February 27, 2005: Message edited by: joseph mcgratton ]

joseph mcgratton
Ranch Hand
Posts: 41
hello

i have identified the problem as negative values. going up or left is a negative value ie grid[row][col-1]. but i dont see how this would limit the number of squares being changed to one.

joseph.

David Harkness
Ranch Hand
Posts: 1646
The four conditions in the if tests are going to fail under certain conditions:When col == NUM_COLS-1 (far right edge), grid[row][col + 1] will result in an ArrayIndexOutOfBoundsException. There are two ways around this:[list]Check for the edge before accessing the "next" cell:[/list]
• Expand the grid array on all four sides that will always fail tests but not throw exceptions. In other words, add a border around the entire grid and set each element to a color like Color.red (as long as you don't use red elsewhere)

• This assumes that you don't want to wrap around the edges. If you do, you can use the modulo operator (%) to get a wrapping effect. If you want wrapping and can't see how to use this operator, just ask.
[ February 27, 2005: Message edited by: David Harkness ]

joseph mcgratton
Ranch Hand
Posts: 41
hello,

thankyou for your reply. you mentioned about a border to stop outofbounds - i have already done this (colored black). i am completely baffled. if you look at both sets of code for the 2 options, they are identical, apart from the "+" or "-" sign. The prgram causes no exceptions. i have tested the options alot, such as fixing the grid so that they are not near edges. i have deleted the constraints. i have changed variable names. But the outcome is always the same - when grid[row+1][grid] or grid [row][col+1] the prgram runs properly and colors 3 squares. but when grid[row-1][col] or grid [row][col-1], the program only colors 1 square.

ill just have to leave it - it only means that "gray" can only go in 2 directions and not four.

thanks,

joseph

joseph mcgratton
Ranch Hand
Posts: 41
here is a quick example of what i mean. 0 = green square. X = origonal gray square. x = generated gray square.

option 1 (grid[row+1][col] or grid [row][col+1])

00000 00000
00X00 0X000
00x00 0xx00
00xx0 00x00
00000 00000

option 2 (grid[row-1][col] or grid [row][col-1])

00000 00000
0xX00 00000
00000 00x00
00000 00X00
00000 00000

As you see, option 2 only goes through 1 square.
[ February 27, 2005: Message edited by: joseph mcgratton ]

joseph mcgratton
Ranch Hand
Posts: 41
Could the problem be that when i go through the grid in a loop, it goes down and right (like option 1)? meaning that grid[row-1][col] etc cant be applied as it is the reverse of the origonal loop?

David Harkness
Ranch Hand
Posts: 1646
I still can't figure out exactly what this is supposed to do (I see what it does, but since it's not working as you'd like, it's hard to extrapolate the correct behavior). Can you describe it again in words?

However, I think your last comment is correct based on my assumption. Starting with only a single grey square, going up or left will only result in one square changing to grey because you are moving down and to the right in the two loops. For the second case, try switching the for loops around to go from max to 0.

You said you added a border to the grid, but since you are checking the array boundaries -- 0 and NUM_ROWS/COLS-1 -- you will still cause NPEs, unless I'm missing something. What I meant by using a border would be increasing the array dimensions by two for both rows and columns. Then, to check the top row, you'd use row = 1, not row = 0. Are we talking about the same thing?

joseph mcgratton
Ranch Hand
Posts: 41
hello,

i will try to explain the program area in question by giving a testing scenario.

1) there is a 10x10 grid.
2) the outer squares (eg grid[0][0] >>> grid[0][9] etc are black. is beacuse i cant fix the Arrayoutofbounds exceptions.
3) this black border prevents outofbounds if i use color.black constraints.
4) one of the middle squares is gray. (it is the current square)
5) a jButton initiates a random number ( 1 or 2).
6) if the random number is one, a square below or to the right of that gray square becomes gray.
7) the square that became gray is now the current square.
8) a square below or to the right of the current square becomes gray.
9) 6, 7, 8 repeats until the "maximum is met". This maximum is decided by "i".

All these steps work as planned if i = 3, 3 new gray squares are made. if i = 4, 4 new gray squares are made.

however, if the random number generated (step 5) is two, the process repeats, but this time the directions are either up or left. Think of it as pathing. But with option 2, "i" does not seem to work. By this i mean that only 1 square ever turns gray. So if i = 3, 1 new gray square is made. if i = 4, 1 new gray square is made.

joseph
[ February 27, 2005: Message edited by: joseph mcgratton ]

David Harkness
Ranch Hand
Posts: 1646
Okay, from your description then the guess I made and you pointed out is correct. When going up or to the left, you're setting a new square to grey that has already been passed up for checking. Think of the case of a single row:The loop looks at and ignores the first five elements since they are not grey. Then when looking at the X element, the element to the left is set to gray:Now the loop continues looking at the 0s to the right of the X, never finding the new grey element x.

You really only have one option here. Instead of looping over the entire grid, loop over the number of elements that should be turned grey. At each step of the loop you have a "current square" and choose the next square to turn grey. In doing so, set that new square to the current square and loop again.Of course you could change that into a for loop easily. You'll need to make sure you don't walk into the boundary (when at far-left column, you can only go up, or maybe you stop walking?). Is that clear? I can explain more if not.

joseph mcgratton
Ranch Hand
Posts: 41
hello,

thankyou for your help tonight. I understand the method and see how it works. One problem is that the "gray" square is randomly generated, and not always in trhe same spot, but this would be eady enough to convert to the current location. What i will do is have a look at your method and see what i can do. If it works fine which it should, then ill use that. Another way to go about this is to add something like grid[row-2][col] (concentrating more on moving down) to the array list. Then making a 3rd option that uses grid[row][col-2](concentrating on moving right.
Overall though i think your way would be better, as my way could leave "gaps" (which is why i thought of an extra option to help reduce gaps).

thanks again, we (you :-) )got there in the end,

joseph

David Harkness
Ranch Hand
Posts: 1646
To find the starting square, you can either make a note of it when picking one at random to set grey or run through your double loop to find the square. The first way would be easier I think, but it depends on how you have the other classes put together.

I probably have a few years of experience on you, so don't worry. After a while you'll get used to thinking of different ways to approach a problem. How I typically approach a problem like this is to visualize it as if I were in the system walking around touching objects and think how I'd go about it. If I know I can take three "steps," I look at making a loop out of it and tracking where I'm at for each step.

joseph mcgratton
Ranch Hand
Posts: 41
hello,

just to let you know that i have got it working now as i want it to. thanks again. I do have another query though (you'd never guess id ask you a question lol). A week ago you mentioned you would show me how to create a grid of JTextAreas using a loop (so i dont have to type out many lines that could slow the program). Well that has been todays task and i am finding it complicated.
As far as i can see, i use a nested loop to go through the grid which has been previously defined. if the grid[row][col] being checked is empty, then a reference of a JTextArea is added. However, im not sure how to use the loop to set dimensions or XYConstraints, and also to create it in a specfic JPanel. I managed earlier to get some code with no errors that supposedly created JTextAreas in a grid yet nothing happend. Everything seems to boil down to manually creating the JTextAreas and constraints ( i gave up after 200 as the computer froze - jbuilder was using 486mb ram ).
its quite frustrating as i have alot of algorithms working in a smaller grid, but i need bigger grids ( 8x8 is not suffice ). Are you able to explain to me how i would go about this? Please note that i have looked up 2 books on such things as layouts, and am currently at the sun website on layout managers, but they only show simplistic areas like arranging 6 different size objects in a frame, which i can do. I have also been looking up TicTacTie, Chess and Battleships source code.
Basically there are two swing containers (JPanels - West and East) and i would like West filled with 20x20 grid of JTextAreas. (West is actually a JPanel within a ScrollPanel. Maybe you detail the basics, then i have a go to see what i can do , then any problems i post code? If you know of any webpages or articles that deal specifally with this problem ( using a loop to make a grid ) that is also fine - i just need something to work on as im stuck.
Again, the only method i have got to work is this.

1) Create grid[row][col] max.
2) Create 400 textarea manually
3) Create 400 textarea dimensions manually
4) Create 400 textarea xtconstraints manually
5) give each grid position one of the textareas manually.

( thats at least 1600 lines of code, probably followed by a computer crash, and probably followed with alot of swearing ).

Joseph

p.s my last effort is this;

it produces no errors.
nothing happens when the program is run.
[ February 28, 2005: Message edited by: joseph mcgratton ]

Horatio Westock
Ranch Hand
Posts: 221
Hi Joseph,

Please bear in mind that I have never written any swing before, but I just tried this and it seems to work:

In your code, you were only creating one textarea and adding it to every slot in your grid. You weren't adding it to your layout though. I created a GridLayout with MAX_ROWS and MAX_COLS (the other two parameters are the padding between elements).

joseph mcgratton
Ranch Hand
Posts: 41

its frustrating that you can do that in seconds and it takes me hours to accomplish nothing
ive tried your method, and there are no errors when compiling. However nothing appears on the appropriate panel. dont worry ill get it sorted soon.

thankyou

joseph

[ February 28, 2005: Message edited by: joseph mcgratton ]
[ February 28, 2005: Message edited by: joseph mcgratton ]

David Harkness
Ranch Hand
Posts: 1646
Hopefully you'll be able to integrate Horatio's code. As something to think about, why the choice of JTextArea? I assume that you're only using it as a way to create a fixed square; is that correct?

If all you need to do is draw a grid of colored squares, I would skip the JTextAreas entirely and instead just extend JPanel and override its paint() method. I'm not a Swing expert by any stretch (probably barely intermediate as it's been a while), but that seems the easiest route.

Obviously, you don't need to go down this route, but for practice you might want to think about how you'd do this. Clearly you'd need to change the type of the "grid" array to not use JTextArea. How would you model the information involved in your application?

Anyway, let us know if you have difficulty getting it up and running.