Match Game 2

Here’s another match game I made because I didn’t have anything better to do. The object is to match up each square so the value on each edge matches the value on the edge next to it. If you match all the squares, a double tap will take you to the next level. The game starts with a 2x2 board. Once solved, it goes to a 3x3, 4x4, etc. An 11x11 board fits on my iPad Air. An even bigger board will show on an iPad Pro 14x14. To move the squares, tap a square, it turns green, then tap the square you want to swap it with. The board turns yellow when it’s solved and a double tap takes you to the next level. If you tap a square by mistake, just tap it a second time. The level is saved so you can pick up at the level you left off. The board isn’t saved, so if you stop in the middle of a game, you’ll start a new game at the last level.

The games I’ve been making aren’t that great, they’re mostly just for new coders to see how to do some things.

Updated code below.

@dave1707 - woaaah, nice idea. Did the first two levels OK, after that mind boggling.

@Bri_G I’ve been playing the game mostly to make sure that everything works OK. I’m currently starting level 8. There have been a few times where I thought things were messed up because I couldn’t match some squares and I got stuck. Turns out the squares that I matched weren’t in the order they were supposed to be in even though they lined up. So I guess as the board gets larger, you can match up sections of squares that seem correct, but they won’t result in a solution. You then have to give up on them and match other squares and go from there. So as the board get larger, it starts to get a lot harder because you can go down a wrong path. I was thinking about allowing a movable board so if it’s bigger than the screen, you can slide it around to see it all. I’m not sure at what size it might be to hard to solve.

@dave1707 - my biggest problem with it is I can build up a section but find it’s in the wrong position, so I have to move each square individually to reposition the section elsewhere. Would be better if you could highlight a section and drag it to where you think it should go - you’d need to lock that section to do it and the others would have to flow round it when it was moved.
Also, it seems a bit odd just playing in the bottom corner - would look better centred.

@Bri_G Here’s updated code that will center the board on the screen for each level. Selecting a large group of squares and moving them all at once isn’t going to happen. That would take a lot of coding and more than I want to put into this. This game was mostly something to do while I was watching reruns on TV waiting for something new to come on. If anyone else wants to expand on this, feel free to do so.

When I try to solve a level, I generally do a row or column first. Then I go at a right angle to what I did so I can determine if I have to shift what I did so far. That way I’m not shifting large sections at once.

viewer.mode=FULLSCREEN

function setup()
    --clearProjectData()    -- reset level back to 2
    cubes=readProjectData("cubes",2)
    rectMode(CENTER)
    size=70
    setup2()
end

function setup2()
    dx=(WIDTH-(size*cubes))//2-size//2
    dy=(HEIGHT-(size*cubes))//2-size//2
    xSize,ySize=cubes,cubes
    s1,s2=vec2(0,0),vec2(0,0)
    tab={}
    for x=1,xSize do
        tab[x]={}
        for y=1,ySize do
            tab[x][y]=sqr(x*size,y*size)
        end
    end
    for x=1,xSize do
        for y=1,ySize do
            if x==1 then
                tab[x][y].left=math.random(10,99)
                tab[x][y].right=math.random(10,99)
            else
                tab[x][y].left=tab[x-1][y].right
                tab[x][y].right=math.random(10,99)
            end
            if y==1 then
                tab[x][y].bottom=math.random(10,99)
                tab[x][y].top=math.random(10,99)
            else
                tab[x][y].bottom=tab[x][y-1].top
                tab[x][y].top=math.random(10,99)
            end
        end
    end
    for z=1,100 do
        x1=math.random(xSize)
        y1=math.random(ySize)
        x2=math.random(xSize)
        y2=math.random(ySize)
        swap(x1,y1,x2,y2)
    end
end

function swap(x1,y1,x2,y2)
    left=tab[x2][y2].left
    right=tab[x2][y2].right
    top=tab[x2][y2].top
    bottom=tab[x2][y2].bottom
    cen=tab[x2][y2].cen
    
    tab[x2][y2].left=tab[x1][y1].left
    tab[x2][y2].right=tab[x1][y1].right
    tab[x2][y2].top=tab[x1][y1].top
    tab[x2][y2].bottom=tab[x1][y1].bottom
    tab[x2][y2].cen=tab[x1][y1].cen
    
    tab[x1][y1].left=left
    tab[x1][y1].right=right
    tab[x1][y1].top=top
    tab[x1][y1].bottom=bottom
    tab[x1][y1].cen=cen
end

function draw()
    background(172, 216, 223, 255)
    fontSize(18)
    for x=1,xSize do
        for y=1,ySize do
            tab[x][y]:draw()
        end
    end
    if corr then
        fontSize(30)
        fill(255, 0, 0)
        text("Double tap for next level",WIDTH/2,HEIGHT-100)
    end
end

function touched(t)
    if t.state==BEGAN then
        if t.tapCount==2 and corr then
            cubes=cubes+1
            saveProjectData("cubes",cubes)
            corr=false
            setup2()
        end
        if t.x<WIDTH/2 and t.y>HEIGHT-100 and corr then
            xSize=xSize+1
            ySize=ySize+1
            corr=false
            setup2()
            return
        end
        for x=1,xSize do
            for y=1,ySize do
                tab[x][y]:touched(t)
            end
        end
    end
end

function checkCorrect()
    corr=true
    for x=2,xSize do
        for y=2,ySize do
            if tab[x][y].left~=tab[x-1][y].right then
                corr=false
            end
            if tab[x][y].bottom~=tab[x][y-1].top then
                corr=false
            end
        end
    end
end


sqr = class()

function sqr:init(x,y,c)
    self.x=x
    self.y=y
    self.left=0
    self.right=0
    self.top=0
    self.bottom=0
end

function sqr:draw()
    fill(255)
    if corr then
        fill(255, 255, 0, 255)
    end
    if s1.x==self.x and s1.y==self.y then
        fill(0, 255, 13, 255)
    end
    rect(self.x+dx,self.y+dy,size-2,size-2)
    fill(255,0,0)
    text(self.left,self.x-size/3.5+dx,self.y+dy)
    text(self.right,self.x+size/3.5+dx,self.y+dy)
    text(self.top,self.x+dx,self.y+size/3.5+dy)
    text(self.bottom,self.x+dx,self.y-size/3.5+dy)
end

function sqr:touched(t)
    if t.x>self.x-size/2+dx and t.x<self.x+size/2+dx and
            t.y>self.y-size/2+dy and t.y<self.y+size/2+dy then
        if s1.x==0 then
            s1=vec2(self.x,self.y)
        else
            s2=vec2(self.x,self.y)
            swap(s1.x/size,s1.y/size,s2.x/size,s2.y/size)
            s1,s2=vec2(0,0),vec2(0,0)
            checkCorrect()
        end
    end
end

@dave1707 - ran into some confusion when trying to re-arrange the number squares - didn’t seem to have the same squares. So dragged up from the bottom to get app menu bar and capture screen dialogue bar appeared. On pressing no thanks Codea crashed. Captured screen before answering dialogue box - attached. @Simeon , second time this has occurred when running this code.

@Bri_G The allow screen recording crashes on any Codea code I try it on. Also, if I select record, it doesn’t do anything.

@dave1707 - that’s what I meant about legacy code. Old code no longer used that needs removing and documenting in the wiki about using the iOS / iPadOS system for grabbing images/video.

Made a change to save the board layout. The reason was as I got into the higher levels ( currently at 11), it would take longer than I wanted to work on it and when I closed Codea, I would lose what I had done so far. Now, I can come back at a later time and pickup where I left off.

viewer.mode=FULLSCREEN

function setup()
    --saveProjectData("cubes",2)        -- set start size to 2
    --saveProjectData("stab",nil)       -- clear board save table
    cubes=readProjectData("cubes",2)
    rectMode(CENTER)
    size=70
    setup2()
end

function setup2()
    dx=(WIDTH-(size*cubes))//2-size//2
    dy=(HEIGHT-(size*cubes))//2-size//2
    xSize,ySize=cubes,cubes
    s1,s2=vec2(0,0),vec2(0,0)
    tab={}
    for x=1,xSize do
        tab[x]={}
        for y=1,ySize do
            tab[x][y]=sqr(x*size,y*size)
        end
    end
    ss=readProjectData("stab")
    if ss~=nil then
        fillBoard()
    else
        randomBoard()
    end
end

function fillBoard()
    sTab=json.decode(ss)
    pos=0
    for x=1,xSize do
        for y=1,ySize do
            tab[x][y].left=sTab[pos+1]
            tab[x][y].right=sTab[pos+2]
            tab[x][y].top=sTab[pos+3]
            tab[x][y].bottom=sTab[pos+4]
            pos=pos+4
        end
    end 
end
    
function randomBoard()
    for x=1,xSize do
        for y=1,ySize do
            if x==1 then
                tab[x][y].left=math.random(10,99)
                tab[x][y].right=math.random(10,99)
            else
                tab[x][y].left=tab[x-1][y].right
                tab[x][y].right=math.random(10,99)
            end
            if y==1 then
                tab[x][y].bottom=math.random(10,99)
                tab[x][y].top=math.random(10,99)
            else
                tab[x][y].bottom=tab[x][y-1].top
                tab[x][y].top=math.random(10,99)
            end
        end
    end
    for z=1,100 do
        x1=math.random(xSize)
        y1=math.random(ySize)
        x2=math.random(xSize)
        y2=math.random(ySize)
        swap(x1,y1,x2,y2)
    end
    saveTab()
end

function swap(x1,y1,x2,y2)
    left=tab[x2][y2].left
    right=tab[x2][y2].right
    top=tab[x2][y2].top
    bottom=tab[x2][y2].bottom
    
    tab[x2][y2].left=tab[x1][y1].left
    tab[x2][y2].right=tab[x1][y1].right
    tab[x2][y2].top=tab[x1][y1].top
    tab[x2][y2].bottom=tab[x1][y1].bottom
    
    tab[x1][y1].left=left
    tab[x1][y1].right=right
    tab[x1][y1].top=top
    tab[x1][y1].bottom=bottom
end

function draw()
    background(172, 216, 223, 255)
    fontSize(18)
    for x=1,xSize do
        for y=1,ySize do
            tab[x][y]:draw()
        end
    end
    if corr then
        fontSize(30)
        fill(255, 0, 0)
        text("Double tap for next level",WIDTH/2,HEIGHT-100)
    end
end

function saveTab()
    sTab={}
    for x=1,xSize do
        for y=1,ySize do
            l=tab[x][y].left
            r=tab[x][y].right
            t=tab[x][y].top
            b=tab[x][y].bottom
            table.insert(sTab,l)
            table.insert(sTab,r)
            table.insert(sTab,t)
            table.insert(sTab,b)
        end
    end
    sss=json.encode(sTab)
    saveProjectData("stab",sss)
end

function touched(t)
    if t.state==BEGAN then
        if t.tapCount==2 and corr then
            cubes=cubes+1
            saveProjectData("cubes",cubes)
            corr=false
            saveProjectData("stab",nil)
            setup2()
        end
        if t.x<WIDTH/2 and t.y>HEIGHT-100 and corr then
            xSize=xSize+1
            ySize=ySize+1
            corr=false
            setup2()
            return
        end
        for x=1,xSize do
            for y=1,ySize do
                tab[x][y]:touched(t)
            end
        end
    end
end

function checkCorrect()
    corr=true
    for x=2,xSize do
        for y=2,ySize do
            if tab[x][y].left~=tab[x-1][y].right then
                corr=false
            end
            if tab[x][y].bottom~=tab[x][y-1].top then
                corr=false
            end
        end
    end
end


sqr = class()

function sqr:init(x,y,c)
    self.x=x
    self.y=y
    self.left=0
    self.right=0
    self.top=0
    self.bottom=0
end

function sqr:draw()
    fill(255)
    if corr then
        fill(255, 255, 0, 255)
    end
    if s1.x==self.x and s1.y==self.y then
        fill(0, 255, 13, 255)
    end
    rect(self.x+dx,self.y+dy,size-2,size-2)
    fill(255,0,0)
    text(self.left,self.x-size/3.5+dx,self.y+dy)
    text(self.right,self.x+size/3.5+dx,self.y+dy)
    text(self.top,self.x+dx,self.y+size/3.5+dy)
    text(self.bottom,self.x+dx,self.y-size/3.5+dy)
end

function sqr:touched(t)
    if t.x>self.x-size/2+dx and t.x<self.x+size/2+dx and
            t.y>self.y-size/2+dy and t.y<self.y+size/2+dy then
        if s1.x==0 then
            s1=vec2(self.x,self.y)
        else
            s2=vec2(self.x,self.y)
            swap(s1.x/size,s1.y/size,s2.x/size,s2.y/size)
            s1,s2=vec2(0,0),vec2(0,0)
            checkCorrect()
            saveTab()
        end
    end
end

@dave1707 - great that’s the logical way forward with match game 2.

Have you considered using touch to change colour on a selected card - then touch another to be switch rather than dragging?

Thanks for the update - doubt wether I’ll reach your level.

Edit: Oops - this comment was meant for the first Match Game, not this one you’ve already added that to this one. Sorrs.

@Bri_G I’m not going to make any more changes to this. I completed level 12 and as I was doing the upper levels, I noticed that there wasn’t much of a challenge completing them. Once you started a game and got a few squares completed, you knew what the next square should be and it was just a matter of scanning the squares to find it. Then you just did that for the remaining squares until the board was solved. So it wasn’t a challenge or fun doing it anymore. I guess the fun part was writing the code.