Skip to content

Instantly share code, notes, and snippets.

@tobiasvl

tobiasvl/lights-out.p8

Last active Nov 18, 2018
Embed
What would you like to do?
z="lights out"poke(24364,3)::x::flip()cls()k=btnp()w={[0]="","",""}f=flr
?z,12,18,stat(95)%4
?"z: classic\nx: 2000",12,32,7
if(k<9)goto x
if(k>16)w[3]=""
b={}p=2m=0
for i=1,35 do
b[i]=i%7<2 and 0or 2
end::_::flip()cls()
?m,30,54
for i=1,35 do
j=b[i]
?w[j],i%7*8-2,6*f(i/7)+18,j*3+2
end
x=p%7*8-2y=6*f(p/7)+17rect(x-1,y,x+7,y+6,9)q=0k=btnp()h={-1,1,-7,0,7}if k>9then m+=1for i in all(h)do
o=b[p+i]
if(o and o>0)b[p+i]=o%#w+1
end
elseif k>0then q=h[f(k/2)+1]end
g=b[p+q]
if(g and g>0)p=p+q
for i=1,35 do
if(b[i]>1)goto _ end
z="you win!"goto x
-- title screen logo
title="lights out"
-- 64x64 resolution
poke(0x5f2c,3)
-- title screen loop
::title_screen::
-- clear screen
-- (we do it here because we
-- jump back upon winning)
flip()
cls()
-- read button input
key=btnp()
-- light values and visuals:
-- 0: no light
-- 1: light off
-- 2: red light
-- 3: green light
-- (green light only in mode
-- "lights out 2000")
lights={[0]="","",""}
-- print title with color
-- alternating based on time
-- (stat(95) is current second)
print(title,12,18,stat(95)%4)
-- print menu
print("z: classic\nx: 2000",12,32,7)
-- if the button value is below
-- 16 (all values are powers of
-- two so by checking below 9
-- here we save a character),
-- including 0 (no input), we
-- just loop. 16 is the z key,
-- so if that's the case we
-- will fall through to classic
-- mode.
if (key<9) goto title_screen
-- button value 32 is x, so in
-- that case we add the green
-- light value for "2000 mode".
if (key>16) lights[3]=""
-- initialize the board
board={}
-- start in the left corner
player=2
-- move counter
moves=0
-- initialize the 5x5 board
-- with the value 2 (red light)
-- but add a column of 0 (no
-- light) on either side to
-- avoid wrapping when toggling
for i=1,35 do
-- if column is 1 or 7:
if i%7<2 then
board[i]=0
else
board[i]=2
end
end
-- gameplay loop
::play::
flip()
cls()
-- move counter
print(moves,30,54)
-- print the board
for i=1,35 do
light=board[i]
-- a trick: each light's
-- color can be computed from
-- its value
-- none: 0*3+2 = 0 (black)
-- off: 1*3+2 = 5 (dark gray)
-- red: 2*3+2 = 8
-- green: 3*3+2 = 11
light_color=light*3+2
-- print lights in grid
print(lights[light],i%7*8-2,6*flr(i/7)+18,light_color)
end
-- print the player's marker
x=player%7*8-2
y=6*flr(player/7)+17
rect(x-1,y,x+7,y+6,9)
-- marker movement: we find the
-- new position and see if it's
-- valid. if so, we move it.
new_player=0
key=btnp()
-- all adjacent grid indices.
-- used for movement and for
-- toggling lights. notice that
-- 0 (ie. no movement, the
-- currently marked light) is
-- in position 4 in the table.
-- this is a trick, used when
-- mapping input keys to
-- positions.
directions={-1,1,-7,0,7}
-- if the key is x or z (value
-- is 16 or 32) we toggle:
if key>9 then
moves+=1
-- look at all adjacent
-- lights in all directions
for i in all(directions) do
light=board[player+i]
-- if it's inside the board
if light and light>0 then
-- cycle light value up
-- (use #lights here so
-- we cover both classic
-- and 2000 mode)
board[player+i]=light%#lights+1
end
end
-- if the key is an arrow key
-- (value is 1, 2, 4 or 8):
elseif key>0 then
-- divide the button value by
-- two and add 1 and we get
-- 1, 2, 3 or 5. look that up
-- in the directions table
-- (recall that position 4
-- was the current light)
new_player=directions[flr(key/2)+1]
-- if it's inside the board
light=board[player+new_player]
if light and light>0 then
-- move there
player=player+new_player
end
end
-- if any of the lights are
-- still on, stay in the
-- gameplay loop
for i=1,35 do
if (board[i]>1) goto play
end
-- otherwise, set the title to
-- a congratulatory message
title="you win!"
-- and go back to the title
-- screen
goto title_screen
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment