Flood It

has any one created code for this game:
http://floodit.appspot.com
It’s called many different things, but I just wanted to know if it’s possible to create this in codea.
I would really need some help because I’m new to coding at 15 years old. Thanks

pretty interesting game. It’s a good codea project indeed.

this is a very cool game. Have been playing a vs the computer version and seems like there’s a lot of strategy

Here you go, in 80 lines. Just had to code it after seeing this post. Had fun doing it. Didn’t realize the flood fill algo could be so simple (Go recurrsion!).

function setup()
    displayMode(FULLSCREEN)
    
    grid = {}  
    turnsLeft = 25
    
    local r,c
    for r = 1,14 do
        grid[r] = {}
        for c = 1,14 do
            grid[r][c] = math.random(6)
        end
    end
    
    colors = {}
    colors[1] = color(255, 0, 0, 255)
    colors[2] = color(0, 0, 255, 255)
    colors[3] = color(0, 255, 0, 255)
    colors[4] = color(255, 255, 0, 255)
    colors[5] = color(255, 0, 255, 255)
    colors[6] = color(0, 255, 255, 255)
end

function draw()
    background(40, 40, 50)

    pushStyle()
    noSmooth()
    local r,c,col
    for r, row in ipairs(grid) do
        for c, cellVal in ipairs(row) do
            col = colors[cellVal]
            fill(col.r, col.g, col.b)
            rect(((c - 1) * 50) + 300, ((r - 1) * 50) + 25, 50, 50)
        end
    end
    popStyle()
    
    pushStyle()
    strokeWidth(3)
    stroke(255, 255, 255, 255)
    for c, col in ipairs(colors) do
        fill(col.r, col.g, col.b)
        ellipse(150, ((c - 1) * 120) + 100, 100)
    end
    popStyle()
    
    text(turnsLeft, 15, HEIGHT - 15)
end

function touched(touch)
    
    if touch.state == ENDED and turnsLeft > 0 then
        local x,y,c
        x = 150
        for c in ipairs(colors) do
            y = ((c - 1) * 120) + 100
            if lineDist(x, y, touch.x, touch.y) <= 50 then
                floodFill(grid, 14, 1, grid[14][1], c)
                turnsLeft = turnsLeft - 1
            end
        end
    end
end

function lineDist(x1, y1, x2, y2)
    return math.sqrt(((x2 - x1)^2) + ((y2 - y1)^2))
end

function floodFill(grid, row, col, target, new)
    if row < 1 or col < 1 or row > #grid or col > #grid[row] then return end
    
    if grid[row][col] == target then
        grid[row][col] = new
        floodFill(grid, row + 1, col, target, new)
        floodFill(grid, row - 1, col, target, new)
        floodFill(grid, row, col + 1, target, new)
        floodFill(grid, row, col - 1, target, new)
    end
end

@Eric, that’s short and looks good too, very nice. Now i want a two player version with an AI that beats me every time. I downloaded a feel free apps, none had two player versions.

@ruilov that’s exactly what I was thinking of. Maybe an iPad app and the two different players would have the same puzzle and first one to finish with the least moves wins. I haven’t even downloaded the app yet b/c I don’t have enough money. Looking forward to it now!

@veeeralp, here’s the one I was playing: http://games.snewzbutton.com/2009/10/flood-it/

there is (was?) an app named “battleflood” in the app store that was 2 player this - but it broke in ios5 (got really really slow) and is apparently unmaintained. I liked it - I’d play a 2 player version.

Hi All,

Been working on this, not complete yet - needs tidying and debugging but playable. Here’s my latest version. Will put on GitHub and post when updates available:

function setup()
    displayMode(FULLSCREEN)
    
    grid = {}  
    turnsStart = 25
    turnsUsed = 0
    turnsLeft = turnsStart - turnsUsed
    -- using a multiple of 14 for the cells used in cellNo
    cellNo = 14
    cellW = 48*14/cellNo
    gridWidth = cellNo*cellW  
    offsetLeft = (WIDTH - gridWidth)/2
    offsetTop = (HEIGHT - gridWidth)/2
    totCells = cellNo*cellNo
    maxCells = 0
    midX = WIDTH/2
    midY = HEIGHT/2
    
    local r,c
    for r = 1,56 do
        grid[r] = {}
        for c = 1,56 do
            grid[r][c] = math.random(6)
        end
    end
    
    colors = {}
    colors[1] = color(255, 0, 0, 255)
    colors[2] = color(0, 0, 255, 255)
    colors[3] = color(0, 255, 0, 255)
    colors[4] = color(255, 255, 0, 255)
    colors[5] = color(255, 0, 255, 255)
    colors[6] = color(0, 255, 255, 255)
    
    colNumber = {}
    statReset()
end

function draw()
    background(40, 40, 50)
    gridDraw()    
    selectors()
    
    font("Georgia-Bold")
    fontSize(72)
    fill(255, 0, 4, 255)
    text("Flood-it", midX, HEIGHT-72)
    fontSize(16)
    text("You have used "..turnsUsed.." turns from "..turnsStart.." in "..totCells.." tiles", midX, HEIGHT - 150)
    if maxCells == totCells then
        messageWin()
    elseif turnsLeft == 0 then
        messageLose()
    end
end

function touched(touch)
    
    if touch.state == ENDED and turnsLeft > 0 then
        local x,y,c
        y = 100
        for c in ipairs(colors) do
            x = ((c - 1) * 120) + 100
            if lineDist(x, y, touch.x, touch.y) <= 50 then
                floodFill(grid, cellNo, 1, grid[cellNo][1], c)
                turnsUsed = turnsUsed + 1
                turnsLeft = turnsStart - turnsUsed
            end
        end
        statReset()
        colourStats()
    end
end

function lineDist(x1, y1, x2, y2)
    return math.sqrt(((x2 - x1)^2) + ((y2 - y1)^2))
end

function floodFill(grid, row, col, target, new)
    if row < 1 or col < 1 or row > cellNo or col > cellNo then return end
    
    if grid[row][col] == target then
        grid[row][col] = new
        floodFill(grid, row + 1, col, target, new)
        floodFill(grid, row - 1, col, target, new)
        floodFill(grid, row, col + 1, target, new)
        floodFill(grid, row, col - 1, target, new)
    end
end

function selectors()
    pushStyle()
    strokeWidth(3)
    stroke(255, 255, 255, 255)
    for c, col in ipairs(colors) do
        fill(col.r, col.g, col.b)
        ellipse(((c - 1) * 120) + 100, 100, 50)
        fill(0, 0, 0, 255)
        text(colNumber[c],((c - 1) * 120) + 100, 100)
    end
    popStyle()  
end

function gridDraw()
    pushStyle()
        noSmooth()
        fill(0, 0, 0, 255)
        rect(offsetLeft-10, offsetTop-10,WIDTH-offsetLeft-28,HEIGHT-offsetTop-156)
        strokeWidth(3)
        stroke(248, 2, 47, 255)
rect(offsetLeft-10, offsetTop-10,WIDTH-offsetLeft-28,HEIGHT-offsetTop-156)    
        noStroke()  
        local r,c,col
        for r = 1, cellNo do
            for c = 1, cellNo do
                cellVal = grid[r][c]
                col = colors[cellVal]
                fill(col.r, col.g, col.b)
                rect(((c - 1) * cellW) + offsetLeft, ((r - 1) * cellW) + offsetTop, cellW, cellW)
            end
        end
    popStyle()
end

function colourStats()
    local r,c, l
    for r = 1, cellNo do
        for c = 1, cellNo do
            cellVal = grid[r][c]
            colNumber[cellVal] = colNumber[cellVal] + 1
        end
    end
    maxCells = colNumber[1]
    for l = 2,6 do
        if maxCells < colNumber[l] then
            maxCells = colNumber[l]
        end
    end
end

function statReset()
    local l
    for l = 1,6 do
        colNumber[l] = 0
    end 
end

function messageWin()
    pushStyle()
        fill(124, 108, 45, 255)
        rect(midX-200, midY-200, 400, 400)
        fill(215, 212, 165, 255)
        rect(midX-197, midY-197, 394, 394)
        font("Georgia-Bold")
        fontSize(32)
        fill(0,0,0,255)
        text("CONGRATULATIONS", WIDTH/2, midY+160)
        fontSize(18)
        text("You completed the target of : "..totCells.." tiles", WIDTH/2, midY+130)
        text("In a total of : "..turnsUsed.." moves", WIDTH/2, midY+110)     
        
    popStyle() 
end

function messageLose()
    pushStyle()
        fill(124, 108, 45, 255)
        rect(midX-200, midY-200, 400, 400)
        fill(215, 212, 165, 255)
        rect(midX-197, midY-197, 394, 394)
        font("Georgia-Bold")
        fontSize(32)
        fill(0,0,0,255)        
        text("HARD LUCK", WIDTH/2, midY+160)
        fontSize(18)       
        text("You converted a total of : "..maxCells.." tiles", WIDTH/2, midY+130)
        text("From a target of : "..totCells.." tiles", WIDTH/2, midY+110)
        text("Which is a percentage of : "..maxCells*100/totCells.."%", WIDTH/2, midY+90)
    popStyle()
end

Hope you like it.

Any suggestions for bugs - please feel free to make any suggestions.

Bri_G

:slight_smile:

@Bri_G my only suggestion would be to fix the orientation. This causes a problem because then the text blends in.

Hi @veeeralp,

Thanks for the feedback. One of my objectives is to enable running in any mode. But, first I’d like to get the system optimised. So, when you say text merging in - at which point is it merging. The reporting of stats etc, at the end, is not finished.

There may be other Codea users making their own versions, it will be interesting to see what they have made.

Thanks,

Bri_G

:slight_smile:

this is mine

function setup()
    displayMode(FULLSCREEN_NO_BUTTONS)
    
    supportedOrientations(LANDSCAPE_ANY)
    
    grid = {}  
    turnsLeft = 25
    
    local r,c
    for r = 1,14 do
        grid[r] = {}
        for c = 1,14 do
            grid[r][c] = math.random(6)
        end
    end
    
    colors = {}
    colors[1] = color(255, 0, 0, 255)
    colors[2] = color(0, 0, 255, 255)
    colors[3] = color(0, 255, 0, 255)
    colors[4] = color(255, 255, 0, 255)
    colors[5] = color(255, 0, 255, 255)
    colors[6] = color(117, 38, 137, 0)
end

function draw()
    background(255, 255, 255, 255)

    pushStyle()
    noSmooth()
    local r,c,col
    for r, row in ipairs(grid) do
        for c, cellVal in ipairs(row) do
            col = colors[cellVal]
            fill(col.r, col.g, col.b)
            rect(((c - 1) * 50) + 300, ((r - 1) * 50) + 25, 50, 50)
        end
    end
    popStyle()
    pushStyle()    
    strokeWidth(0)
    stroke(255, 255, 255, 255)
    for c, col in ipairs(colors) do
        fill(col.r, col.g, col.b)
        ellipse(150, ((c-1) * 120) + 74, 100)
    end
    
    
    popStyle()
    rotate(90)
    font("HelveticaNeue-Light")
    fill(235, 234, 235, 255)
    fontSize(102)
    text("Flood It", 368, -50)
    
    popStyle()
    font("HelveticaNeue-Light")
    fill(235, 234, 235, 255)
    fontSize(72)
    text("Veeral Patel", 368, -248)
    
    popStyle()
    rotate(-90)
    font("HelveticaNeue-Light")
    fontSize(43)
    fill(127, 127, 127, 255)
    text(turnsLeft, 649, HEIGHT - 23)
end

function touched(touch)
    
    if touch.state == ENDED and turnsLeft > 0 then
        local x,y,c
        x = 150
        for c in ipairs(colors) do
            y = ((c - 1) * 120) + 100
            if lineDist(x, y, touch.x, touch.y) <= 50 then
                floodFill(grid, 14, 1, grid[14][1], c)
                turnsLeft = turnsLeft - 1
            end
        end
    end
end

function lineDist(x1, y1, x2, y2)
    return math.sqrt(((x2 - x1)^2) + ((y2 - y1)^2))
end

function floodFill(grid, row, col, target, new)
    if row < 1 or col < 1 or row > #grid or col > #grid[row] then return end
    
    if grid[row][col] == target then
        grid[row][col] = new
        floodFill(grid, row + 1, col, target, new)
        floodFill(grid, row - 1, col, target, new)
        floodFill(grid, row, col + 1, target, new)
        floodFill(grid, row, col - 1, target, new)
    end
end




anyone know how to implement a shake to restart feature into this game. Would be awesome

to reset. Triple tap the left side with three fingers

Hi veeeralp,

Thanks for that - nice package. I’m going to try to get my code so it can be used in whichever orientation you choose.

Bri_G

:slight_smile:

@veeeralp, I wrote a shake detector for cargo bot, and works ok but in the end I took it out because I tried using while traveling in a car and it kept triggering. With that disclaimer, code is here: https://github.com/ruilov/CargoBot/blob/master/ShakeDetector.lua

@Bri_G I updated my code.

function setup()
    displayMode(FULLSCREEN_NO_BUTTONS)
    
    supportedOrientations(LANDSCAPE_ANY)
    
    grid = {}  
    turnsLeft = 25
    
    local r,c
    for r = 1,15 do
        grid[r] = {}
        for c = 1,17 do
            grid[r][c] = math.random(6)
        end
    end
    
    colors = {}
    colors[1] = color(255, 0, 0, 255)
    colors[2] = color(0, 0, 255, 255)
    colors[3] = color(0, 255, 0, 255)
    colors[4] = color(255, 255, 0, 255)
    colors[5] = color(255, 0, 255, 255)
    colors[6] = color(117, 38, 137, 0)
end

function draw()
    background(135,206,249,255)

    pushStyle()
    noSmooth()
    local r,c,col
    for r, row in ipairs(grid) do
        for c, cellVal in ipairs(row) do
            col = colors[cellVal]
            fill(col.r, col.g, col.b)
            rect(((c - 1) * 50) + 164, ((r - 1) * 50) + 9, 50, 50)
        end
    end
    popStyle()
    pushStyle()    
    strokeWidth(3)
    stroke(255, 255, 255, 255)
    for c, col in ipairs(colors) do
        fill(col.r, col.g, col.b)
        ellipse(81, ((c-1) * 120) + 85, 130)
        rect(16, ((c-1) * 120) + 20, 130,130)
        
    end
    
    popStyle()
    font("ArialMT")
    fontSize(43)
    fill(255, 255, 255, 146)
    text(turnsLeft, 505, HEIGHT - 27)
    
    popStyle()
    font("ArialMT")
    fontSize(43)
    fill(255, 255, 255, 146)
    text("turns left", 618, HEIGHT - 27)
    
    popStyle()
    font("ArialMT")
    fontSize(140)
    fill(255, 255, 255, 146)
    text("FLOOD IT", 585, HEIGHT - 388)
    
    popStyle()
    font("ArialMT")
    fontSize(55)
    fill(255, 255, 255, 146)
    text("VEERAL PATEL", 593, HEIGHT - 740)
    
   
end

function touched(touch)
    
    if touch.state == ENDED and turnsLeft > 0 then
        local x,y,c
        x = 81
        for c in ipairs(colors) do
            y = ((c - 1) * 120) + 85
            if lineDist(x, y, touch.x, touch.y) <= 50 then
                floodFill(grid, 14, 1, grid[14][1], c)
                turnsLeft = turnsLeft - 1
            end
        end
    end
end

function lineDist(x1, y1, x2, y2)
    return math.sqrt(((x2 - x1)^2) + ((y2 - y1)^2))
end

function floodFill(grid, row, col, target, new)
    if row < 1 or col < 1 or row > #grid or col > #grid[row] then return end
    
    if grid[row][col] == target then
        grid[row][col] = new
        floodFill(grid, row + 1, col, target, new)
        floodFill(grid, row - 1, col, target, new)
        floodFill(grid, row, col + 1, target, new)
        floodFill(grid, row, col - 1, target, new)
    end
end







@veeeralp, nice! I think, it’s better to let the buttons on the screen to reset the game :smiley:

can anyone help with a reset button and some code for it to say “congrats, you win” when the game is over and all of the cells are one color. I worked out one for it to say you lose but can’t get the winning label to work. Also, how would you play 1 sound when some wins/loses. I tried but it keeps on playing the sound over and over again. Thanks. Code is attached for help.

function setup()
    displayMode(FULLSCREEN_NO_BUTTONS)
    
    supportedOrientations(LANDSCAPE_ANY)
    
    grid = {}  
    turnsStart = 25
    turnsUsed = 0
    turnsLeft = turnsStart- turnsUsed
    totCells = 15*17
    maxCells = 0
    

    local r,c
    for r = 1,15 do
        grid[r] = {}
        for c = 1,17 do
            grid[r][c] = math.random(6)
        end
    end
    
    colors = {}
    colors[1] = color(255, 0, 0, 255)
    colors[2] = color(0, 0, 255, 255)
    colors[3] = color(0, 255, 0, 255)
    colors[4] = color(255, 255, 0, 255)
    colors[5] = color(255, 0, 255, 255)
    colors[6] = color(117, 38, 137, 0)
    
end
function colourStats()
    local r,c, l
    for r = 1, cellNo do
        for c = 1, cellNo do
            cellVal = grid[r][c]
            colNumber[cellVal] = colNumber[cellVal] + 1
        end
    end
    maxCells = colNumber[1]
    for l = 2,6 do
        if maxCells < colNumber[l] then
            maxCells = colNumber[l]
        end
    end
end
function draw()
    background(135,206,249,255)

    pushStyle()
    noSmooth()
    local r,c,col
    for r, row in ipairs(grid) do
        for c, cellVal in ipairs(row) do
            col = colors[cellVal]
            fill(col.r, col.g, col.b)
            rect(((c - 1) * 50) + 164, ((r - 1) * 50) + 9, 50, 50)
        end
    end
    popStyle()
    pushStyle()    
    strokeWidth(4)
    stroke(255, 255, 255, 255)
    for c, col in ipairs(colors) do
        fill(col.r, col.g, col.b)
        rect(16, ((c-1) * 120) + 20, 130,130)
        
    end
    
    popStyle()
    font("ArialMT")
    fontSize(43)
    fill(255, 255, 255, 146)
    text(turnsLeft, 505, HEIGHT - 27)
    
    popStyle()
    font("ArialMT")
    fontSize(43)
    fill(255, 255, 255, 146)
    text("turns left", 618, HEIGHT - 27)
    
    popStyle()
    font("ArialMT")
    fontSize(140)
    fill(255, 255, 255, 85)
    text("FLOOD IT", 585, HEIGHT - 388)
    
    popStyle()
    font("ArialMT")
    fontSize(55)
    fill(255, 255, 255, 0)
    text("VEERAL PATEL", 593, HEIGHT - 740)
    
    timeLeft = os.difftime(91 - ElapsedTime)
    
    popStyle()
    font("ArialMT")
    fontSize(43)
    fill(255, 255, 255,  146)
    text(timeLeft, 589, HEIGHT - 740)
    
    if timeLeft == 0 then
        messageLose()
    end
    if maxCells == totCells then
        messageWin()
    elseif turnsLeft == 0 then
        messageLose()
    end
end

function lineDist(x1, y1, x2, y2)
    return math.sqrt(((x2 - x1)^2) + ((y2 - y1)^2))
end

function floodFill(grid, row, col, target, new)
    if row < 1 or col < 1 or row > #grid or col > #grid[row] then return end
    
    if grid[row][col] == target then
        grid[row][col] = new
        floodFill(grid, row + 1, col, target, new)
        floodFill(grid, row - 1, col, target, new)
        floodFill(grid, row, col + 1, target, new)
        floodFill(grid, row, col - 1, target, new)
    end
end

function touched(touch)
    
    if touch.state == ENDED and turnsLeft > 0 then
        local x,y,c
        x = 81
        for c in ipairs(colors) do
            y = ((c - 1) * 120) + 85
            if lineDist(x, y, touch.x, touch.y) <= 50 then
                floodFill(grid, 15, 1, grid[15][1], c)
                turnsLeft = turnsLeft - 1
            end
        end
    end
end



function messageWin()
    pushStyle()
        font("ArialMT")
        fontSize(54)
        fill(30, 125, 36, 255)
        text("CONGRATULATIONS, YOU WIN!", 585, HEIGHT - 263)
    popStyle() 
end

function messageLose()
    pushStyle()
        font("ArialMT")
        fontSize(54)
        fill(183, 31, 31, 255)        
        text("SORRY, YOU LOSE!", 585, HEIGHT - 263)
    popStyle()
end