Picking a random neighboring square

Hi, I’m quite new to programming. I have a change that I’m trying to implement in a program that I inherited. It’s frustrating because I imagine for an experienced programmer it’s pretty straightforward. Can anyone help me?

I have an array of squares. Each square has a value, either s(i,j)=1 or s(i,j)=-1. I want to randomly select a square and a random neighbor to the top, bottom, left, or right such that the neighbor has an opposite value to the original square, else move on to the next random square and look for a random neighbor that has the opposite value, etc. I’m not sure how to do this in an efficient way, though the program already has a random integer generator, App.RandInt

Some potential problems:
-I’m not sure if I would need to take into account boundary conditions. While for periodic boundaries, this probably wouldn’t be a problem, for isolated boundaries it might be, where the edge squares have some neighbors that are off the array completely, i.e. whose value s(i,j) = 0.
-Finally, I will use this to then to call another subroutine, so it seems impractical to call it within each if statement - is there another way?

I started with the following, but I know it’s wrong and it seems very inefficient:

Dim i,j as Integer
i = RandInt(Size) // this calls the preexisting App.RandInt to generate a random integer between zero and Size-1 inclusive
j = RandInt(Size)
// The following looks at all the neighbors. I want it to look at a random one, i.e. not necessarily the one to the top (for example) else move on. Am not sure how to do that, though…
if s(i,j) <> s(i+1,j) then
    if s(i,j) <> 0 and s(i+1,j) <> 0 then
         //call subroutine
    end if
end if
if s(i,j) <> s(i-1,j) then
    if s(i,j) <> 0 and s(i-1,j) <> 0 then
         //call subroutine
    end if
end if
if s(i,j) <> s(i,j+1) then
    if s(i,j) <> 0 and s(i,j+1) <> 0 then
         //call subroutine
    end if
end if
if s(i,j) <> s(i,j-1) then
    if s(i,j) <> 0 and s(i,j-1) <> 0 then
         //call subroutine
    end if
end if

To pick a random neighbor, one approach would be to shuffle an array. Start with an array

dim nb() as integer = array(1,2,3,4)

where 1 = top, 2 = right, 3 = bottom, 4 = left

Then your code becomes

dim i, j, k, i1, j1 as integer

i = RandInt(Size)
j = RandInt(Size)
shuffle(nb)
for k = 0 to 3
   i1 = i
   j1 = j
   select case nb(k)
   case 1
      j1= j-1
   case 2
      i1 = i+1
   case 3
      j1 =  j+1
   case 4
      i1 = i-1
   end
   if s(i,j) <> s(i1,j1) then
      if s(i,j) <> 0 and s(i1,j1) <> 0 then
         // call subroutine
         exit for k
      end
   end
next

Thanks. I get an error saying that the item “shuffle” does not exist. Is there something else that I can use? Also, how does the code “know” that 1, 2, 3, and 4 are top, right, bottom, and left? -Sam

  dim nb() as integer = array(1,2,3,4)
  
  dim i, j, k, i1, j1 as integer
  
  i = RandInt(Size)
  j = RandInt(Size)
  shuffle(nb)
  for k = 0 to 3
    i1 = i
    j1 = j
    select case nb(k)
    case 1
      j1= j-1
    case 2
      i1 = i+1
    case 3
      j1 =  j+1
    case 4
      i1 = i-1
    end
    if s(i,j) <> s(i1,j1) then
      if s(i,j) <> 0 and s(i1,j1) <> 0 then
        // call subroutine
        exit for k
      end
    end
  next

Shuffle used as is array.shuffle, so you need to change it to

nb.shuffle

As to making the code “know,” that is up to you. A select case statement would come to mind.

Thanks, but I get an “out of bound” exception for the line “if s(i,j) <> s(i1,j1) then” when I run it. Any clue how to solve it?

  // executes ColorSquare and ColorSquareforNeighbor every time two dipole flip
  
  Dim nb() as integer = array(1,2,3,4)
  Dim i,j,k,i1,j1,thisS,thatS,count as Integer
  Dim Ediff,EdiffforM as Double
  #if TargetCarbon
    Declare Function Random Lib "Carbon" as Short
  #endif
  #if TargetPPC
    Declare Function Random Lib "InterfaceLib" as Short
  #endif
  #pragma disableBackgroundTasks  // we need speed here
  
  for count = 1 to StepsPerLoop
    i = RandInt(Size)
    j = RandInt(Size)
    nb.shuffle
    for k = 0 to 3
      i1 = i
      j1 = j
      select case nb(k)
      case 1
        j1= j-1
      case 2
        i1 = i+1
      case 3
        j1 =  j+1
      case 4
        i1 = i-1
      end
      if s(i,j) <> s(i1,j1) then
        if s(i,j) <> 0 and s(i1,j1) <> 0 then
          thisS = s(i,j)
          thatS = s(i1,j1)
          Ediff = deltaUforNeighbors(i,j,thisS)
          EdiffforM= deltaUforNeighbors(i,j,thisS)
          If EdiffforM <= 0.0 then
            thisS = -thisS
            s(i,j) = thisS
            thatS = -thatS
            s(i1,j1) = thatS
            ColorSquare(i,j,thisS)
            ColorSquareforNeighbor(i1,j1,thatS)
            Ecurrent = Ecurrent + Ediff
            Mcurrent = Mcurrent + 2*thisS + 2*thatS
          Else
            #if TargetMacOS
              If (Random() + 32767) < 65535.0*exp(-EdiffforM/T) then  // check constants!
                thisS = -thisS
                s(i,j) = thisS
                thatS = -thatS
                s(i1,j1) = thatS
                ColorSquare(i,j,thisS)
                ColorSquareforNeighbor(i1,j1,thatS)
                Ecurrent = Ecurrent + Ediff
                Mcurrent = Mcurrent + 2*thisS + 2*thatS
              End if
            #else
              If Rnd < exp(-EdiffforM/T) then  // on Windows, use RB's slower RNG
                thisS = -thisS
                s(i,j) = thisS
                thatS = -thatS
                s(i1,j1) = thatS
                ColorSquare(i,j,thisS)
                ColorSquareforNeighbor(i1,j1,thatS)
                Ecurrent = Ecurrent + Ediff
                Mcurrent = Mcurrent + 2*thisS + 2*thatS
              End if
            #endif
          End if
          exit for k
        end
      end
    next
  next
  InnerLoopCount = InnerLoopCount + 1

[quote=128950:@Samuel Cohen]I started with the following, but I know it’s wrong and it seems very inefficient:
[/quote]

It has been a while I have seen you struggle with this issue, and even try to hire someone to solve it for you. Apparently without success. Modifying someone else program is difficult even for a competent programmer. One has to have a thorough understanding of all aspects of coding, and programming techniques, simply to understand what the program does.

If I may risk a bit of advice, I have the impression you are trying to modify a program before learning the basics, and this simply will not work. Programming is just like any other human knowledge, based on an accumulation of basic concepts that need to be assimilated before your can risk working with more elaborate. In mathematics, you cannot engage in higher concepts if you do not know basic calculus. In mechanics, one cannot start repairing an engine before having learned the basics of nut sizes.

Your answers demonstrate a lack of these basic concepts. You are trying to build an entire new room to a house before laying out the foundations. You cannot simply venture into a program without understanding it.

Before attempting such an endeavour, you may want to get more familiar with the basic, and build simpler programs of your own, to get the feeling of what is involved. Then, when you are more familiar with Xojo and the concepts involved in small programs, the larger picture will be a lot clearer.

You absolutely need to be comfortable with the basics. See Book 1 - Fundamentals at http://documentation.xojo.com and then Desktop Quick Start.

Also, BKeeney Software (me) has roughly 42 hours (over 110 separate projects) of Training Video on Real Studio and Xojo at http://www.bkeeney.com/XojoTraining/xojotraining.cgi .

Learn to swim before you dive !

Cannot edit my previous post. I copied a sentence from Bob Keeney. The “(me)” in the paragraph mentioning his training videos is him, not myself. Sorry.