Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Match game

dave1707dave1707 Mod
in Code Sharing Posts: 8,781

Here’s something I thru together just to pass the time. To play, touch an image and slide it up, down, left, or right one square to a matching image. The image you slide will disappear and any image above it will take it’s place. The object is to eliminate as many images as you can. The text will tell you how many images are left, your low score and how many valid moves are left. You’ll get a message when there are no more valid move and the game is over. It should work in landscape or portrait mode. This was written on an iPad Air, so I’m not sure what it looks like on a smaller or larger screen.

viewer.mode=FULLSCREEN

function setup()
    --clearProjectData()
    score=13*19
    xVal,yVal=19,13
    if HEIGHT>WIDTH then
        xVal,yVal=13,19
    end
    lowScore=readProjectData("lowScore",score)
    spr={asset.builtin.Planet_Cute.Character_Pink_Girl,
        asset.builtin.Planet_Cute.Character_Horn_Girl,
        asset.builtin.Planet_Cute.Character_Cat_Girl,
        asset.builtin.Planet_Cute.Character_Princess_Girl,
        asset.builtin.Planet_Cute.Character_Boy}    
    selected=0
    moves={-1,0,1,0,0,-1,0,1}
    tab={}
    for x=1,xVal do       
        tab[x]={}
        for y=1,yVal do
            tab[x][y]=math.random(5)
        end
    end
    checkPieces()
end

function draw()
    background(0)
    stroke(255)
    strokeWidth(2)
    fill(128)
    for x=1,xVal do
        for y=1,yVal do
            rect(x*50,y*50,52)
            if tab[x][y]>0 then
                sprite(spr[tab[x][y]],x*50+25,y*50+35,50)
            end
        end
    end
    fill(255)
    fontSize(20)
    text("Score  "..score.."    Low Score  "..string.format("%d",lowScore).."    Valid moves left  "..count,WIDTH/2,HEIGHT-10)
    if gameOver then
        fontSize(70)
        fill(255)
        text("NO MORE MOVES",WIDTH/2,HEIGHT/2)
    end
end

function touched(t)
    x=math.floor(t.x/50)
    y=math.floor(t.y/50)
    if x<1 or x>xVal or y<1 or y>yVal then
        fillGap()
        return
    end
    if t.state==BEGAN and tab[x][y]>0 then
        selected=tab[x][y]
        selX,selY=x,y
    end
    if t.state==ENDED and selected>0 then
        if validMove() and selected==tab[x][y] then
            tab[selX][selY]=0
            selected=0
            score=score-1
            checkScore()
        end
        fillGap()
    end
end

function validMove()
    if selX==x and (selY==y+1 or selY==y-1) then
        return true
    elseif selY==y and (selX==x+1 or selX==x-1) then
        return true
    end
    return false
end

function checkScore()
    if score<lowScore then
        lowScore=score
        saveProjectData("lowScore",lowScore)
    end    
end

function fillGap()
    for x=1,xVal do
        for y=1,yVal do
            if tab[x][y]==0 then
                for z=1,yVal-y do
                    if tab[x][y+z]~=0 then
                        tab[x][y]=tab[x][y+z]
                        tab[x][y+z]=0
                        break
                    end                   
                end
            end
        end
    end
    checkPieces()
end

function checkPieces()
    count=0
    gameOver=true
    for x=1,xVal do
        for y=1,yVal do
            if tab[x][y]>0 then
                for h=1,8,2 do
                    x1=x+moves[h]
                    y1=y+moves[h+1]
                    if x1>=1 and x1<=xVal and y1>=1 and y1<=yVal then
                        if tab[x][y]==tab[x1][y1] then
                            gameOver=false
                            count=count+1
                        end
                    end
                end                
            end
        end
    end
end

Comments

  • Posts: 1,958

    @dave1707 - neat but a touch frustrating. Perhaps an option to change the size of the images so you can move from easy to progressively harder. Also, some of the images are very similar making this hard on the eyes at time (my old eyes that is). Quite subtle in a way as you need to asses the effect of making a move on the surrounding images.

  • dave1707dave1707 Mod
    edited February 19 Posts: 8,781

    @Bri_G Here’s an updated version. I changed the images and added a size variable to alter the number of squares. Change the size value to something thats comfortable.

    PS. Removed clearProjectData and added a reset button in the upper right corner to reset the low score if you change the number of squares.

    PS. You have to look a little ahead to see how each move affects how some other moves can be made.

    viewer.mode=FULLSCREEN
    
    function setup()
        size=60     -- the smaller the number, the more squares
        rectMode(CENTER)
        spriteMode(CENTER)
        xs=(WIDTH//size)-1
        ys=(HEIGHT//size)-1
        score=xs*ys
        lowScore=readProjectData("lowScore",score)
        spr={asset.builtin.Planet_Cute.Key,
            asset.builtin.Planet_Cute.Tree_Ugly,
            asset.builtin.Planet_Cute.Heart,
            asset.builtin.Planet_Cute.Character_Princess_Girl,
            asset.builtin.Planet_Cute.Star}
        selected=0
        moves={-1,0,1,0,0,-1,0,1}
        tab={}
        for x=1,xs do       
            tab[x]={}
            for y=1,ys do
                tab[x][y]=math.random(5)
            end
        end
        checkPieces()
    end
    
    function draw()
        background(0)
        stroke(255)
        strokeWidth(2)
        fill(128)
        for x=1,xs do
            for y=1,ys do
                rect(x*size,y*size,size)
                if tab[x][y]>0 then
                    sprite(spr[tab[x][y]],x*size,y*size+10,size)
                end
            end
        end
        fontSize(20)
        fill(255)
        rect(WIDTH-30,HEIGHT-30,60,60)
        fill(0)
        text("reset",WIDTH-30,HEIGHT-10)
        text("low",WIDTH-30,HEIGHT-30)
        text("score",WIDTH-30,HEIGHT-50)
        fill(255)
        text("Score  "..score.."    Low Score  "..string.format("%d",lowScore).."    Moves left  "..count,WIDTH/2,HEIGHT-10)
        if gameOver then
            fontSize(40)
            fill(255)
            text("NO MORE MOVES",WIDTH/2,HEIGHT/2)
        end
    end
    
    function touched(t)
        if t.state==BEGAN and t.x>WIDTH-60 and t.y>HEIGHT-60 then
            lowScore=xs*ys
            saveProjectData("lowScore",lowScore)
            return
        end
        x=math.floor((t.x-size/2)/size)+1
        y=math.floor((t.y-size/2)/size)+1
        if x<1 or x>xs or y<1 or y>ys then
            fillGap()
            return
        end
        if t.state==BEGAN and tab[x][y]>0 then
            selected=tab[x][y]
            selX=x
            selY=y
        end
        if t.state==ENDED and selected>0 then
            if validMove() and selected==tab[x][y] then
                tab[selX][selY]=0
                selected=0
                score=score-1
                checkScore()
            end
            fillGap()
        end
    end
    
    function validMove()
        if selX==x and (selY==y+1 or selY==y-1) then
            return true
        elseif selY==y and (selX==x+1 or selX==x-1) then
            return true
        end
        return false
    end
    
    function checkScore()
        if score<lowScore then
            lowScore=score
            saveProjectData("lowScore",lowScore)
        end    
    end
    
    function fillGap()
        for x=1,xs do
            for y=1,ys do
                if tab[x][y]==0 then
                    for z=1,ys-y do
                        if tab[x][y+z]~=0 then
                            tab[x][y]=tab[x][y+z]
                            tab[x][y+z]=0
                            break
                        end                   
                    end
                end
            end
        end
        checkPieces()
    end
    
    function checkPieces()
        count=0
        gameOver=true
        for x=1,xs do
            for y=1,ys do
                if tab[x][y]>0 then
                    for h=1,8,2 do
                        x1=x+moves[h]
                        y1=y+moves[h+1]
                        if x1>=1 and x1<=xs and y1>=1 and y1<=ys then
                            if tab[x][y]==tab[x1][y1] then
                                gameOver=false
                                count=count+1
                            end
                        end
                    end                
                end
            end
        end
    end
    
  • Posts: 1,958

    @dave1707 - much better, image difference more pronounced and larger size better on the eye. I have a slight problem with the touch on the periphery response seems poor - noticed more on right side and bottom. May be down to my huge finger tips. Going to play with this - I think this could amuse the grandkids. Thanks.

  • dave1707dave1707 Mod
    Posts: 8,781

    @Bri_G One thing you can try is to touch a square, wait a fraction of a second, then slide it. You might be hitting the first touch on a slide and it’s not being recognized. I’m only looking for BEGAN or ENDED and not CHANGED in the touched function.

  • edited February 20 Posts: 1,958
    @dave1707 - that seemed to improve the response a little thanks.
    Ran into a couple of issues with it though. Firstly trying to modify code to use a path and array for loading sprites and the format I'm using wouldn't allow underscores in the Sprite name. Any way round that?
    Secondly, whilst playing the game I had a dialogue pop up about screen recording. May have hit the button bar in bottom corner, but didn't recognize the dialogue. On selecting the no option Codea crashed -wasn't expecting that. Do you think this may be due to old code in the latest version? I think most users use the iOS recording system now. An issue for @Simeon ?
Sign In or Register to comment.