0,]']±>Sï}WÿÍu§ğp8·d%qy)6o;]ÉA¦ösï÷ôôô”°ÂVl†3= min and value <= max end function load_level(lines) played_win_music = false win_timer=0 for y=1,BOARD_H do for x=1,BOARD_W do board[y][x]=0 end end for y=1,BOARD_H do for x=1,BOARD_W do local c=lines[y]:sub(x,x) board[y][x]=(c=="0" and 0) or c end end piece_x, piece_y=0,0 current_piece=2 for i=1,4 do placed[i]=false selectable[i]=true placed_positions[i]=nil end level_complete=false prev_complete=false played_win_music=false music(-1) for i=BOARD_H+1,#lines do local piece_name=lines[i] for pi=1,4 do if pieces[pi+1].name==piece_name then placed[pi]=true selectable[pi]=false -- new: mark placed positions so we don't show ghost for already placed pieces for y=1,BOARD_H do for x=1,BOARD_W do local v=board[y][x] if v=="X" or v=="Y" then placed_positions[pi]={x=0, y=0} -- dummy position so it's treated as placed end end end end end end local found=false for i=1,4 do if selectable[i] then current_piece=i+1 found=true break end end if not found then current_piece=2 print ("A") end end function all_y_connected() local y_tiles={} for y=1,BOARD_H do for x=1,BOARD_W do if board[y][x]=="Y" then table.insert(y_tiles,{x=x,y=y}) end end end if #y_tiles==0 then return false end -- Check all pieces placed for i=1,4 do if selectable[i] and not placed[i] then return false end end -- If only one Y tile, trivially straight if #y_tiles==1 then return true end local dx = y_tiles[2].x - y_tiles[1].x local dy = y_tiles[2].y - y_tiles[1].y -- Determine direction if dx==0 then -- vertical for i=3,#y_tiles do if y_tiles[i].x ~= y_tiles[1].x then return false end end return true elseif dy==0 then -- horizontal for i=3,#y_tiles do if y_tiles[i].y ~= y_tiles[1].y then return false end end return true elseif math.abs(dx) == math.abs(dy) then -- diagonals local sign_x = dx > 0 and 1 or -1 local sign_y = dy > 0 and 1 or -1 for i=3,#y_tiles do local tdx = y_tiles[i].x - y_tiles[1].x local tdy = y_tiles[i].y - y_tiles[1].y if math.abs(tdx) ~= math.abs(tdy) or (tdx ~= 0 and (tdx/math.abs(tdx)) ~= sign_x) or (tdy ~= 0 and (tdy/math.abs(tdy)) ~= sign_y) then return false end end return true end return false end function playwin() if not played_win_music then tracktoplay=1 if between(current_level,1,12) then tracktoplay=1 elseif between(current_level,13,24) then tracktoplay=4 elseif between(current_level,15,36) then tracktoplay=5 elseif between(current_level,37,50) then tracktoplay=6 end music(tracktoplay,0,0,false) played_win_music=true end end played_win_music = false win_timer=0 function TIC() cls() if game_state == "menu" then local title="PENGUIN PARADE" print(title,21,1,3,2,2) print(title,22,2,5,2,2) print("Select a level: ",21,21,9) local columns_per_row = 10 local spacing_x = 20 local spacing_y = 15 local start_x = 20 local start_y = 30 for i=1,#levels do if between(i,1,12) then lc=5 elseif between(i,13,24) then lc=3 elseif between(i,25,36) then lc=4 elseif between(i,37,50) then lc=1 end local col = (i-1) % columns_per_row local row = math.floor((i-1) / columns_per_row) local x = start_x + col * spacing_x local y = start_y + row * spacing_y local color = (i == selected_level) and 11 or lc if i ~= selected_level then print(""..i, x, y, color) else local distancer=i<10 and 0 or 6 print(""..i, x-distancer, y, color+1,2,2) end end rect(0,100,300,100,8) print ("* Connect the 4 Penguins in a horizontal,",0,100,7) print (" vertical or diagonal line.",10,110,7) print ("* Use arrows keys to move on the board",0,120,7,false,1) print ("* B/Y-drop/pick up, A/X-change selected",0,130,7,false,1) print ("Good luck!",10,150) if (btnp(0) or btnp(2)) and selected_level > 1 then selected_level=selected_level-1 end if (btnp(1) or btnp(3)) and selected_level < #levels then selected_level=selected_level+1 end if (btnp(4) or btnp(5) or btnp(6) or btnp(7)) then current_level=selected_level load_level(levels[current_level]) game_state="playing" end else local p = pieces[current_piece] local min_dx, max_dx, min_dy, max_dy = 0,0,0,0 for _,o in ipairs(p.shape) do local dx, dy = o[1], o[2] if dx < min_dx then min_dx=dx end if dx > max_dx then max_dx=dx end if dy < min_dy then min_dy=dy end if dy > max_dy then max_dy=dy end end if btnp(0) and piece_y + min_dy -1 >=0 then piece_y=piece_y-1 end if btnp(1) and piece_y + max_dy +1 < BOARD_H then piece_y=piece_y+1 end if btnp(2) and piece_x + min_dx -1 >=0 then piece_x=piece_x-1 end if btnp(3) and piece_x + max_dx +1 < BOARD_W then piece_x=piece_x+1 end if btnp(5) or btnp(7) then local i=current_piece-1 if placed[i] and placed_positions[i] then local pos=placed_positions[i] remove_piece(p, pos.x, pos.y) placed[i]=false placed_positions[i]=nil elseif selectable[i] and not placed[i] and piece_fits(p) then place_piece(p, piece_x, piece_y) placed[i]=true placed_positions[i]={x=piece_x, y=piece_y} -- 🔹 Auto-select next unplaced piece local found=false for j=1,4 do if selectable[j] and not placed[j] then current_piece=j+1 found=true break end end end if placed[i]==true then music(2,0,0,false) end if placed[i]==false then music(3,0,0,false) end end if btnp(4) or btnp(6) then local any=false for j=1,4 do if selectable[j] then any=true break end end if any then repeat current_piece=current_piece+1 if current_piece>5 then current_piece=2 end until selectable[current_piece-1] end end print("LEVEL "..current_level,43,6,2) print("LEVEL "..current_level,44,7,4) for y=1,BOARD_H do for x=1,BOARD_W do local v=board[y][x] if v==0 then rect(x*TILE_SIZE,y*TILE_SIZE,TILE_SIZE-1,TILE_SIZE-1,13) elseif v=="X" then rect(x*TILE_SIZE,y*TILE_SIZE,TILE_SIZE-1,TILE_SIZE-1,5) elseif v=="Y" then rect(x*TILE_SIZE,y*TILE_SIZE,TILE_SIZE-1,TILE_SIZE-1,8) spr(0, x*TILE_SIZE-1, (y+1)*TILE_SIZE-16, 1,1,0,0,2,2) end end end -- 🔹 Blink the ghost piece local blink_on = ((time() // 250) % 2) == 0 if blink_on then for idx,o in ipairs(p.shape) do local x=piece_x+o[1]+1 local y=piece_y+o[2]+1 local col=2 if p.y_positions then for _,yi in ipairs(p.y_positions) do if idx==yi then col=9 end end end if col==9 then spr(0, x*TILE_SIZE-1, (y+1)*TILE_SIZE-16, 1,1,0,0,2,2) else rectb(x*TILE_SIZE,y*TILE_SIZE,TILE_SIZE-1,TILE_SIZE-1,col) end end end local shift_right=30 local side_x=BOARD_W*TILE_SIZE+10 local side_y=10 local mini_TILE_SIZE=TILE_SIZE/2 for i=1,4 do if selectable[i] then local p=pieces[i+1] local min_x, min_y, max_x, max_y = 999,999,-999,-999 for idx,o in ipairs(p.shape) do local x=side_x+o[1]*mini_TILE_SIZE local y=side_y+o[2]*mini_TILE_SIZE if xmax_x then max_x=x end if ymax_y then max_y=y end local col=placed[i] and 2 or 6 if p.y_positions then for _,yi in ipairs(p.y_positions) do if idx==yi then col=9 end end end if placed[i] then rectb(x+shift_right,y+10,mini_TILE_SIZE-1,mini_TILE_SIZE-1,col) else rect(x+shift_right,y+10,mini_TILE_SIZE-1,mini_TILE_SIZE-1,col) end end if i+1 == current_piece then rectb(min_x+shift_right-2, min_y+8, (max_x-min_x)+mini_TILE_SIZE+4, (max_y-min_y)+mini_TILE_SIZE+4, 15) end side_y=side_y+mini_TILE_SIZE+20 end end local complete=all_y_connected() if complete and not prev_complete then level_complete=true playwin() win_timer=0 end if complete then local lc_message="LEVEL COMPLETE!" print(lc_message,20,BOARD_H*TILE_SIZE+18,2) print(lc_message,21,BOARD_H*TILE_SIZE+19,4) end prev_complete=complete if level_complete then win_timer=win_timer+1 if win_timer>60 then for k=0,7 do if btnp(k) then current_level=current_level+1 if current_level>#levels then game_state="menu" else load_level(levels[current_level]) end break end end end end end end function piece_fits(p) for _,o in ipairs(p.shape) do local x=piece_x+o[1]+1 local y=piece_y+o[2]+1 if x<1 or y<1 or x>BOARD_W or y>BOARD_H then return false end if board[y][x]~=0 then return false end end return true end function place_piece(p, px, py) for idx,o in ipairs(p.shape) do local x=px+o[1]+1 local y=py+o[2]+1 local cell="X" if p.y_positions then for _,yi in ipairs(p.y_positions) do if idx==yi then cell="Y" break end end end board[y][x]=cell end end function remove_piece(p, px, py) for _,o in ipairs(p.shape) do local x=px+o[1]+1 local y=py+o[2]+1 if x>=1 and y>=1 and x<=BOARD_W and y<=BOARD_H then if board[y][x]=="X" or board[y][x]=="Y" then board[y][x]=0 end end end end