tharkad on Games

  • Archive
  • RSS
  • Ask me anything

Can’t Stop Code

I put the finishing touches on the game today. Here is the code in case you want to give it a go in Codea. I learned Lua three days ago to get into Codea so I make no claims about how elegant the code is! I’m not sure if there is anything to really learn from this code but the game does work and is fun to play. Rules at http://en.wikipedia.org/wiki/Can’t_Stop_(board_game)

-- Can't Stop
-- Mike Houser

-- Use this function to perform your initial setup
function setup()
    max=700
    spacing=116
    transx=260
    dice={0,0,0,0}
    kChoosePlayers = 1
    kTurnStart = 2
    kDiceRolled = 3
    kSpotsPicked = 4
    kBusted = 5
    kGameOver = 6
    gamestate = kChoosePlayers
    playerrect = {{80,350,160,430},{80,250,160,330},{80,150,160,230},{80,50,160,130}}
    playercolor = {{0,0,255,255},{255,0,0,255},{0,255,0,255},{255,255,0,255}}
    offmult = 10
    offset = {{-1,-1},{1,1},{1,-1},{-1,1}}
    numplayers = 0
    currentplayer = 0
    displayMode(FULLSCREEN)
    fontSize(32)
    textMode(CENTER)
    columnsfilled={false,false,false,false,false,false,false,false,false,false,false,false}
    legalnums = {false,false,false,false,false,false,false,false,false,false,false,false}
    columnrects = {}
    markers = {0,0,0,0,0,0,0,0,0,0,0,0}
    spotrects = {}
    board = {}
    setupSpots()
end

function setupSpots()
    spots = 1
    for x = spacing+4, max, spacing do
        spotrects[spots+1] = {}
        spotrects[13-spots] = {}
        for i = 1, spots*2, 1 do
            centerx = (x / (spots*2+1))*i
            centery = ((x / (spots*2+1))*i) + (max-x)
            spotrects[spots + 1][i] = {centerx+transx,centery,20,20}
            spotrects[13 - spots][i] = {centery+transx,centerx,20,20}
        end
        spots = spots + 1
    end
end

function setupBoard()
    for i = 1,numplayers,1 do
        board[i] = {}
        for j = 2,7,1 do
            board[i][j] = {}
            board[i][14-j] = {}
            for k = 1,((j-1)*2)+1,1 do
                table.insert(board[i][j],false)
                if j ~= 7 then
                    table.insert(board[i][14-j],false)
                end
            end
        end
    end
end

function rollDice()
    for i = 1,4,1 do
        dice[i]=math.random(1,6)
    end
    gamestate = kDiceRolled
    legalnums = {false,false,false,false,false,false,false,false,false,false,false,false}
    if not columnsfilled[dice[1]+dice[2]] then
        if numMarkers() < 3 or markers[dice[1]+dice[2]] > 0 then
            legalnums[dice[1]+dice[2]] = true
        end
    end
    if not columnsfilled[dice[3]+dice[4]] then
        if numMarkers() < 3 or markers[dice[3]+dice[4]] > 0 then
            legalnums[dice[3]+dice[4]] = true
        end
    end
    if not columnsfilled[dice[1]+dice[3]] then
        if numMarkers() < 3 or markers[dice[1]+dice[3]] > 0 then
            legalnums[dice[1]+dice[3]] = true
        end
    end
    if not columnsfilled[dice[2]+dice[4]] then
        if numMarkers() < 3 or markers[dice[2]+dice[4]] > 0 then
            legalnums[dice[2]+dice[4]] = true
        end
    end
    if not columnsfilled[dice[1]+dice[4]] then
        if numMarkers() < 3 or markers[dice[1]+dice[4]] > 0 then
            legalnums[dice[1]+dice[4]] = true
        end
    end
    if not columnsfilled[dice[2]+dice[3]] then
        if numMarkers() < 3 or markers[dice[2]+dice[3]] > 0 then
            legalnums[dice[2]+dice[3]] = true
        end
    end
    numlegalnums = 0
    for i=2,12,1 do
        if legalnums[i] then
            numlegalnums = numlegalnums + 1
            break
        end
    end
    if numlegalnums == 0 then
        gamestate = kBusted
    end
end

function numMarkers()
    num = 0
    for i = 2,12,1 do
        if markers[i] > 0 then
            num = num + 1
        end
    end
    return num
end

function topColumn(col)
    if col < 8 then
        return ((col-1)*2)+1
    else
        return ((13-col)*2)+1
    end
end

function columnPositionWithMarkers(column)
    if markers[column] > 0 then
        return markers[column]
    else
        for i = #board[currentplayer][column],1,-1 do
            if board[currentplayer][column][i] then
                return i
            end
        end
        return 0
    end
end

function isGameOver()
    numCols = 0
    for i=2,7,1 do
        if board[currentplayer][i][((i-1)*2)+1] then
            numCols = numCols + 1
        end
        if i ~= 7 then
            if board[currentplayer][14 - i][((i-1)*2)+1] then
                numCols = numCols + 1
            end
        end
    end
    return numCols >= 3
end

function pullBackOverColumns()
    for i = 2,7,1 do
        if markers[i] > ((i-1)*2)+1 then
            markers[i] = ((i-1)*2)+1
        end
        if markers[14-i] > ((i-1)*2)+1 then
            markers[14-i] = ((i-1)*2)+1
        end
    end
end

function lockBoard()
    for i = 2,12,1 do
        if markers[i] > 0 then
            if markers[i] < topColumn(i) then
                for j = 1,markers[i]-1,1 do
                    board[currentplayer][i][j] = false
                end
                board[currentplayer][i][markers[i]] = true
            else
                columnsfilled[i] = true
                board[currentplayer][i][topColumn(i)] = true
                for j = 1,topColumn(i)-1,1 do
                    for player = 1,numplayers,1 do
                        board[player][i][j] = false
                    end
                end
            end
        end
    end
end

function columnHit(col)
    markers[col] = columnPositionWithMarkers(col) + 1
    if dice[1] + dice[2] == col then
        if not columnsfilled[dice[3] + dice[4]] then
            if numMarkers() < 3 or markers[dice[3] + dice[4]] > 0 then
                markers[dice[3] + dice[4]] = columnPositionWithMarkers(dice[3] + dice[4]) + 1
            end
        end
    elseif dice[1] + dice[3] == col then
        if not columnsfilled[dice[2] + dice[4]] then
            if numMarkers() < 3 or markers[dice[2] + dice[4]] > 0 then
                markers[dice[2] + dice[4]] = columnPositionWithMarkers(dice[2] + dice[4]) + 1
            end
        end
    elseif dice[1] + dice[4] == col then
        if not columnsfilled[dice[2] + dice[3]] then
            if numMarkers() < 3 or markers[dice[2] + dice[3]] > 0 then
                markers[dice[2] + dice[3]] = columnPositionWithMarkers(dice[2] + dice[3]) + 1
            end
        end
    elseif dice[2] + dice[3] == col then
        if not columnsfilled[dice[1] + dice[4]] then
            if numMarkers() < 3 or markers[dice[1] + dice[4]] > 0 then
                markers[dice[1] + dice[4]] = columnPositionWithMarkers(dice[1] + dice[4]) + 1
            end
        end
    elseif dice[2] + dice[4] == col then
        if not columnsfilled[dice[1] + dice[3]] then
            if numMarkers() < 3 or markers[dice[1] + dice[3]] > 0 then
                markers[dice[1] + dice[3]] = columnPositionWithMarkers(dice[1] + dice[3]) + 1
            end
        end
    elseif dice[3] + dice[4] == col then
        if not columnsfilled[dice[1] + dice[2]] then
            if numMarkers() < 3 or markers[dice[1] + dice[2]] > 0 then
                markers[dice[1] + dice[2]] = columnPositionWithMarkers(dice[1] + dice[2]) + 1
            end
        end
    end

    pullBackOverColumns()
    legalnums = {false,false,false,false,false,false,false,false,false,false,false,false}
    gamestate = kSpotsPicked
end

function stopHit()
    lockBoard()
    markers = {0,0,0,0,0,0,0,0,0,0,0,0}
    if isGameOver() then
        gamestate = kGameOver
    else
        currentplayer = currentplayer + 1
        if currentplayer > numplayers then
            currentplayer = 1
        end
        gamestate = kTurnStart
        dice = {0,0,0,0}
    end
end

function bustHit()
    currentplayer = currentplayer + 1
    if currentplayer > numplayers then
        currentplayer = 1
    end
    markers = {0,0,0,0,0,0,0,0,0,0,0,0}
    gamestate = kTurnStart
    dice = {0,0,0,0}
end

function touched(touch)
    if touch.state ~= ENDED then
        return
    end
    if gamestate == kChoosePlayers then
        for i = 1,4,1 do
            if touch.x > playerrect[i][1] and touch.x < playerrect[i][3] then
                if touch.y > playerrect[i][2] and touch.y < playerrect[i][4] then
                    numplayers = i
                    currentplayer = 1
                    gamestate = kTurnStart
                    setupBoard()
                    markers = {0,0,0,0,0,0,0,0,0,0,0,0}
                    break
                end
            end
        end
    elseif gamestate == kTurnStart or gamestate == kSpotsPicked then
        if touch.x > 0 and touch.x < 230 then
            if touch.y > 530 and touch.y < 720 then
                rollDice()
            end
        end
        if gamestate == kSpotsPicked then
            if touch.x > 55 and touch.x < 182 then
                if touch.y > 461 and touch.y < 530 then
                    stopHit()
                end
            end
        end
    elseif gamestate == kBusted then
        if touch.x > 55 and touch.x < 182 then
            if touch.y > 461 and touch.y < 530 then
                bustHit()
            end
        end
    elseif gamestate == kGameOver then
        if touch.x > 55 and touch.x < 182 then
            if touch.y > 461 and touch.y < 530 then
                setup()
            end
        end
    elseif gamestate == kDiceRolled then
        for i = 2,12,1 do
            if legalnums[i] then
                if touch.x > columnrects[i][1] and touch.x < columnrects[i][1] + columnrects[i][3] then
                    if touch.y > columnrects[i][2] and touch.y < columnrects[i][2] + columnrects[i][4] then
                        columnHit(i)
                    end
                end
            end
        end
    end
end

-- This function gets called once every frame
function draw()
    background(0, 0, 0, 255)
    strokeWidth(5)
    stroke(255, 255, 255, 255)
    fill(0, 0, 0, 255)
    ellipseMode(CENTER)

    -- draw board
    if gamestate > kChoosePlayers then
        spots = 1
        for x = spacing+4, max, spacing do
            fill(0, 0, 0, 255)
            stroke(255, 255, 255, 255)
            for player = 1,numplayers,1 do
                if board[player][spots+1][topColumn(spots+1)] then
                    stroke(playercolor[player][1],playercolor[player][2], playercolor[player][3], playercolor[player][4])
                end
            end
            line(x+transx,max,0+transx,max-x)
            stroke(255, 255, 255, 255)
            for player = 1,numplayers,1 do
                if board[player][13-spots][topColumn(13-spots)] then
                    stroke(playercolor[player][1],playercolor[player][2], playercolor[player][3], playercolor[player][4])
                end
            end
            line(max+transx,x,transx+(max-x),0)
            stroke(255, 255, 255, 255)

            for i = 2,12,1 do
                for j = 1, #spotrects[i], 1 do
                    stroke(255, 255, 255, 255)
                    fill(0, 0, 0, 255)
                    for player = 1,numplayers,1 do
                        if board[player][i][topColumn(i)] then
                            stroke(playercolor[player][1],playercolor[player][2], playercolor[player][3], playercolor[player][4])
                        end
                    end
                    ellipse(spotrects[i][j][1],spotrects[i][j][2],spotrects[i][j][3], spotrects[i][j][4])
                    if markers[i] == j then
                        fill(255, 255, 255, 0)
                        stroke(167, 157, 157, 255)
                        rect(spotrects[i][j][1] - 19,spotrects[i][j][2] - 19,spotrects[i][j][3] + 20, spotrects[i][j][4] + 20)
                    end
                    for player = 1,numplayers,1 do
                        if board[player][i][j] then
                            fill(playercolor[player][1],playercolor[player][2], playercolor[player][3], playercolor[player][4])
                            stroke(playercolor[player][1],playercolor[player][2], playercolor[player][3], playercolor[player][4])
                            ellipse(spotrects[i][j][1] + offset[player][1]*offmult,spotrects[i][j][2] + offset[player][2]*offmult,25,25)
                        end
                    end
                end
            end
            font("Arial-BoldMT")
            fill(255, 255, 255, 255)
            for player = 1,numplayers,1 do
                if board[player][spots+1][topColumn(spots+1)] then
                    fill(playercolor[player][1],playercolor[player][2], playercolor[player][3], playercolor[player][4])
                end
            end
            text(tostring(spots+1),x+transx+30,max+30)
            columnrects[spots+1] = {x+transx+6,max+5,50,50}
            if legalnums[spots+1] then
                fill(255, 255, 255, 255)
                stroke(255, 255, 255, 255)
                rect(x+transx+6,max+5,50,50)
                fill(0, 0, 0, 255)
                text(tostring(spots+1),x+transx+30,max+30)
            end
            if markers[spots+1] == (spots*2)+1 then
                fill(255, 0, 0, 0)
                stroke(167, 157, 157, 255)
                rect(x+transx+6,max+5,50,50)
            end
            fill(255, 255, 255, 255)
            for player = 1,numplayers,1 do
                if board[player][13-spots][topColumn(13-spots)] then
                    fill(playercolor[player][1],playercolor[player][2], playercolor[player][3], playercolor[player][4])
                end
            end
            text(tostring(13-spots),max+30+transx,x+30)
            columnrects[13-spots] = {max+6+transx,x+6,50,50}
            if legalnums[13-spots] then
                fill(255, 255, 255, 255)
                stroke(255, 255, 255, 255)
                rect(max+6+transx,x+6,50,50)
                fill(0, 0, 0, 255)
                text(tostring(13-spots),max+30+transx,x+30)
            end
            if markers[13-spots] == (spots*2)+1 then
                fill(255, 255, 255, 0)
                stroke(167, 157, 157, 255)
                rect(max+6+transx,x+6,50,50)
            end
            spots = spots + 1
        end

        --draw dice
        stroke(252, 252, 252, 255)
        fill(182, 175, 175, 255)
        rect(30,650,80,80)
        rect(130,650,80,80)
        rect(30,550,80,80)
        rect(130,550,80,80)
        fill(255, 255, 255, 255)
        if dice[1] > 0 then
            text(tostring(dice[1]),70,690)
            text(tostring(dice[2]),170, 690)
            text(tostring(dice[3]),70,590)
            text(tostring(dice[4]),170,590)
        end

        for i=1,numplayers,1 do
            if gamestate == kGameOver then
                if i == currentplayer then
                    drawplayer(i)
                end
            else
                drawplayer(i)
            end
        end

        if gamestate == kSpotsPicked then 
            drawStopSign()
        elseif gamestate == kBusted then 
            drawBusted()
        elseif gamestate == kGameOver then
            drawNewGame()
        end
    else
        strokeWidth(5)
        fill(255, 255, 255, 255)
        font("Arial-BoldItalicMT")
        text("Choose # of Players",159,468)
        for i=1,4,1 do
            drawplayer(i)
        end
    end
end

function drawplayer(player)
    stroke(playercolor[player][1], playercolor[player][2], playercolor[player][3], playercolor[player][4])
    if player == currentplayer then
        fill(0, 0, 0, 255)
        rect(playerrect[player][1]-10, playerrect[player][2]-10, 100, 100)    
    end
    fill(playercolor[player][1], playercolor[player][2], playercolor[player][3], playercolor[player][4])
    rect(playerrect[player][1], playerrect[player][2], 80, 80)
    if player < 4 then
        fill(255, 255, 255, 255)
    else
        fill(0, 0, 0, 255)
    end
    font("Arial-BoldMT")
    text(tostring(player), playerrect[player][1] + 40, playerrect[player][2] + 40)
    if player == currentplayer then
        fill(0, 0, 0, 0)
        stroke(157, 157, 157, 255)
        if numMarkers() < 1 then
            rect(playerrect[player][1] - 40, playerrect[player][2] + 64, 25, 25)
        end
        if numMarkers() < 2 then
            rect(playerrect[player][1] - 40, playerrect[player][2] + 28, 25, 25)
        end
        if numMarkers() < 3 then
            rect(playerrect[player][1] - 40, playerrect[player][2] - 8, 25, 25)
        end
    end
end

function drawStopSign()
    stroke(255, 0, 0, 255)
    fill(255, 0, 0, 255)
    rect(55,461,127,69)
    font("Arial-BoldMT")
    fill(255, 255, 255, 255)
    text("STOP",121,494)
end

function drawBusted()
    stroke(255, 0, 0, 255)
    fill(255, 0, 0, 0)
    rect(55,461,127,69)
    font("Arial-BoldMT")
    fill(255, 255, 255, 255)
    text("BUST",121,494)
end

function drawNewGame()
    stroke(255, 255, 255, 255)
    fill(255, 0, 0, 0)
    rect(55,461,127,69)
    font("Arial-BoldMT")
    fill(255, 255, 255, 255)
    text("WIN!",121,494)
end
    • #boardgame
    • #board game
    • #Can't Stop
    • #codea
    • #iPad
    • #lua
  • 1 year ago
  • Permalink
Share

Short URL

TwitterFacebookPinterestGoogle+
← Previous • Next →

About

A blog mostly about my board gaming experiences.

Board Games










  • » Harry Potter's World
  • » Hermione, Queen of Witches, Books 1-5
    » Sine Qua Non
  • » Harry Potter and the Half-Blood Prince
  • » Harry Potter and the Order of the Phoenix
  • » Harry Potter and the Goblet of Fire
  • Books Read in 2005

    • Harry Potter and the Prisoner of Azkaban
    • Harry Potter and the Chamber of Secrets
    • Deus Vitae
    • Harry Potter and the Philosopher's Stone
    • Snow Crash (again)
    • The Truth (with jokes)
    • Trinity
    • The Tipping Point
    • Identity Crisis
    • The Rough Guide to Sci-Fi Movies
    • Divided by God
    • On Intelligence
    • Mars Is No Place for Children
    • Flow My Tears, the Policeman Said
    • Blink
    • The Shadow of Saganami
    • Harrington on Hold 'em Volume I
    • Phil Hellmuth's Texas Hold 'em
    • Flag in Exile (again)
    • Field of Dishonor (again)
    • The Short Victorious War (again)
    • Monster Island
    • Singularity Sky
    • Dave Barry is not Taking this Sitting Down
    • The Honor of the Queen (again)
    • Second Foundation (again)
    • Mindscan
    • Light
    • On Basilisk Station (again)
    • Dive into Python
    • Eastern Standard Tribe
    • Think Like a Dinosaur
  • Books Read in 2004

    • Building Robots With Lego Mindstorms
    • God's Debris
    • Halo 2 Game Guide
    • America: The Book
    • The Road to the Dark Tower
    • Darwin's Children
    • The Dark Tower
    • The Forever War (again)
    • We the Media
    • Planetary
    • Year of the Blog
    • America: the Book
    • Darwin's Radio
    • Lust
    • The Wonder of Girls
    • Perdido Street Station
    • Lovecraft
    • Batman: The Dark Knight Strikes Again (again)
    • Coraline
    • It's a Bird
    • Song of Susannah
    • Free Culture
    • American Gods

  • Friend's Sites


    Sodo Oh No
    Milk and Cookies
    Hellroy
    Choosing Hope
    Alex in Wonderland
    Helper Monkeys Corner
    Family Reviews
  • Twitter

    loading tweets…

    • RSS
    • Random
    • Archive
    • Ask me anything
    • Mobile
    Effector Theme by Pixel Union