Algorithm question: how to flip the colors on a checkerboard using Xojo

I’m learning how to program using Xojo code that I inherited. Given a checkerboard of two colors, I want to flip one color, say the colors on the squares where the columns and rows are all even-valued or all odd-valued, if that makes sense. How do I do that? What am I doing wrong? I wrote the following but it doesn’t work. In fact, the program freezes when I use it.

In case it would be helpful to see the whole code: https://www.dropbox.com/s/2rneozqhtijoc7v/MyApp.xojo_binary_project

  Dim k, n as Integer
  
  for i = 0 to size-1
    for j = 0 to size-1
      if i/2 = k and j/2 = n then
        if thisS = 1 then
          GraphicsWindow.Graphics.ForeColor = DownColor
        else
          GraphicsWindow.Graphics.ForeColor = UpColor
        end if
      elseif i/2 <> k and j/2 <> n then
        if thisS = 1 then
          GraphicsWindow.Graphics.ForeColor = DownColor
        else
          GraphicsWindow.Graphics.ForeColor = UpColor
        end if
      end if
    next
  next

Since there are only two colours, you are drawing at least 50% more things than you need to.

Its already quite speedy though.

In your shoes, I would:

Create an offscreen picture
Fill it with one of the colours.
Then only draw rects for things of the other colour. (Half as many fillrects)
then in the paint event of the Draw window, copy the offscreen picture entire.

You can use invalidate to tell the window it needs to paint
And refresh if you insist that it paints.

Another approach would be to maintain an array of object2d RectShapes, held inside a Group2D object (say its called MyGroup)
You could iterate through those and change their fillcolor at any time.

Painting the screen is simply using g.drawobject MyGroup in the paint event

Hi there,

Given k and n haven’t been set, just Dimmed, they’ll be zero, so i/2 or j/2 won’t ever be useful values.
Also (not sure if this is by design), your If tests won’t be flipping any values which have a column even but a row odd, or vice versa.

If you’re trying to test for even-ness or odd-ness, try using mod - i.e.

if i mod 2 = 0 and j mod 2 = 0 then
  • that way you won’t need k and n. The test above is for even-ness.

Looking at the context in which the method you have posted is used is revealing. You are passing i and j in as method parameters, but then promptly override them using a for loop!

There is also no feedback mechanism in colorSquares to set s(i,j) to the value of the colour that you have set the square to.

Something like this is more like what I think you were trying to do.

[code] Dim x, y as Integer

if i mod 2 = 0 and j mod 2 = 0 then
if thisS = 1 then
GraphicsWindow.Graphics.ForeColor = DownColor
s(i,j)=-1
else
GraphicsWindow.Graphics.ForeColor = UpColor
s(i,j)=1
end if
elseif i mod 2 <> 0 and j mod 2 <> 0 then
if thisS = 1 then
GraphicsWindow.Graphics.ForeColor = DownColor
s(i,j)=-1
else
GraphicsWindow.Graphics.ForeColor = UpColor
s(i,j)=1
end if
end if

If Showspin then
If BfieldM(i, j) > 0.0001 then
GraphicsWindow.Graphics.ForeColor = Setupco
Else
if BfieldM(i,j) < -0.0001 then
GraphicsWindow.Graphics.ForeColor = Setdoco
end if
end if
end if
x = i * SquareWidth
y = j * SquareWidth
GraphicsWindow.Graphics.FillRect x, y, SquareWidth, SquareWidth[/code]

PS The program wasn’t actually freezing, just setting all the colours to themselves, then redrawing. So, it looked like it wasn’t doing anything, whereas actually it was dutifully drawing rectangles, but because they were the same colour as the rectangle they were drawing over, it looked like nothing was happening.

Thanks, Hamish. I didn’t know about the “mod” feature in Xojo! The new code certainly is cleaned up but still doesn’t give the desired results. When I click RadioButton3, I’m trying to flip the color but not the square value for only half the checkerboard, so I think setting a new s(i,j) is undesired. What I mean by this is given a checkerboard of squares, I want to flip all of the squares on even columns and rows to the opposite color and all the squares on the odd columns and rows to the opposite color as well. Everything else, including the value of the square should remain unchanged. It seems that the code now does this, but still doesn’t give the desired results. Any idea?

Using the GUI, when I bring the temperature to zero and click RadioButton2, I should see temporarily outlines of some features. What I would like to do is use RadioButton3 so that those outlines should become clear, with the squares all one color on one side of the feature (“interface”) and all another color on the other side, if that makes sense.

Hi -
Afraid I don’t quite understand what’s needed. It it to stop the animation and flip colours, or keep going with the animation and flip colours, or something else?
Hamish

Hi Hamish, ideally it would be the latter, if that’s possible (to do it once in the beginning and then the rest of the animation would show the desired effect). -Sam

Hi there,

Not really sure how to do that, I’m afraid, but hopefully the help I’ve given above would be of use to get you on the right track…

H

Thanks, Hamish. By any chance, would you know how to flip the colors each time you press RadioButton3? I think that would be a good first step. In other words, not “once in the beginning and then the rest of the animation would show the desired effect”, but just only when you click the radio button? Right now when you click the radio button, it doesn’t have the desired effect at all. I’m not sure how to do that either. -Sam

Hi there,
The problem as I see it is that the animation keeps running. Do you want to do something like this?

  • Stop the timer, so the animation stops
  • Flip the colours
    It’s not really that I don’t know how to do it (I’m sure I could work it out) but that I’m not familiar enough with what your program does and how it works, or the physical stuff you’re modelling, to know what’s needed…
    If the code I wrote before does the correct flipping, then why not just have a flag somewhere to stop the animation?
    H

Hi Hamish, thanks very much for your suggestions. Unfortunately, the code doesn’t seem to do the correct flipping because when you lower the temperature, say to zero, and then go from RadioButton2 to RadioButton3, you should no longer see the checkerboard pattern and instead should see interfaces between all blue squares on one side and all yellow squares on another side. I apologize for the lack of clarity, but it’s very difficult to describe without pictures! -Sam

Hi Samuel,
I’m really sorry, but I don’t understand what output you are expecting. Can you post pictures of a) the graphic before moving to radio button 3 and b) what you expect it to be after moving to radio button 3? Remember I have no background in magnetics and don’t understand what the output is supposed to be!
Hamish

Is that somehow different to ‘swap all the colours to the opposite colour’?

It may be easier to generate an array of booleans up front

myStates(500,500) as boolean
then your code would be

for i = 0 to 500 for j = 0 to 500 if myStates(i,j) then //use color1 else //use color2 end if //draw the box next next

flipping the colours would be

[code]sub flipThecolors
for i = 0 to 500
for j = 0 to 500
myStates(i,j) = not( myStates(i,j) )

next
next
end sub

//now call the paint event of the canvas
[/code]

Doing only the even rows would be

sub flipEvenRows for i = 0 to 500 for j = 0 to 500 if j mod 2 = 0 then myStates(i,j) = not( myStates(i,j) ) next next end sub

and so on.
The drawing could be much optimised as above, but its clear you need a way to flip states first… this code will do that.

I confess I havent a clue what your app is supposed to be doing: all the buttons generate a screen full of seemingly random squares…

Different track: say you want a flippable 8x8 black&white chess pattern.

Draw a picture with a 9x9 chess pattern just once.

Then draw that picture into your canvas using g.DrawPucture either from 0 to 8 (normal state) or from 1 to 9 (flipped state)

Might be talking nonsense though as I’m not at my computer and can’t look at your code …

Thanks for the replies. Jeff: It’s not the same as to “swap all the colours to the opposite color” because I only want to swap the colors for some of the squares on the checkerboard (the ones on the even columns with even rows AND odd columns with odd rows, but not, for example, the ones on even columns with odd rows, etc.).

Hamish: Attached are pictures. In the first one (“Untitled”) you see a typical picture after a short amount of time has passed near zero temperature. Notice the features or “interfaces” in the image which are hard to see due to the checkerboard pattern. I want to be able to automatically switch from the checkerboard pattern to the following (see “Untitled2”). In principle, by flipping the colors but not the square values for only one of the two sublattices on the checkerboard, you should be able to see this. It is a difficult problem, difficult to interface with the GUI, and I hope this clarifies it somewhat! -Sam

https://www.dropbox.com/s/g3d7qihnatqt9mw/Untitled
https://www.dropbox.com/s/j3pta6yuv3dohgr/Untitled2

I think I would take a different approach to this problem, to help separate the drawing from the “which squares” change algorithm.

I’d create a two-dimensional array that represents the board, with each item in the array holding the color of the square. Then the paint event just loops through the board and colors each square.

Then you can move your color-changing logic to a separate method (which could be updated via a timer or pushbutton or whatever). I’m still not exactly sure what you’re trying to do there (those picture files wouldn’t display as I don’t know what format they are in), but it shouldn’t be too hard to figure it out. You just call refresh to the canvas’ paint event when you change the board array.

If you use the image tag and paste the dropbox public link to the picture into that then the pictures show up in your post.

[quote]I’d create a two-dimensional array that represents the board, with each item in the array holding the color of the square. Then the paint event just loops through the board and colors each square.

Then you can move your color-changing logic to a separate method (which could be updated via a timer or pushbutton or whatever).[/quote]
Which is what I said.

if its items where rows and column are even, and where row and column are odd:

[code]sub flipEvenRows
for i = 0 to 500
for j = 0 to 500
if j mod 2 = 0 and i mod 2 = 0 then myStates(i,j) = not( myStates(i,j) )
if j mod 2 = 1 and i mod 2 = 1 then myStates(i,j) = not( myStates(i,j) )
next
next
end sub

//now go and paint them
[/code]

Thanks very much for the replies. I’d been busy with another (non-programming) project, so that’s why I’m only responding now.

I’m a newbie at this, but I believe that’s what the program is already doing. To explain it again (sorry for being unclear):

Consider the model as having two sublattices. One sublattice contains both odd rows and columns AND both even rows and columns, if that makes sense. I wish to show that the features shown using RadioButton2 can look equivalent to the features shown using RadioButton1.

To do this, start with a 100 x 100 lattice say, set the temperature on the GUI to zero, click RadioButton2, and wait only a short time. You will see a checkerboard pattern along with fluctuating other features, “interfaces” as shown by the following: Dropbox - Error - Simplify your life

Now, by clicking RadioButton3, you should resolve those features so that it looks similar (but isn’t identical to) clicking RadioButton1 as shown by the following link: Dropbox - Error - Simplify your life

This should work by flipping the colors (but not the values of the squares themselves) to their opposite color along one sublattice only. So, for both odd rows and columns AND both even rows and columns, you would flip a yellow to a blue or a blue to a yellow square.

Why doesn’t this work as currently implemented? When I do the above procedure - i.e., going from RadioButton2 to RadioButton3 - I still see a checkerboard pattern, even after clicking RadioButton3.

Here’s my program: Dropbox - Error - Simplify your life
The App, ColorSquares(i,j,thisS), is a separate method that implements the color-change logic.