feat: full grid collision, freeze, and T-piece support (20 rows)

Extended collision detection from py 12-17 to py 0-17 (full grid).
Extended freeze writes from rows 13-19 to all 20 rows (0-19).
Extended T-piece bottom cell freeze from 6 rows to all 19 rows.
Pieces now correctly collide at ANY height in the grid.
Previously pieces fell through tall stacks because collision
only checked rows 12-17.
This commit is contained in:
enzotar 2026-02-27 13:02:06 -08:00
parent 5c8b397d7b
commit 5e382ce25d

View file

@ -87,11 +87,11 @@ on keydown(ev) -> paused = if ev.key == "p" then (if paused then 0 else 1) else
-- Collision detection: can the piece move down?
-- All pieces: check grid[py+1] at px, px+1, px+2 (top row destination).
-- T-piece (6) only: also check grid[py+2] at px+1 (protruding bottom cell).
-- Bottom wall: py >= 18.
-- Bottom wall: py >= 18. Full grid coverage (py 0-17).
let blocked = 0
-- Piece-aware collision: top row for all, bottom cell only for T-piece
every 33 -> blocked = if py > 17 then 1 else (if py == 17 then (if g18[px] > 0 then 1 else (if g18[px + 1] > 0 then 1 else (if g18[px + 2] > 0 then 1 else (if piece == 6 then (if g19[px + 1] > 0 then 1 else 0) else 0)))) else (if py == 16 then (if g17[px] > 0 then 1 else (if g17[px + 1] > 0 then 1 else (if g17[px + 2] > 0 then 1 else (if piece == 6 then (if g18[px + 1] > 0 then 1 else 0) else 0)))) else (if py == 15 then (if g16[px] > 0 then 1 else (if g16[px + 1] > 0 then 1 else (if g16[px + 2] > 0 then 1 else (if piece == 6 then (if g17[px + 1] > 0 then 1 else 0) else 0)))) else (if py == 14 then (if g15[px] > 0 then 1 else (if g15[px + 1] > 0 then 1 else (if g15[px + 2] > 0 then 1 else (if piece == 6 then (if g16[px + 1] > 0 then 1 else 0) else 0)))) else (if py == 13 then (if g14[px] > 0 then 1 else (if g14[px + 1] > 0 then 1 else (if g14[px + 2] > 0 then 1 else (if piece == 6 then (if g15[px + 1] > 0 then 1 else 0) else 0)))) else (if py == 12 then (if g13[px] > 0 then 1 else (if g13[px + 1] > 0 then 1 else (if g13[px + 2] > 0 then 1 else (if piece == 6 then (if g14[px + 1] > 0 then 1 else 0) else 0)))) else 0))))))
-- Piece-aware collision: full grid, top row + T-piece bottom cell
every 33 -> blocked = if py > 17 then 1 else (if py == 17 then (if g18[px] > 0 then 1 else (if g18[px + 1] > 0 then 1 else (if g18[px + 2] > 0 then 1 else (if piece == 6 then (if g19[px + 1] > 0 then 1 else 0) else 0)))) else (if py == 16 then (if g17[px] > 0 then 1 else (if g17[px + 1] > 0 then 1 else (if g17[px + 2] > 0 then 1 else (if piece == 6 then (if g18[px + 1] > 0 then 1 else 0) else 0)))) else (if py == 15 then (if g16[px] > 0 then 1 else (if g16[px + 1] > 0 then 1 else (if g16[px + 2] > 0 then 1 else (if piece == 6 then (if g17[px + 1] > 0 then 1 else 0) else 0)))) else (if py == 14 then (if g15[px] > 0 then 1 else (if g15[px + 1] > 0 then 1 else (if g15[px + 2] > 0 then 1 else (if piece == 6 then (if g16[px + 1] > 0 then 1 else 0) else 0)))) else (if py == 13 then (if g14[px] > 0 then 1 else (if g14[px + 1] > 0 then 1 else (if g14[px + 2] > 0 then 1 else (if piece == 6 then (if g15[px + 1] > 0 then 1 else 0) else 0)))) else (if py == 12 then (if g13[px] > 0 then 1 else (if g13[px + 1] > 0 then 1 else (if g13[px + 2] > 0 then 1 else (if piece == 6 then (if g14[px + 1] > 0 then 1 else 0) else 0)))) else (if py == 11 then (if g12[px] > 0 then 1 else (if g12[px + 1] > 0 then 1 else (if g12[px + 2] > 0 then 1 else (if piece == 6 then (if g13[px + 1] > 0 then 1 else 0) else 0)))) else (if py == 10 then (if g11[px] > 0 then 1 else (if g11[px + 1] > 0 then 1 else (if g11[px + 2] > 0 then 1 else (if piece == 6 then (if g12[px + 1] > 0 then 1 else 0) else 0)))) else (if py == 9 then (if g10[px] > 0 then 1 else (if g10[px + 1] > 0 then 1 else (if g10[px + 2] > 0 then 1 else (if piece == 6 then (if g11[px + 1] > 0 then 1 else 0) else 0)))) else (if py == 8 then (if g9[px] > 0 then 1 else (if g9[px + 1] > 0 then 1 else (if g9[px + 2] > 0 then 1 else (if piece == 6 then (if g10[px + 1] > 0 then 1 else 0) else 0)))) else (if py == 7 then (if g8[px] > 0 then 1 else (if g8[px + 1] > 0 then 1 else (if g8[px + 2] > 0 then 1 else (if piece == 6 then (if g9[px + 1] > 0 then 1 else 0) else 0)))) else (if py == 6 then (if g7[px] > 0 then 1 else (if g7[px + 1] > 0 then 1 else (if g7[px + 2] > 0 then 1 else (if piece == 6 then (if g8[px + 1] > 0 then 1 else 0) else 0)))) else (if py == 5 then (if g6[px] > 0 then 1 else (if g6[px + 1] > 0 then 1 else (if g6[px + 2] > 0 then 1 else (if piece == 6 then (if g7[px + 1] > 0 then 1 else 0) else 0)))) else (if py == 4 then (if g5[px] > 0 then 1 else (if g5[px + 1] > 0 then 1 else (if g5[px + 2] > 0 then 1 else (if piece == 6 then (if g6[px + 1] > 0 then 1 else 0) else 0)))) else (if py == 3 then (if g4[px] > 0 then 1 else (if g4[px + 1] > 0 then 1 else (if g4[px + 2] > 0 then 1 else (if piece == 6 then (if g5[px + 1] > 0 then 1 else 0) else 0)))) else (if py == 2 then (if g3[px] > 0 then 1 else (if g3[px + 1] > 0 then 1 else (if g3[px + 2] > 0 then 1 else (if piece == 6 then (if g4[px + 1] > 0 then 1 else 0) else 0)))) else (if py == 1 then (if g2[px] > 0 then 1 else (if g2[px + 1] > 0 then 1 else (if g2[px + 2] > 0 then 1 else (if piece == 6 then (if g3[px + 1] > 0 then 1 else 0) else 0)))) else (if py == 0 then (if g1[px] > 0 then 1 else (if g1[px + 1] > 0 then 1 else (if g1[px + 2] > 0 then 1 else (if piece == 6 then (if g2[px + 1] > 0 then 1 else 0) else 0)))) else 0))))))))))))))))))
-- Gravity tick
every 33 -> gravityTick = if paused then gravityTick else (if gameOver then gravityTick else gravityTick + 1)
@ -104,48 +104,91 @@ every 33 -> gravityTick = if gravityTick > dropInterval then 0 else gravityTick
every 33 -> lockTick = if blocked then lockTick + 1 else 0
-- ── Freeze piece into grid at py position on lock ──
-- The piece top-row cells go into row py, bottom-row cell into py+1
-- For T-piece: (px,py), (px+1,py), (px+2,py) and (px+1,py+1)
-- We write the top 3 cells into grid[py] and bottom cell into grid[py+1]
-- Top 3 cells go into grid[py], T-piece bottom cell into grid[py+1]
-- Full grid coverage: rows 0-19
-- Freeze top cells into grid row py (for each possible py value)
-- Row 19
every 33 -> g19[px] = if lockTick == 3 then (if py == 19 then piece else g19[px]) else g19[px]
every 33 -> g19[px + 1] = if lockTick == 3 then (if py == 19 then piece else g19[px + 1]) else g19[px + 1]
every 33 -> g19[px + 2] = if lockTick == 3 then (if py == 19 then piece else g19[px + 2]) else g19[px + 2]
-- Row 18
every 33 -> g18[px] = if lockTick == 3 then (if py == 18 then piece else g18[px]) else g18[px]
every 33 -> g18[px + 1] = if lockTick == 3 then (if py == 18 then piece else g18[px + 1]) else g18[px + 1]
every 33 -> g18[px + 2] = if lockTick == 3 then (if py == 18 then piece else g18[px + 2]) else g18[px + 2]
-- Row 17
every 33 -> g17[px] = if lockTick == 3 then (if py == 17 then piece else g17[px]) else g17[px]
every 33 -> g17[px + 1] = if lockTick == 3 then (if py == 17 then piece else g17[px + 1]) else g17[px + 1]
every 33 -> g17[px + 2] = if lockTick == 3 then (if py == 17 then piece else g17[px + 2]) else g17[px + 2]
-- Row 16
every 33 -> g16[px] = if lockTick == 3 then (if py == 16 then piece else g16[px]) else g16[px]
every 33 -> g16[px + 1] = if lockTick == 3 then (if py == 16 then piece else g16[px + 1]) else g16[px + 1]
every 33 -> g16[px + 2] = if lockTick == 3 then (if py == 16 then piece else g16[px + 2]) else g16[px + 2]
-- Row 15
every 33 -> g15[px] = if lockTick == 3 then (if py == 15 then piece else g15[px]) else g15[px]
every 33 -> g15[px + 1] = if lockTick == 3 then (if py == 15 then piece else g15[px + 1]) else g15[px + 1]
every 33 -> g15[px + 2] = if lockTick == 3 then (if py == 15 then piece else g15[px + 2]) else g15[px + 2]
-- Row 14
every 33 -> g14[px] = if lockTick == 3 then (if py == 14 then piece else g14[px]) else g14[px]
every 33 -> g14[px + 1] = if lockTick == 3 then (if py == 14 then piece else g14[px + 1]) else g14[px + 1]
every 33 -> g14[px + 2] = if lockTick == 3 then (if py == 14 then piece else g14[px + 2]) else g14[px + 2]
-- Row 13
every 33 -> g13[px] = if lockTick == 3 then (if py == 13 then piece else g13[px]) else g13[px]
-- Freeze top cells (3 per row, all 20 rows)
every 33 -> g0[px] = if lockTick == 3 then (if py == 0 then piece else g0[px]) else g0[px]
every 33 -> g0[px + 1] = if lockTick == 3 then (if py == 0 then piece else g0[px + 1]) else g0[px + 1]
every 33 -> g0[px + 2] = if lockTick == 3 then (if py == 0 then piece else g0[px + 2]) else g0[px + 2]
every 33 -> g1[px] = if lockTick == 3 then (if py == 1 then piece else g1[px]) else g1[px]
every 33 -> g1[px + 1] = if lockTick == 3 then (if py == 1 then piece else g1[px + 1]) else g1[px + 1]
every 33 -> g1[px + 2] = if lockTick == 3 then (if py == 1 then piece else g1[px + 2]) else g1[px + 2]
every 33 -> g2[px] = if lockTick == 3 then (if py == 2 then piece else g2[px]) else g2[px]
every 33 -> g2[px + 1] = if lockTick == 3 then (if py == 2 then piece else g2[px + 1]) else g2[px + 1]
every 33 -> g2[px + 2] = if lockTick == 3 then (if py == 2 then piece else g2[px + 2]) else g2[px + 2]
every 33 -> g3[px] = if lockTick == 3 then (if py == 3 then piece else g3[px]) else g3[px]
every 33 -> g3[px + 1] = if lockTick == 3 then (if py == 3 then piece else g3[px + 1]) else g3[px + 1]
every 33 -> g3[px + 2] = if lockTick == 3 then (if py == 3 then piece else g3[px + 2]) else g3[px + 2]
every 33 -> g4[px] = if lockTick == 3 then (if py == 4 then piece else g4[px]) else g4[px]
every 33 -> g4[px + 1] = if lockTick == 3 then (if py == 4 then piece else g4[px + 1]) else g4[px + 1]
every 33 -> g4[px + 2] = if lockTick == 3 then (if py == 4 then piece else g4[px + 2]) else g4[px + 2]
every 33 -> g5[px] = if lockTick == 3 then (if py == 5 then piece else g5[px]) else g5[px]
every 33 -> g5[px + 1] = if lockTick == 3 then (if py == 5 then piece else g5[px + 1]) else g5[px + 1]
every 33 -> g5[px + 2] = if lockTick == 3 then (if py == 5 then piece else g5[px + 2]) else g5[px + 2]
every 33 -> g6[px] = if lockTick == 3 then (if py == 6 then piece else g6[px]) else g6[px]
every 33 -> g6[px + 1] = if lockTick == 3 then (if py == 6 then piece else g6[px + 1]) else g6[px + 1]
every 33 -> g6[px + 2] = if lockTick == 3 then (if py == 6 then piece else g6[px + 2]) else g6[px + 2]
every 33 -> g7[px] = if lockTick == 3 then (if py == 7 then piece else g7[px]) else g7[px]
every 33 -> g7[px + 1] = if lockTick == 3 then (if py == 7 then piece else g7[px + 1]) else g7[px + 1]
every 33 -> g7[px + 2] = if lockTick == 3 then (if py == 7 then piece else g7[px + 2]) else g7[px + 2]
every 33 -> g8[px] = if lockTick == 3 then (if py == 8 then piece else g8[px]) else g8[px]
every 33 -> g8[px + 1] = if lockTick == 3 then (if py == 8 then piece else g8[px + 1]) else g8[px + 1]
every 33 -> g8[px + 2] = if lockTick == 3 then (if py == 8 then piece else g8[px + 2]) else g8[px + 2]
every 33 -> g9[px] = if lockTick == 3 then (if py == 9 then piece else g9[px]) else g9[px]
every 33 -> g9[px + 1] = if lockTick == 3 then (if py == 9 then piece else g9[px + 1]) else g9[px + 1]
every 33 -> g9[px + 2] = if lockTick == 3 then (if py == 9 then piece else g9[px + 2]) else g9[px + 2]
every 33 -> g10[px] = if lockTick == 3 then (if py == 10 then piece else g10[px]) else g10[px]
every 33 -> g10[px + 1] = if lockTick == 3 then (if py == 10 then piece else g10[px + 1]) else g10[px + 1]
every 33 -> g10[px + 2] = if lockTick == 3 then (if py == 10 then piece else g10[px + 2]) else g10[px + 2]
every 33 -> g11[px] = if lockTick == 3 then (if py == 11 then piece else g11[px]) else g11[px]
every 33 -> g11[px + 1] = if lockTick == 3 then (if py == 11 then piece else g11[px + 1]) else g11[px + 1]
every 33 -> g11[px + 2] = if lockTick == 3 then (if py == 11 then piece else g11[px + 2]) else g11[px + 2]
every 33 -> g12[px] = if lockTick == 3 then (if py == 12 then piece else g12[px]) else g12[px]
every 33 -> g12[px + 1] = if lockTick == 3 then (if py == 12 then piece else g12[px + 1]) else g12[px + 1]
every 33 -> g12[px + 2] = if lockTick == 3 then (if py == 12 then piece else g12[px + 2]) else g12[px + 2]
every 33 -> g13[px] = if lockTick == 3 then (if py == 13 then piece else g13[px]) else g13[px]
every 33 -> g13[px + 1] = if lockTick == 3 then (if py == 13 then piece else g13[px + 1]) else g13[px + 1]
every 33 -> g13[px + 2] = if lockTick == 3 then (if py == 13 then piece else g13[px + 2]) else g13[px + 2]
every 33 -> g14[px] = if lockTick == 3 then (if py == 14 then piece else g14[px]) else g14[px]
every 33 -> g14[px + 1] = if lockTick == 3 then (if py == 14 then piece else g14[px + 1]) else g14[px + 1]
every 33 -> g14[px + 2] = if lockTick == 3 then (if py == 14 then piece else g14[px + 2]) else g14[px + 2]
every 33 -> g15[px] = if lockTick == 3 then (if py == 15 then piece else g15[px]) else g15[px]
every 33 -> g15[px + 1] = if lockTick == 3 then (if py == 15 then piece else g15[px + 1]) else g15[px + 1]
every 33 -> g15[px + 2] = if lockTick == 3 then (if py == 15 then piece else g15[px + 2]) else g15[px + 2]
every 33 -> g16[px] = if lockTick == 3 then (if py == 16 then piece else g16[px]) else g16[px]
every 33 -> g16[px + 1] = if lockTick == 3 then (if py == 16 then piece else g16[px + 1]) else g16[px + 1]
every 33 -> g16[px + 2] = if lockTick == 3 then (if py == 16 then piece else g16[px + 2]) else g16[px + 2]
every 33 -> g17[px] = if lockTick == 3 then (if py == 17 then piece else g17[px]) else g17[px]
every 33 -> g17[px + 1] = if lockTick == 3 then (if py == 17 then piece else g17[px + 1]) else g17[px + 1]
every 33 -> g17[px + 2] = if lockTick == 3 then (if py == 17 then piece else g17[px + 2]) else g17[px + 2]
every 33 -> g18[px] = if lockTick == 3 then (if py == 18 then piece else g18[px]) else g18[px]
every 33 -> g18[px + 1] = if lockTick == 3 then (if py == 18 then piece else g18[px + 1]) else g18[px + 1]
every 33 -> g18[px + 2] = if lockTick == 3 then (if py == 18 then piece else g18[px + 2]) else g18[px + 2]
every 33 -> g19[px] = if lockTick == 3 then (if py == 19 then piece else g19[px]) else g19[px]
every 33 -> g19[px + 1] = if lockTick == 3 then (if py == 19 then piece else g19[px + 1]) else g19[px + 1]
every 33 -> g19[px + 2] = if lockTick == 3 then (if py == 19 then piece else g19[px + 2]) else g19[px + 2]
-- Freeze T-piece bottom center cell into grid[py+1]
-- (T has a cell at px+1, py+1; also applicable to O, S, Z shapes)
every 33 -> g19[px + 1] = if lockTick == 3 then (if py == 18 then (if piece == 6 then 6 else g19[px + 1]) else g19[px + 1]) else g19[px + 1]
every 33 -> g18[px + 1] = if lockTick == 3 then (if py == 17 then (if piece == 6 then 6 else g18[px + 1]) else g18[px + 1]) else g18[px + 1]
every 33 -> g17[px + 1] = if lockTick == 3 then (if py == 16 then (if piece == 6 then 6 else g17[px + 1]) else g17[px + 1]) else g17[px + 1]
every 33 -> g16[px + 1] = if lockTick == 3 then (if py == 15 then (if piece == 6 then 6 else g16[px + 1]) else g16[px + 1]) else g16[px + 1]
every 33 -> g15[px + 1] = if lockTick == 3 then (if py == 14 then (if piece == 6 then 6 else g15[px + 1]) else g15[px + 1]) else g15[px + 1]
-- Freeze T-piece bottom center cell into grid[py+1] (all rows)
every 33 -> g1[px + 1] = if lockTick == 3 then (if py == 0 then (if piece == 6 then 6 else g1[px + 1]) else g1[px + 1]) else g1[px + 1]
every 33 -> g2[px + 1] = if lockTick == 3 then (if py == 1 then (if piece == 6 then 6 else g2[px + 1]) else g2[px + 1]) else g2[px + 1]
every 33 -> g3[px + 1] = if lockTick == 3 then (if py == 2 then (if piece == 6 then 6 else g3[px + 1]) else g3[px + 1]) else g3[px + 1]
every 33 -> g4[px + 1] = if lockTick == 3 then (if py == 3 then (if piece == 6 then 6 else g4[px + 1]) else g4[px + 1]) else g4[px + 1]
every 33 -> g5[px + 1] = if lockTick == 3 then (if py == 4 then (if piece == 6 then 6 else g5[px + 1]) else g5[px + 1]) else g5[px + 1]
every 33 -> g6[px + 1] = if lockTick == 3 then (if py == 5 then (if piece == 6 then 6 else g6[px + 1]) else g6[px + 1]) else g6[px + 1]
every 33 -> g7[px + 1] = if lockTick == 3 then (if py == 6 then (if piece == 6 then 6 else g7[px + 1]) else g7[px + 1]) else g7[px + 1]
every 33 -> g8[px + 1] = if lockTick == 3 then (if py == 7 then (if piece == 6 then 6 else g8[px + 1]) else g8[px + 1]) else g8[px + 1]
every 33 -> g9[px + 1] = if lockTick == 3 then (if py == 8 then (if piece == 6 then 6 else g9[px + 1]) else g9[px + 1]) else g9[px + 1]
every 33 -> g10[px + 1] = if lockTick == 3 then (if py == 9 then (if piece == 6 then 6 else g10[px + 1]) else g10[px + 1]) else g10[px + 1]
every 33 -> g11[px + 1] = if lockTick == 3 then (if py == 10 then (if piece == 6 then 6 else g11[px + 1]) else g11[px + 1]) else g11[px + 1]
every 33 -> g12[px + 1] = if lockTick == 3 then (if py == 11 then (if piece == 6 then 6 else g12[px + 1]) else g12[px + 1]) else g12[px + 1]
every 33 -> g13[px + 1] = if lockTick == 3 then (if py == 12 then (if piece == 6 then 6 else g13[px + 1]) else g13[px + 1]) else g13[px + 1]
every 33 -> g14[px + 1] = if lockTick == 3 then (if py == 13 then (if piece == 6 then 6 else g14[px + 1]) else g14[px + 1]) else g14[px + 1]
every 33 -> g15[px + 1] = if lockTick == 3 then (if py == 14 then (if piece == 6 then 6 else g15[px + 1]) else g15[px + 1]) else g15[px + 1]
every 33 -> g16[px + 1] = if lockTick == 3 then (if py == 15 then (if piece == 6 then 6 else g16[px + 1]) else g16[px + 1]) else g16[px + 1]
every 33 -> g17[px + 1] = if lockTick == 3 then (if py == 16 then (if piece == 6 then 6 else g17[px + 1]) else g17[px + 1]) else g17[px + 1]
every 33 -> g18[px + 1] = if lockTick == 3 then (if py == 17 then (if piece == 6 then 6 else g18[px + 1]) else g18[px + 1]) else g18[px + 1]
every 33 -> g19[px + 1] = if lockTick == 3 then (if py == 18 then (if piece == 6 then 6 else g19[px + 1]) else g19[px + 1]) else g19[px + 1]
-- Spawn new piece after lock
every 33 -> piece = if lockTick == 3 then nextPiece else piece