Created
July 11, 2014 09:09
-
-
Save dermotbalson/c5d566720c24afc54238 to your computer and use it in GitHub Desktop.
Threes part 2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function setup() | |
Settings() | |
CreateBoard() | |
Initialise() | |
state=states.PLAY --NEW | |
end | |
function Settings() | |
states={PLAY=1,END=2} --NEW | |
dragXY=nil | |
moves={vec2(-1,0),vec2(1,0),vec2(0,-1),vec2(0,1)} | |
moveText={"Left","Right","Down","Up"} | |
cellWidth,cellHeight,cellGap,textSize=100,133,10,48 | |
boardValues={ [0]={0,0,0}, | |
[1]={color(255),color(0,0,255),0}, | |
[2]={color(255),color(255,0,0),0}, | |
[3]={color(0),color(255),3}, | |
[6]={color(0),color(255),9}, | |
[12]={color(255,0,0),color(255),27}, | |
[24]={color(255,0,0),color(255),81}, | |
[48]={color(255,0,0),color(255),243}, | |
[96]={color(255,0,0),color(255),729}, | |
[192]={color(255,0,0),color(255),2187}, | |
[384]={color(255,0,0),color(255),6561}} | |
end | |
function CreateBoard() | |
imgBoard=image(cellWidth*4+cellGap*5,cellHeight*4+cellGap*5) | |
setContext(imgBoard) | |
background(150, 192, 211, 255) | |
fill(177, 199, 210, 255) | |
local w=cellGap | |
for r=1,4 do | |
local h=cellGap | |
for c=1,4 do | |
rect(w,h,cellWidth,cellHeight) | |
h=h+cellHeight+cellGap | |
end | |
w=w+cellWidth+cellGap | |
end | |
setContext() | |
GetNextTile() | |
end | |
function Initialise() | |
--create 9 random tiles valued 1,2 or 3 and put them somewhere in the table called board | |
--board is a 4x4 table | |
--start off by creating an empty 4x4 table with all values = 0 | |
board={} | |
for i=1,4 do | |
board[i]={0,0,0,0} | |
end | |
--now create the initial tiles | |
for i=1,9 do | |
local n=RandInt(3) | |
while true do | |
local r=RandInt(4) | |
local c=RandInt(4) | |
if board[c][r]==0 then | |
board[c][r]=n | |
break | |
end | |
end | |
end | |
NextTile=RandInt(3) --get the next tile to be added so we can show it to the player | |
--calculate the position of each tile on the screen | |
--first calculate bottom left position of board | |
bottomPos=vec2(WIDTH/2-cellWidth*2-cellGap*2.5,HEIGHT/2-cellHeight*2-cellGap*2.5) | |
boardPos={} --table to hold positions | |
for c=1,4 do | |
boardPos[c]={} | |
for r=1,4 do | |
boardPos[c][r]=vec2(bottomPos.x+(cellWidth+cellGap)*(c-1)+cellGap, | |
bottomPos.y+(cellHeight+cellGap)*(r-1)+cellGap) | |
end | |
end | |
nextTilePos=vec2(bottomPos.x-cellWidth-10,HEIGHT/2) | |
end | |
function draw() | |
background(135, 187, 213, 255) | |
DrawBoard() | |
end | |
function DrawBoard() | |
--draw board itself | |
sprite(imgBoard,WIDTH/2,HEIGHT/2) | |
--draw the tiles | |
for c=1,4 do | |
for r=1,4 do | |
if board[c][r]>0 then | |
DrawTile(boardPos[c][r],board[c][r]) | |
end | |
end | |
end | |
--show next tile to come | |
DrawTile(nextTilePos,NextTile) | |
--show score --NEW | |
fontSize(24) | |
fill(color(0,0,255)) | |
text("Score: " .. GetScore(),bottomPos.x+cellWidth*2,bottomPos.y-50) | |
if state==states.END then | |
fontSize(72) | |
fill(0,255,0) | |
text("Game Over\nTouch to Restart",WIDTH/2,HEIGHT/2) | |
end | |
end | |
function RandInt(a) --returns random integer between 1 and b (inclusive) | |
return math.floor(math.random()*a)+1 | |
end | |
function DrawTile(p,v) | |
fill(boardValues[v][2]) | |
rect(p.x,p.y,cellWidth,cellHeight) | |
fill(boardValues[v][1]) | |
font("ArialRoundedMTBold") | |
fontSize(textSize) | |
text(v,p.x+cellWidth/2,p.y+cellHeight/2) | |
end | |
function GetScore(b,loadBlanks) --all NEW | |
loadBlanks=loadBlanks or false | |
b=b or board | |
blanks=0 | |
local score=0 | |
for c=1,4 do | |
for r=1,4 do | |
score=score+boardValues[b[c][r]][3] | |
if b[c][r]==0 then blanks=blanks+1 end | |
end | |
end | |
if loadBlanks then score=score*16/(16-blanks) end | |
return score | |
end | |
function touched(t) --all NEW | |
if t.state==BEGAN then --Started dragging (or touched a button) | |
if state==states.END then | |
Initialise() | |
state=states.PLAY | |
else | |
--reset movement variables | |
dragXY=vec2(t.x,t.y) | |
end | |
elseif t.state==ENDED and dragXY then --Ended | |
local dx=math.abs(t.x-dragXY.x) | |
local dy=math.abs(t.y-dragXY.y) | |
local d=dx-dy --is X or Y movement larger | |
local m=0 | |
if d>0 then --X movement is larger | |
if dx<cellWidth/2 then return end | |
if t.x>dragXY.x then m=vec2(1,0) else m=vec2(-1,0) end | |
elseif d<0 then --Y movement is larger | |
if dy<cellHeight/2 then return end | |
if t.y>dragXY.y then m=vec2(0,1) else m=vec2(0,-1) end | |
end | |
MoveCells(m) | |
dragXY=nil | |
end | |
end | |
function MoveCells(m) --all NEW | |
local r1,r2,r3=1,4,1 | |
local c1,c2,c3=1,4,1 | |
if m.x<0 then c1,c2,c3=2,4,1 | |
elseif m.x>0 then c1,c2,c3=3,1,-1 | |
elseif m.y<0 then r1,r2,r3=2,4,1 | |
elseif m.y>0 then r1,r2,r3=3,1,-1 | |
end | |
for c=c1,c2,c3 do | |
for r=r1,r2,r3 do | |
if board[c][r]>0 then | |
if board[c+m.x][r+m.y]==0 then | |
board[c+m.x][r+m.y]=board[c][r] | |
board[c][r]=0 | |
elseif (board[c+m.x][r+m.y]+board[c][r]==3) or | |
(board[c+m.x][r+m.y]==board[c][r] and board[c][r]>2) then | |
board[c+m.x][r+m.y]=board[c+m.x][r+m.y]+board[c][r] | |
board[c][r]=0 | |
elseif board[c+m.x][r+m.y]==board[c][r] and board[c][r]>2 then | |
board[c+m.x][r+m.y]=board[c+m.x][r+m.y]+board[c][r] | |
board[c][r]=0 | |
end | |
end | |
end | |
end | |
--add new cell at edge, get cell location | |
q={} --list of blank cells | |
a=nil | |
if m.x~=0 then | |
for r=1,4 do | |
if board[c2][r]==0 then table.insert(q,r) end | |
end | |
if #q>0 then a=vec2(c2,q[RandInt(#q)]) end | |
elseif m.y~=0 then | |
for c=1,4 do | |
if board[c][r2]==0 then table.insert(q,c) end | |
end | |
if #q>0 then a=vec2(q[RandInt(#q)],r2) end | |
end | |
if a then | |
board[a.x][a.y]=NextTile | |
GetNextTile() | |
end | |
local mov=CheckAvailableMoves() | |
if #mov==0 then state=states.END end | |
end | |
function CheckAvailableMoves() --all NEW | |
-- check for end of game | |
mov={} | |
--check if any blank squares left, if so, we aren't done | |
for c=1,4 do | |
for r=1,4 do | |
if board[c][r]==0 then | |
return {1,2,3,4} --we can move all four ways | |
end | |
end | |
end | |
--check if matching pairs are adjacent (or 1 & 2) | |
if #mov==0 then | |
for c=1,4 do | |
for r=2,4 do | |
if (board[c][r]>2 and board[c][r]==board[c][r-1]) or board[c][r]+board[c][r-1]==3 then | |
mov={3,4} | |
break | |
end | |
end | |
if #mov>0 then break end | |
end | |
for r=1,4 do | |
for c=2,4 do | |
if (board[c][r]>2 and board[c][r]==board[c-1][r]) or board[c][r]+board[c-1][r]==3 then | |
table.insert(mov,1,1) | |
table.insert(mov,2,2) | |
break | |
end | |
end | |
if #mov>0 and mov[1]==1 then break end | |
end | |
end | |
return mov | |
end | |
function GetNextTile() --all NEW | |
NextTile=RandInt(3) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment