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("Add", add)
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
function add()
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
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