2

Cart #59036 | 2018-11-15 | Code ▽ | License: CC4-BY-NC-SA
2

The classic Lights Out puzzle game for the TweetTweetJam. The source code fits in two tweets (560 characters).

Your goal is to turn all the lights off. However, each light toggles all four adjacent lights as well.

I didn't have room for different levels, but there's two modes:

• Lights Out Classic: Lights toggle between off and on (red). Best solution is 15 moves.
• Lights Out 2000: Lights toggle between off, red and green. Best solution is 18 moves.
P#59034 2018-11-15 18:15 ( Edited 2019-02-01 08:58)

I "unminified" the code on the jam forums, maybe it's interesting for people here too.

Original code:

 ```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 code:

 ```-- 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 ```
P#59214 2018-11-20 04:53 ( Edited 2018-11-20 09:53)

really cool concept and difficult for me too lol

P#59216 2018-11-20 05:51 ( Edited 2018-11-20 10:51)