# Math.random confusion

So, I have a game where objects move down the screen from a randomly selected x location (there are 5 possible lanes). However, I want to make it so that the objects do not come down in three successive lanes. So if you look at the next function I tried to store the last 2 locations and then if the new location makes it so that there are 3 in a row then I tried to make it reselect the location using math.random, and then when the new location it should exit the while loop. My code does not work though, as when I test it there are still objects coming down in three successive lanes :

``````
displayMode( FULLSCREEN)
supportedOrientations(CurrentOrientation)

function setup()
dy=-5
count=0
loc={342, 433, 523, 608, 703}
car={}
car1={}
table.insert(car, "Planet Cute:Character Boy")
table.insert(car, "Planet Cute:Character Cat Girl")
table.insert(car, "Planet Cute:Character Horn Girl")
table.insert(car, "Planet Cute:Character Pink Girl")
table.insert(car, "Planet Cute:Character Princess Girl")
next()
end

function next()
x = math.random(1,5)
while (last == {1,2} and x==3) or (last=={2,3} and x==4) or (last =={3,2} and x ==1) or (last=={3,4} or x==5) or (last=={4,3} and x==2) or (last=={5,4} and x==3) do
x = math.random(1,5)
end
if #last == 2 then
for i=#last,1,-1 do
table.remove(last,i)
end
end
s = math.random(1,5)
table.insert(car1,vec3(s,x,HEIGHT))
table.insert(last, x)
end

function draw()
background(52, 172, 22, 255)
for a,b in pairs(car1) do
sprite(car[b.x],loc[b.y],b.z)
b.z=b.z+dy
if b.z<0 then
table.remove(car1,a)
return
end
end
count=count+1
if count>50 then
next()
count=0
end
end

``````

Your problem stems from the fact that you cannot compare different tables with the `==` operator, even if they have the same contents:

``````last = {1,2}

print( last == {1,2} ) -- this is false
``````

This is because even though they have the same contents, these are two different tables.

A better algorithm (and more efficient) might be to compute the “valid lanes” each time. Then randomly select a valid lane to spawn on from the list.

So for example, your list of valid lanes starts at `{1,2,3,4,5}` and if you have a situation where you spawn on `1,2` then you make sure your valid lanes only contains `{1,2,4,5}`.

Here’s a small example that only spawns at empty places:

``````function setup()
dots = {0,0,0,0,0}

parameter.action("Reset", function() restart() end)

h = HEIGHT/(#dots+1)
end

function draw()
background(45)
stroke(255); strokeWidth(5)
fill(255)
for i,v in ipairs(dots) do
ellipse(WIDTH/2, i*h, 5+20*v)
end
end

local list = {}     -- The list that will contain empty indices

-- This loop saves empty indices to 'list'
for i,v in ipairs(dots) do
if v == 0 then table.insert(list, i) end
end

-- 'index' is picked randomly from list
local index = list[math.random(1, #list)]
print("index: ", index)

-- Change the index'th dot
dots[index] = 1
end
``````

However, another way of doing this is by keeping the list of empty indices updated every time an enemy spawns or disappears. That way, the program doesn’t have to run a for loop every time.

@RedCoder1 Here is an example that might work for you. Pass it 1 value and it will return a random value from 1,5 that’s not equal to the original value. Pass it 2 values and it will return a random value from 1,5 that is not equal to the original 2, and will not have 3 values in a row.
I added some code to show a combination of 1 or 2 values passed. The values in [ ] are the ones passed. The other value is what is returned. Just call next with 1 or 2 values.

``````
function setup()
-- passing 1 number
for x=1,5 do
print("[ "..x.." ]  ",next(x))
end
print()
-- passing 2 numbers
for x=1,5 do
for y=1,5 do
print("[ "..x..","..y.." ]  ",next(x,y))
end
end
end

function draw()
background(40, 40, 50)
end

function next(p1,p2)
if p2==nil or p1==p2 then
p2=0
end
while 1 do
n=math.random(5)
if n~=p1 and n~=p2 then
if math.abs(p1-n)~=1 and math.abs(p2-n)~=1 then
return n
end
if math.abs(p1-p2)~=1 and math.abs(p1-n)~=1 then
return n
end
if math.abs(p1-p2)~=1 and math.abs(p2-n)~=1 then
return n
end
end
end
end

``````

Untested

``````local a,b = -1,-1
function next()
local i
if b == a + 1 then
i = math.random(1,4)
if i > b then
i = i + 1
end
elseif b == a -1 then
i = math.random(2,5)
if i < b then
i = i - 1
end
else
i = math.random(1,5)
end
a,b = b,i
return i
end
``````

Thank you all who replied my game now works as intended =)