Table madness

I am working on my second game (anxiously waiting for app store approval on first)

Basically the game will have a 3X3 grid of shuffled cards and I need to detect any vertically or horizontally adjacent 3 or more of a kind, sequences of 3 or more of any suit, sequences of 3 or more of the same suit.

Please look at: http://dl.dropbox.com/u/11235/cards.png for a diagram

I am having a heck of a time coming up with the logic to do that. Is there a good resource for figuring out this kind of logic. Here is the code I started to write. Right now it only checks for single matches and its getting very convoluted. There has to be a better way!

[code]
local c11, c21, c31, c12, c22, c32, c13, c23, c33
local row1, row2, row3, col1, col2, col3
–create deck
local cards = {}
for b = 1, 4 do
for i=1,14 do
local myCard = {b,i}
table.insert ( cards, myCard )
end
end
–shuffle deck
local shuffledCards = {}
while #cards > 0 do
randNum =math.random(1,#cards)
randPick = cards[randNum]
table.insert ( shuffledCards, randPick )
table.remove ( cards, randNum )
end
– put first 9 into grid cels
c11 = {shuffledCards[1]}
c21 = {shuffledCards[2]}
c31 = {shuffledCards[3]}
c12 ={shuffledCards[4]}
c22 ={shuffledCards[5]}
c32 = {shuffledCards[6]}
c13 = {shuffledCards[7]}
c23 = {shuffledCards[8]}
c33 = {shuffledCards[9]}
–put cells into row arrays
row1 = {c11, c21, c31}
row2 = {c12,c22,c32}
row3 = {c13,c23,c33}
–put cells into collums arrays
col1 = {c11, c12, c13}
col2 = {c21, c22, c23}
col2 = {c31, c32, c33}
–find matches
if row1[1][1][2] == row1[2][1][2] then print(“match on row 1!”)end
if row1[2][1][2] == row1[3][1][2] then print(“match! on row 1!”)end

if row2[1][1][2] == row2[2][1][2] then print(“match on row 2!”)end
if row2[2][1][2] == row2[3][1][2] then print(“match on row 2!”)end

if row3[1][1][2] == row3[2][1][2] then print(“match on row 3!”)end
if row3[2][1][2] == row3[3][1][2] then print(“match on row 3!”)end

if row1[1][1][2] == row2[1][1][2] then print(“match on col1!”)end
if row2[1][1][2] == row3[1][1][2] then print(“match on col1!”)end

if row1[2][1][2] == row2[2][1][2] then print(“match on col1!”)end
if row2[2][1][2] == row3[2][1][2] then print(“match on col1!”)end

if row1[3][1][2] == row2[3][1][2] then print(“match on col1!”)end
if row2[3][1][2] == row3[3][1][2] then print(“match on col1!”)end
[/code] [import]uid: 6310 topic_id: 15684 reply_id: 315684[/import]

check out this thread http://developer.anscamobile.com/forum/2011/09/06/checking-grid-array-line-patterns here i gave code to do something similar but on a bigger grid just adjust to fit your 3x3 grid [import]uid: 7911 topic_id: 15684 reply_id: 57888[/import]

I was going to refer to jstrahan’s post as well, who was kind enough to share that code with me. It’s working great for me at the moment!

You’ll have to do a little adapting but nothing too hard to do! [import]uid: 70134 topic_id: 15684 reply_id: 57929[/import]

This is great guys! I had searched for tons of keywords but never “grid array line patterns” sometimes english is too rich a language! [import]uid: 6310 topic_id: 15684 reply_id: 58009[/import]

your welcome
if you have problem adapting let me know and I’ll help [import]uid: 7911 topic_id: 15684 reply_id: 58016[/import]

Ok. I think I have made some good progress!

I have revised the code so it nows goes through each cell on the grid and checks for a sequential number on any of four directions.

So far so good. I have a nice collection of all the two digit sequences detected and in which direction. Now the question is… how do I string all these together so I can detect sequences longer than 2 that are not linear? for example:

\_\_\_\_\_\_\_\_\_\_\_\_\_ --how do i detect the 1,2,3,4,5,6 sequence?  
| 2 | 3 | 8 |--I have 1,2 and 2,3 and 3,4 and 4,5 and 5,6  
|---|---|---|--I know which direction each goes   
| 1 | 4 | 5 |   
|---|---|---|--I guess my question is:   
| 5 | 2 | 6 |--How do I patch them up into a single sequence?   
------------   

Here is the code I am using:

math.randomseed( os.time() )  
ol = {} gr = {} gr[1] = {} gr[2] = {} gr[3] = {}  
  
for y=1, 3 do  
 for x=1,3 do   
 gr[x][y] = math.random(13)   
 end  
end  
  
print("\rda grid:\r\r")  
for y=1, 3 do  
 print( gr[1][y] .. ":".. gr[2][y]..":".. gr[3][y])   
end  
print("\r------")  
  
seq = {}  
  
local aboveLengh=0  
local belowLengh=0  
local rightLengh=0  
local leftLengh=0  
  
for y=1, 3 do  
 for x=1,3 do  
 cand = gr[x][y]  
 if(x \>2) then -- check to the left  
 if(gr[x-1][y] == gr[x][y]+1 ) then  
 leftLengh = leftLengh+1  
 seq[#seq+1] = gr[x][y]  
 print("left sequence detected:" .. gr[x][y] .. " to " .. gr[x-1][y] )  
 end  
 end   
 if(x \< 3) then -- check to the right  
 if(gr[x+1][y] == gr[x][y]+1 ) then  
 rightLengh = rightLengh +1  
 seq[#seq+1] = gr[x][y]  
 print("right sequence detected:" .. gr[x][y] .. " to " .. gr[x+1][y] )  
 end  
 end  
 if(y \> 1) then -- check above  
 if(gr[x][y-1] == gr[x][y]+1 ) then  
 aboveLengh = aboveLengh+ 1  
 seq[#seq+1] = gr[x][y]  
 print("above sequence detected:" .. gr[x][y] .. " to " .. gr[x][y-1] )  
 end  
 end  
 if(y \< 3) then -- check below  
 if(gr[x][y+1] == gr[x][y]+1 ) then  
 belowLengh = belowLengh + 1  
 seq[#seq+1] = gr[x][y]  
 print("below sequence detected:" .. gr[x][y] .. " to " .. gr[x][y+1] )  
 end  
 end   
 end  
end  

Thanks for any help you can provide! [import]uid: 6310 topic_id: 15684 reply_id: 58109[/import]

sorry im not understanding what it is your trying to do
are you try to get which cell each one is in like

1 - 1,2
2 - 1,1
3 - 2,1
4 - 2,2
5 - 3,2
6 - 3,3 [import]uid: 7911 topic_id: 15684 reply_id: 58127[/import]

Sorry, let me try to explain myself again.

I can find out which cells make up consecutive sequences of 2 in any direction, what I can’t figure out is how to make all those individual two cell sequences into an orderly list that holds sequences that are 3 or longer and don’t occur on the same row/collum.

For example

cell1=5 cell2=6 cell3=2
cell4=2 cell5=7 cell6=1
cell6=5 cell8=8 cell9=5

With my current code I end up with the expected pairs cell1-cell2 (5-6), cell2-cell5(6-7), cell5=cell8(7-8) but I also get the unrelated set cell6-cell3 (1-2)

So I end up with 4 cel pairs of which 3 are related to each other and actually make up a sequence of 3 or more.

What I need to do is able to but up relevant pairs to make up a sequence of 3 or more pairs so I can then add up the points and remove those cards from the board.

Maybe I should just re-design the game for sequences on the same line only. That would be pretty easy but I think it would really affect the nature of the game.
[import]uid: 6310 topic_id: 15684 reply_id: 58129[/import]

getting late not thinking straight but briefly

after you have all your pairs

in the code i posted on the thread above the part that removes duplicates modify it so it compares the pairs and each time a pair has a cell in common with another pair it gets saved into a new table the if the new table has 3 or more pairs you have your pairs to remove

give this a try and let me know if you have trouble and ill try to help more tomorrow
my mind’s tied up between me working on a particle system and sleep [import]uid: 7911 topic_id: 15684 reply_id: 58132[/import]

Thanks jstrahan.

I need to take my girl to a school trip but I will try this as soon as I return and let you know how it goes! Thanks again! [import]uid: 6310 topic_id: 15684 reply_id: 58179[/import]

What you are after is a maze solving type algorithm, that will find the largest match for you. Hope that is a clue for your search.

You will have to use recursion to achieve what you are after and get the length of each direction to determine the best length.

cheers,

?:slight_smile: [import]uid: 3826 topic_id: 15684 reply_id: 58185[/import]

Thanks! Just knowing where to look is a big help! This is one of those things that I first dismissed as trivial and has proven to be anything but!
[import]uid: 6310 topic_id: 15684 reply_id: 58188[/import]

Ok! I did it! here is my final code:

math.randomseed( os.time() )  
gr={} gr[1]={} gr[2]={} gr[3]={}  
for y=1, 3 do  
 for x=1,3 do   
 gr[x][y] = math.random(13)   
 end  
end  
-- comment the following line out to get a random set. The one in the next line is good for testing.  
gr[1][1] = 11 gr[2][1] = 10 gr[3][1] = 5 gr[1][2] = 12 gr[2][2] = 9 gr[3][2] = 6 gr[1][3] = 13 gr[2][3] = 8 gr[3][3] = 7  
-- display the current grid for visual reference  
print("\rda grid:\r\r--------")  
for y=1, 3 do  
 print( gr[1][y] .. "|".. gr[2][y].."|".. gr[3][y])   
 print("--------")  
end  
print("\rFound Sequences:\r\r")  
local function checkNeighbors(cord1, cord2)  
 local directions = {{1,0},{-1,0},{0,-1},{0,1}}  
 for i=1, 4 do  
 directionFetch = directions[i]  
 if( (cord1 + directionFetch[1] \> 0) and (cord1 + directionFetch[1] \< 4) and (cord2 + directionFetch[2] \> 0) and (cord2 + directionFetch[2] \< 4 ))  
 then  
 if( gr[cord1][cord2]+1 == gr[cord1 + directionFetch[1] ] [cord2 + directionFetch[2] ]) then  
 tt = {cord1 + directionFetch[1],cord2 + directionFetch[2]}  
 return(tt)  
 end  
 end   
 end  
 return(nil)  
end  
for yPos = 1,3 do -- we will do a check for each of the cels on our 3X3 grid  
 for xPos = 1,3 do  
 cords = {xPos,yPos} -- the cell we will start looking for sequences from  
 foundSequence = {cords} -- all searches will start with a single match, the cell itself  
 myCheck = checkNeighbors(xPos, yPos) -- check to the right, left, above and below for a sequential number  
 while (myCheck ~= nil) do -- we will keep checking for a sequentials until the last cel checked has none  
 table.insert ( foundSequence, myCheck) -- lets add it to our found sequence  
 myCheck = checkNeighbors(myCheck[1], myCheck[2]) -- now let see if the is another sequential after this one   
 end  
 if(#foundSequence \> 2) then -- ok, was our final squence longer than 2? Then lets show it!  
 print("---")  
 for i=1, #foundSequence do  
 print(foundSequence[i][1]..","..foundSequence[i][2])  
 end   
 end  
 end   
end  

Let me know if you see something that could be better.

Thanks again for all the help! [import]uid: 6310 topic_id: 15684 reply_id: 58299[/import]

New improved version! Now for any table dimension.

I have revised the code a bit and now it works for any size grid. I am not sure where to share this code in case someone else needs it in the future so I’ll just put it here:

[code]
local function buildMyGrid(xDim, yDim)
math.randomseed( os.time() )
gridSize = {xDim,yDim} – make your grid any dimensions you like, we will refer to this later so make it a global
grid={} – a home for our eventual grid
for i=1, gridSize[1] do – create an empty table for each column
table.insert(grid, {})
end
for y=1, gridSize[2] do
for x=1,gridSize[1] do
grid[x][y] = math.random(13) – generate a random number and put it on a coresponding table cel
end
end
end

local function printGrid()
local dashLine – make this local to the function so we can print it when the loop is done
print(“our generated table:\r”)
for y=1, gridSize[2] do
local comp = “| "
dashLine = " "
for p=1, gridSize[1] do
numberToInsert = grid[p][y]
dashLine = dashLine … “—”
if(numberToInsert < 10)then numberToInsert = “0” … numberToInsert end
comp = comp … numberToInsert …” | "
dashLine = dashLine … “-”
end
dashLine = dashLine … “–”
print(dashLine)
print( comp)
end
print(dashLine)
end

local function checkNeighbors(cord1, cord2)
local directions = {{1,0},{-1,0},{0,-1},{0,1}}
local directionPointer = 1
for i=1, gridSize[1]+1 do
if(directionPointer > #directions) then directionPointer=1 end
directionFetch = directions[directionPointer]
directionPointer = directionPointer+1
if( (cord1 + directionFetch[1] >= 1) and (cord1 + directionFetch[1] <= gridSize[1]) and (cord2 + directionFetch[2] >= 1) and (cord2 + directionFetch[2] <= gridSize[2] ))
then
if( grid[cord1][cord2]+1 == grid[cord1 + directionFetch[1] ] [cord2 + directionFetch[2] ]) then
tt = {cord1 + directionFetch[1],cord2 + directionFetch[2]}
return(tt)
end
end
end
return(nil)
end

local function findSequences()
print("\rFound Sequences:\r\r")
for yPos = 1,gridSize[2] do – we will do a check for each of the cels on our 3X3 grid
for xPos = 1,gridSize[1] do
cords = {xPos,yPos} – the cell we will start looking for sequences from
foundSequence = {cords} – all searches will start with a single match, the cell itself
myCheck = checkNeighbors(xPos, yPos) – check to the right, left, above and below for a sequential number
while (myCheck ~= nil)
do – we will keep checking for a sequence until the last cel checked has none
table.insert ( foundSequence, myCheck) – lets add it to our found sequences
myCheck = checkNeighbors(myCheck[1], myCheck[2]) – now let see if the is another sequential after this one
end
if(#foundSequence > 2) then – ok, was our final sequence longer than 2? Then lets show it!
print("—")
for i=1, #foundSequence do
print(foundSequence[i][1]…","…foundSequence[i][2])
end
end
end
end
end

buildMyGrid(3,3)
printGrid()
findSequences()

[/code] [import]uid: 6310 topic_id: 15684 reply_id: 58368[/import]

glad you got it working. at top of page in the community dropdown there’s a link to share code [import]uid: 7911 topic_id: 15684 reply_id: 58370[/import]

Hmmm, I am trying to reuse your code but I cant manage to get the findSequences to work?

I am not sure if I am doing this right but I am looking for equals in my table…

 --------------------------  
| 0 | 0 | 0 | 0 | 0 | 0 |   
 --------------------------  
| 0 | 0 | 0 | 0 | 3 | 3 |   
 --------------------------  
| 0 | 0 | 0 | 0 | 3 | 3 |   
 --------------------------  
| 0 | 1 | 0 | 0 | 2 | 3 |   
 --------------------------  
| 1 | 0 | 0 | 0 | 0 | 0 |   
 --------------------------  
  

Shouldnt I get a match on the “3” in the last row?

Joakim [import]uid: 81188 topic_id: 15684 reply_id: 60665[/import]

The problem is that my code is set up to detect sequences of numbers (1,2,3,4,5,6,7) this is key to the algorithm since it only will detect numbers that are higher than the cell currently being checked. If I modify it to find same numbers it goes into an endless loop and crashes (basically eating its own tail).

What you need to do is probably best served with a different algorithm. I remember finding others that do what you want but not what I needed. I’ll look around and see if I can find them.

[import]uid: 6310 topic_id: 15684 reply_id: 60671[/import]