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


