Log In  

Cart #59036 | 2018-11-15 | Code ▽ | Embed ▽ | 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)

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2024-04-18 23:31:34 | 0.010s | Q:18