Created
November 9, 2013 08:05
-
-
Save dermotbalson/7382993 to your computer and use it in GitHub Desktop.
L game beta
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
--Project: L Game | |
--Version: Beta 1.0 | |
--Comments: | |
--================ SETUP =================== | |
function setup() | |
--playing stages | |
NONE,MOVED_L,TOUCHED_DOT,MOVED_DOT=10,11,12,13 | |
--setup the grid | |
size=400 --total size of grid | |
offset=vec2(WIDTH/2-size/2-50,HEIGHT/2-size/2+65) --position slightly left and above of centre | |
square=size/4 --size of each cell in the square | |
--make an image containing the board | |
board=image(size,size) | |
setContext(board) | |
background(137, 194, 208, 255) | |
pushStyle() | |
--draw grid | |
stroke(45, 125, 151, 50) | |
strokeWidth(2) | |
for i=0,4 do | |
line(square*i,1,square*i,square*4) | |
line(1,square*i,square*4,square*i) | |
end | |
pushStyle() | |
setContext() | |
StartGame() | |
end | |
--this runs each time the game restarts, it sets up the initial position | |
function StartGame() | |
--table holds touches, used for drawing L shape | |
touches={} for i=1,4 do touches[i]={} end | |
--tables to hold player data, pos = position of 4 squares of the L | |
player={} | |
player[1]={name="Blue",pos={vec2(2,1),vec2(2,2),vec2(2,3),vec2(3,1)},color=color(44, 155, 219, 255)} | |
player[2]={name="Red",pos={vec2(2,4),vec2(3,4),vec2(3,3),vec2(3,2)},color=color(209, 93, 113, 255)} | |
--and another table to hold a player's new move until it is submitted | |
playerN={pos={}} | |
--a table for the two dots | |
dot={pos={vec2(1,4),vec2(4,1)},color=color(84, 167, 84, 255)} | |
dot2={pos={}} --and one for the dot moved by the player (until it is submitted) | |
--control buttons | |
buttons={} | |
buttons.Restart={text="Restart",show=true,x=offset.x+square*4+90,y=offset.y+square*3} | |
buttons.Undo={text="Undo",show=false,x=offset.x+square*4+90,y=offset.y+square*3-75} | |
buttons.Done={text="Done",show=false,x=offset.x+square*4+90,y=offset.y+square*3-150} | |
stage=NONE | |
D_touched=nil | |
--choose a player to start with | |
play=math.random(1,2) | |
--start tween to vibrate current player colour, see use in DrawBoard | |
Alpha={a=255} | |
tween( 2, Alpha, { a=50 }, { easing = tween.easing.linear, loop = tween.loop.pingpong } ) | |
end | |
--====== DRAW functions ================= | |
function draw() | |
background(200) | |
DrawBoard() | |
--draw ellipse under finger if touching screen | |
if CurrentTouch.state~=ENDED and CurrentTouch.x>0 then | |
pushStyle() | |
fill(255,255,0,100) | |
ellipse(CurrentTouch.x,CurrentTouch.y,40,60) | |
popStyle() | |
end | |
if stage==NONE then --player must move L | |
DrawHelpText("It is "..player[play].name.." to move.\n".. | |
[[ | |
Try to block your opponent from moving their L piece. Use your finger to draw your L piece at another position on the board (you can only draw on pale blue, unoccupied squares - including the squares your piece was on - but at least one square must be different). | |
You can draw it upside down and back to front, any way you want. | |
The new position will be shown as 4 square dots until you finish your move.]]) | |
else --player has moved L, and can now move dot | |
DrawHelpText( | |
[[If you want, move ONE of the dots to a blank square to make it more difficult for your opponent. | |
To do this, touch a dot, then a blank square, and the dot should move. | |
Press the Done button when you're finished your move, or Undo to start your move again.]]) | |
end | |
end | |
function DrawBoard() | |
pushStyle() | |
--draw heading | |
font("Papyrus") fontSize(48) | |
fill(100) text("The L Game",offset.x+square*2+3,offset.y+square*4+57) | |
fill(255,255,0) text("The L Game",offset.x+square*2,offset.y+square*4+60) | |
fill(0) font("ArialMT") fontSize(14) text("(c) Edward De Bono",offset.x+square*2+3,offset.y+square*4+30) | |
--draw board | |
spriteMode(CORNER) | |
sprite(board,offset.x,offset.y) | |
--draw dots | |
strokeWidth(0) | |
for i=1,2 do | |
if D_touched==i then fill(dot.color.r,dot.color.g,dot.color.b,Alpha.a) else fill(dot.color) end | |
local d=dot.pos[i] | |
if dot2.id==i then d=dot2.pos end | |
ellipse(offset.x+square*(d.x-.5),offset.y+square*(d.y-.5),square*.6) | |
end | |
--draw current player | |
local a=255 | |
if playerN.pos[1] then a=75 else a=Alpha.a end | |
local pp=player[play] | |
fill(pp.color.r,pp.color.g,pp.color.b,a) | |
for i=1,4 do | |
rect(offset.x+square*(player[play].pos[i].x-1),offset.y+square*(player[play].pos[i].y-1),square,square) | |
end | |
if playerN.pos[1] then | |
fill(player[play].color) | |
for i=1,4 do | |
rect(offset.x+square*(playerN.pos[i].x-.75),offset.y+square*(playerN.pos[i].y-.75),square*.5,square*.5) | |
end | |
end | |
--draw other player's L | |
local p=3-play --other player's id | |
fill(player[p].color) | |
for i=1,4 do | |
rect(offset.x+square*(player[p].pos[i].x-1),offset.y+square*(player[p].pos[i].y-1),square,square) | |
end | |
--add buttons | |
DrawButtons() | |
popStyle() | |
end | |
function DrawButtons() | |
pushStyle() | |
fontSize(24) | |
font("ArialRoundedMTBold") | |
for i,b in pairs(buttons) do | |
if b.w==nil then b.w,b.h=textSize(b.text) end | |
if b.show then | |
stroke(186, 132, 185, 255) | |
strokeWidth(b.h) | |
line(b.x-b.w/2,b.y,b.x+b.w/2,b.y) | |
fill(255) | |
text(b.text,b.x,b.y) | |
end | |
end | |
popStyle() | |
end | |
function DrawHelpText(t) | |
pushStyle() | |
font("HelveticaNeue") | |
fill(0) | |
fontSize(16) | |
textWrapWidth(size+offset.x+20) | |
textMode(CORNER) | |
local sx,sy=textSize(t) | |
text(t,offset.x/2,offset.y-sy-25) | |
popStyle() | |
end | |
--===== TOUCH functions ======================= | |
function touched(touch) | |
--get square that was touched as vec2 | |
local p=GetSquare(touch.x,touch.y) | |
--if user is making a move, process touch | |
if touch.state~=ENDED and state==MOVE then | |
if stage==TOUCHED_DOT then --if user has previously touched a dot | |
if GetD(p) then --see if he's touched a blank square to move it to | |
dot2.id=D_touched | |
dot2.pos=vec2(p.x,p.y) --yes, so store new position | |
ChangeStage(MOVED_DOT) --and move to next stage | |
return | |
else --move was faulty, reset to position after L moved | |
ChangeStage(MOVED_L) | |
dot2={} | |
end | |
--if user has already moved the L, he has option to move a dot or finish the move | |
elseif stage==MOVED_L then | |
--check if either of the dots touched | |
if p==dot.pos[1] then D_touched=1 | |
elseif p==dot.pos[2] then D_touched=2 | |
end | |
if D_touched~=nil then --a dot was touched, wait for user to choose new square | |
ChangeStage(TOUCHED_DOT) | |
return | |
end | |
end | |
if stage<=MOVED_L and p then --check for a move of the L piece | |
if id~=touch.id then | |
id=touch.id | |
touches={} | |
nTouches=0 | |
end | |
local v=GetSquare(touch.x,touch.y) | |
local u=v.x*10+v.y | |
if touches[u]==nil then nTouches=nTouches+1 end | |
touches[u]=v | |
if nTouches==4 then MoveL() end | |
end | |
--check the other game states | |
elseif touch.state==ENDED then | |
local b=GetButton(touch.x,touch.y) | |
if b then HandleButton(b) end | |
end | |
end | |
function HandleButton(b) | |
if b==buttons.Restart then | |
StartGame() | |
elseif b==buttons.Undo then | |
playerN.pos={} | |
dot2={} | |
D_touched=nil | |
ChangeStage(NONE) | |
elseif b==buttons.Done then --finish move | |
--TO DO - store move to allow move rollbacks | |
for i=1,4 do --store new position | |
player[play].pos[i]=playerN.pos[i] | |
end | |
playerN.pos={} --clear | |
--move dot if applicable | |
if dot2.id then dot.pos[dot2.id]=dot2.pos end | |
dot2.id=nil dot2.pos={} D_touched=nil | |
ChangeStage(NONE) | |
--switch player | |
play=3-play | |
end | |
end | |
--process L move | |
function MoveL() | |
playerN.pos={} | |
local n,tr,tc=0,{},{} | |
for i=1,4 do tr[i],tc[i]=0,0 end | |
local mr,mc=0,0 | |
local r,c=0,0 | |
local ar,ac=0,0 | |
local p=3-play --opponent's id | |
for i,t in pairs(touches) do | |
--check for valid move first | |
for k=1,2 do if t==dot.pos[k] then ChangeStage(NONE) return end end | |
for k=1,4 do if t==player[p].pos[k] then ChangeStage(NONE) return end end | |
tr[t.x]=tr[t.x]+1 | |
if tr[t.x]>mr then mr=tr[t.x] r=t.x end | |
ar=ar+t.x | |
tc[t.y]=tc[t.y]+1 | |
if tc[t.y]>mc then mc=tc[t.y] c=t.y end | |
ac=ac+t.y | |
end | |
local moved=false | |
if (mr==3 and mc==2 and mc~=mr/3) or --L is lying down | |
(mr==2 and mc==3 and mr~=mc/3) then --L is upright | |
for i=1,4 do | |
local n=player[play].pos[i].x*10 + player[play].pos[i].y | |
if touches[n]==nil then moved=true end | |
end | |
local n=0 | |
for i,t in pairs(touches) do | |
n=n+1 | |
playerN.pos[n]=vec2(t.x,t.y) | |
end | |
end | |
if moved==true then | |
ChangeStage(MOVED_L) | |
else | |
playerN.pos={} | |
ChangeStage(NONE) | |
end | |
end | |
function ChangeStage(s) | |
stage=s | |
if s>=MOVED_L then | |
buttons.Undo.show=true | |
buttons.Done.show=true | |
else | |
buttons.Undo.show=false | |
buttons.Done.show=false | |
end | |
end | |
--====== UTILITY functions | |
--give an x,y position, return the grid position (1,1 is bottom left) or nil if outside grid | |
function GetSquare(x,y) | |
local x,y=math.floor((x-offset.x)/square+1),math.floor((y-offset.y)/square+1) | |
if x>0 and x<5 and y>0 and y<5 then return vec2(x,y) else return nil end | |
end | |
function GetButton(x,y) | |
for i,b in pairs(buttons) do | |
if math.abs(x-b.x)<b.w and math.abs(y-b.y-b.h/2)<b.h | |
and b.show==true then return b end | |
end | |
return nil | |
end | |
function GetD(p) | |
--check for valid move first | |
for k=1,2 do if p==dot.pos[k] then return false end end | |
for k=1,4 do if p==playerN.pos[k] then return false end end | |
for k=1,4 do if p==player[3-play].pos[k] then return false end end | |
return true | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment