Here's my other game too, Lights Out. I'm more pleased with this game as it has two modes, a title screen and a win state.
Minified:
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
Unobfuscated and commented (gist, since itch strips linebreaks):
-- 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