Match 3 logic

Hi all,

I’m new to CoronaSDK, new to Lua and new to programming in general. I have been trying to fumble my way through some match 3 logic but I am just stuck. I can’t figure out how to remove the display objects once a 3rd match is made. Below is my code.

[code]
–SETUP
–hide status bar
display.setStatusBar( display.HiddenStatusBar )

–set physics
local physics = require “physics”
physics.start()
physics.setGravity( 0, 9 )

–set draw mode
–physics.setDrawMode( “hybrid” )

–vars
i = 0;
beans = {};
end_flag =false;

–stage walls
local leftWall = display.newRect(0,0,1, display.contentHeight)
local rightWall = display.newRect(display.contentWidth,0,1,display.contentHeight)
local floor = display.newRect(0,display.contentHeight,display.contentWidth,1)
local roof = display.newRect(0,0,display.contentWidth,1)
floor.myName = “floor”
roof.myName = “roof”

–set wall physics
physics.addBody(leftWall, “static”, {density=0, friction=1, bounce=0} )
physics.addBody(rightWall, “static”, {density=0, friction=1, bounce=0} )
physics.addBody(floor, “static”, {density=0, friction=1, bounce=0} )
physics.addBody(roof, “static”, {density=0, friction=1, bounce=0, isSensor = true} )

–FUNCTIONS
–set the end game flag
function endGame (event)
print (“Game Over”);
end_flag = true;
end

–create the bean images
function startBean()
if(end_flag ~= true)then
–>set bean colour
local rand = math.random(121);
if (rand < 24) then
colour = “GreenBean.png”;
ctype = “green”
elseif (rand < 48) then
colour = “YellowBean.png”;
ctype = “yellow”
elseif (rand < 72) then
colour = “BlueBean.png”;
ctype = “blue”
elseif (rand < 96) then
colour = “RedBean.png”
ctype = “red”
elseif (rand < 120) then
colour = “PurpleBean.png”;
ctype = “purple”
else
colour = “BlackBean.png”;
ctype = “black”
end

–display bean
newBean = display.newImage(colour);
newBean.x = display.contentWidth*0.5;
newBean.y = 40;
i = i + 1;
newBean.myName = “bean” … i;
newBean.tRef = i;
newBean.beanType = ctype;
newBean.touching = {};
local left = { -7,-4, 12,24, -5,29, -21,30, -33,25, -40,18, -41,7, -34,1 };
local right = { -8,-7, 4,-20, 16,-32, 28,-30, 35,-20, 34,-2, 27,11, 11,22 };
physics.addBody( newBean,
{ density=100, friction=1, bounce=0, shape=left},
{ density=100, friction=1, bounce=0, shape=right}
)
beans[i] = newBean;
end
end

–check if beans are touching
function beanCheck(event)
local obj1 = event.object1.myName;
local obj2 = event.object2.myName;
local beanType1 = event.object1.beanType;
local beanType2 = event.object2.beanType;
local tableRef1 = event.object1.tRef;
local tableRef2 = event.object2.tRef;
if(event.phase == “began”) then
if(beanType1 == beanType2) then
if (#beans[tableRef1].touching > 0) then
inTable = false;
for k=1,#beans[tableRef1].touching do
if (beans[tableRef1].touching[k] == obj2) then
inTable = true;
–print (“existing”);
end
end
if(inTable == false) then
beans[tableRef1].touching[#beans[tableRef1].touching+1] = obj2;
–print (“additional add”);
end
else
beans[tableRef1].touching[1] = obj2;
–print (“new add”);
end
if (#beans[tableRef2].touching > 0) then
inTable = false;
for k=1,#beans[tableRef2].touching do
if (beans[tableRef2].touching[k] == obj1) then
inTable = true;
–print (“existingobj2”);
end
end
if(inTable == false) then
beans[tableRef2].touching[#beans[tableRef2].touching+1] = obj1;
–print (“additional addobj2”);
end
else
beans[tableRef2].touching[1] = obj1;
–print (“new addobj2”);
end
if(#beans[tableRef1].touching >= 3) then
for k=1,#beans[tableRef1].touching do
if(beans[tableRef1].touching[k] ~= nil) then
–print (beans[tableRef1].touching[k]);
local test = beans[tableRef1].touching[k];
–beans[tableRef1].touching[k]:removeSelf();
–bean1:removeSelf();
print(test);
beans[tableRef1].touching[k] = nil;
end
end
end
end
end
if(event.phase == “ended”) then
if(beanType1 == beanType2) then
if (#beans[tableRef1].touching > 0) then
for k=1,#beans[tableRef1].touching do
if (beans[tableRef1].touching[k] == obj2) then
beans[tableRef1].touching[k] = nil;
–print (“removed”);
end
end
end
if (#beans[tableRef2].touching > 0) then
for k=1,#beans[tableRef2].touching do
if (beans[tableRef2].touching[k] == obj1) then
beans[tableRef2].touching[k] = nil;
–print (“removedobj2”);
end
end
end
end
end
end

– function moveTest(event)
– local vx,vy = newBean:getLinearVelocity();
– if (vx < 1 and vy < 1 ) then
– startBean();
– end
– end
roof:addEventListener(“collision”, endGame);
–Runtime:addEventListener(“enterFrame”, moveTest);
Runtime:addEventListener(“collision”, beanCheck);
–MAIN CODE

if(end_flag ~= true)then
tmr = timer.performWithDelay(500, startBean, -1);
end
[/code] [import]uid: 31694 topic_id: 22063 reply_id: 322063[/import]

I’m not familiar with “Match 3” - is that basically a matching game where you want to match 3 images rather than 2? (Sorry if I’m appearing dense ;)) [import]uid: 52491 topic_id: 22063 reply_id: 87803[/import]

Yes exactly. Like bejewelled for example, or Dr Robotnik’s mean bean machine.

Beans fall down one by one and when 3 or more of the same colour touch they are removed. As time goes by the beans fall faster and faster etc. [import]uid: 31694 topic_id: 22063 reply_id: 87809[/import]

Ah I see, apologies, when I read “match” I was thinking of an actual matching game. (You know, like flipping over cards?)

You’d have to see which bean was touching what other beans - either by comparing a “square” to the squares around it, or, if using physics, to keep track of collisions and colors. [import]uid: 52491 topic_id: 22063 reply_id: 87820[/import]

Yes I’m trying to keep track of collisions with the following function. It seems to be recording matches in a table called beans[].touching[]

Im now not sure how to retrieve the information and remove the display objects.

obj is the bean name

beanType is the colour

tableRef is the table row number of the bean involved in the collision.

[code]
function beanCheck(event)
local obj1 = event.object1.myName;
local obj2 = event.object2.myName;
local beanType1 = event.object1.beanType;
local beanType2 = event.object2.beanType;
local tableRef1 = event.object1.tRef;
local tableRef2 = event.object2.tRef;
if(event.phase == “began”) then
if(beanType1 == beanType2) then
if (#beans[tableRef1].touching > 0) then
inTable = false;
for k=1,#beans[tableRef1].touching do
if (beans[tableRef1].touching[k] == obj2) then
inTable = true;
–print (“existing”);
end
end
if(inTable == false) then
beans[tableRef1].touching[#beans[tableRef1].touching+1] = obj2;
–print (“additional add”);
end
else
beans[tableRef1].touching[1] = obj2;
–print (“new add”);
end
if (#beans[tableRef2].touching > 0) then
inTable = false;
for k=1,#beans[tableRef2].touching do
if (beans[tableRef2].touching[k] == obj1) then
inTable = true;
–print (“existingobj2”);
end
end
if(inTable == false) then
beans[tableRef2].touching[#beans[tableRef2].touching+1] = obj1;
–print (“additional addobj2”);
end
else
beans[tableRef2].touching[1] = obj1;
–print (“new addobj2”);
end
if(#beans[tableRef1].touching >= 3) then
for k=1,#beans[tableRef1].touching do
if(beans[tableRef1].touching[k] ~= nil) then
–print (beans[tableRef1].touching[k]);
local test = beans[tableRef1].touching[k];
–beans[tableRef1].touching[k]:removeSelf();
–bean1:removeSelf();
print(test);
beans[tableRef1].touching[k] = nil;
end
end
end
end
end
if(event.phase == “ended”) then
if(beanType1 == beanType2) then
if (#beans[tableRef1].touching > 0) then
for k=1,#beans[tableRef1].touching do
if (beans[tableRef1].touching[k] == obj2) then
beans[tableRef1].touching[k] = nil;
–print (“removed”);
end
end
end
if (#beans[tableRef2].touching > 0) then
for k=1,#beans[tableRef2].touching do
if (beans[tableRef2].touching[k] == obj1) then
beans[tableRef2].touching[k] = nil;
–print (“removedobj2”);
end
end
end
end
end
end

[/code] [import]uid: 31694 topic_id: 22063 reply_id: 87826[/import]

I more or less understand the logic;

check if #beans[].touching >= 3 and if so check the tables of all entries to see if they contain any matches and then remove all.

I’m unsure about how to actually impliment this and do the remove. [import]uid: 31694 topic_id: 22063 reply_id: 87827[/import]

Anyone? [import]uid: 31694 topic_id: 22063 reply_id: 88357[/import]

Hey there, I did see I have an email from you I just haven’t had a chance to read it yet. (I get a lot of emails so it can take a bit.)

In doing the remove you’d likely need to drop down objects, if so you’d need to work out which column was effected, how many beans were removed and then move each bean which is higher and in the same column downward.

I wonder if it might be easiest to have each column be it’s own table… Hmmm.

There are various ways you could go about it, the best way to find out what meshes with your thinking style is to try pseudo code - writing out the logic of what you are doing, then writing code that fits that logic. [import]uid: 52491 topic_id: 22063 reply_id: 88414[/import]

Apologies, I am picturing this in a very certain way and clearly it’s not quite right.

Bookmarked that link; if I find myself with any time over the next day or two will do my best to take a look. [import]uid: 52491 topic_id: 22063 reply_id: 88574[/import]

Thanks a lot. If you do get a chance you will see the beans falling very fast. This is just for testing and I will change the timing later. [import]uid: 31694 topic_id: 22063 reply_id: 88620[/import]

Unfortunately the affect I am going for is to not have columns. I want the physics to make the beans roll naturally. Maybe if you have time you could take a look at what I have so far in the simulator?
[import]uid: 31694 topic_id: 22063 reply_id: 88420[/import]

Hey, have not yet had the chance to delve into this, however I just saw this thread and thought you may try to chat with the developer - it seems they have created something similar and may have some valuable insight: http://developer.anscamobile.com/forum/2012/03/12/zwyper-ipad-free-puzzle-game-available-app-store [import]uid: 52491 topic_id: 22063 reply_id: 92960[/import]