# 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

``````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.