refactor: complete collision system rewrite — decomposed sub-signals
Replaced single monolithic blocked expression with 4 composable signals: - blockedWall: piece-type aware bottom wall (T=18, others=19) - blockedTop: grid[py+1] at px,px+1,px+2 (all pieces) - blockedFoot: grid[py+2] at px+1 (T-piece foot only) - blockedI4: grid[py+1] at px+3 (I-piece 4th cell only) - blocked: OR combination of all 4 Fixed auto-drop cap from py<18 to py<19 so flat pieces reach the bottom row. Fixed hard drop and keyboard per piece type.
This commit is contained in:
parent
d2cb302961
commit
9fb65e6a77
1 changed files with 29 additions and 12 deletions
|
|
@ -76,28 +76,45 @@ let lockTick = 0
|
|||
on keydown(ev) -> px = if gameOver then px else (if paused then px else (if ev.key == "ArrowLeft" then (if px > 0 then px - 1 else px) else px))
|
||||
on keydown(ev) -> px = if gameOver then px else (if paused then px else (if ev.key == "ArrowRight" then (if px < 7 then px + 1 else px) else px))
|
||||
on keydown(ev) -> rotation = if gameOver then rotation else (if paused then rotation else (if ev.key == "ArrowUp" then (rotation + 1) % 4 else rotation))
|
||||
on keydown(ev) -> py = if gameOver then py else (if paused then py else (if blocked then py else (if ev.key == "ArrowDown" then (if py < 18 then py + 1 else py) else py)))
|
||||
on keydown(ev) -> py = if gameOver then py else (if paused then py else (if blocked then py else (if ev.key == " " then 18 else py)))
|
||||
on keydown(ev) -> py = if gameOver then py else (if paused then py else (if blocked then py else (if ev.key == "ArrowDown" then (if py < 19 then py + 1 else py) else py)))
|
||||
on keydown(ev) -> py = if gameOver then py else (if paused then py else (if blocked then py else (if ev.key == " " then (if piece == 6 then 18 else 19) else py)))
|
||||
on keydown(ev) -> paused = if ev.key == "p" then (if paused then 0 else 1) else paused
|
||||
|
||||
-- ================================================================
|
||||
-- LAYER 4: DERIVED SIGNALS — Collision, gravity, lock, line clear
|
||||
-- ================================================================
|
||||
-- COLLISION SYSTEM (decomposed into composable sub-signals)
|
||||
-- ================================================================
|
||||
|
||||
-- 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. Full grid coverage (py 0-17).
|
||||
-- Sub-signal 1: Bottom wall (piece-type dependent)
|
||||
-- T-piece stops at py=18 (foot at 19), all others at py=19
|
||||
let blockedWall = 0
|
||||
every 33 -> blockedWall = if piece == 6 then (if py >= 18 then 1 else 0) else (if py >= 19 then 1 else 0)
|
||||
|
||||
-- Sub-signal 2: Top row collision — check grid[py+1] at px, px+1, px+2
|
||||
-- This is the core 3-cell check shared by ALL piece types
|
||||
let blockedTop = 0
|
||||
every 33 -> blockedTop = if py >= 19 then 0 else (if py == 18 then (if g19[px] > 0 then 1 else (if g19[px + 1] > 0 then 1 else (if g19[px + 2] > 0 then 1 else 0))) 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 0))) else 0)))))))))))))))))))
|
||||
|
||||
-- Sub-signal 3: T-piece foot collision — check grid[py+2] at px+1
|
||||
-- Only applies to T-piece (piece==6)
|
||||
let blockedFoot = 0
|
||||
every 33 -> blockedFoot = if piece != 6 then 0 else (if py >= 18 then 0 else (if py == 17 then (if g19[px + 1] > 0 then 1 else 0) else (if py == 16 then (if g18[px + 1] > 0 then 1 else 0) else (if py == 15 then (if g17[px + 1] > 0 then 1 else 0) else (if py == 14 then (if g16[px + 1] > 0 then 1 else 0) else (if py == 13 then (if g15[px + 1] > 0 then 1 else 0) else (if py == 12 then (if g14[px + 1] > 0 then 1 else 0) else (if py == 11 then (if g13[px + 1] > 0 then 1 else 0) else (if py == 10 then (if g12[px + 1] > 0 then 1 else 0) else (if py == 9 then (if g11[px + 1] > 0 then 1 else 0) else (if py == 8 then (if g10[px + 1] > 0 then 1 else 0) else (if py == 7 then (if g9[px + 1] > 0 then 1 else 0) else (if py == 6 then (if g8[px + 1] > 0 then 1 else 0) else (if py == 5 then (if g7[px + 1] > 0 then 1 else 0) else (if py == 4 then (if g6[px + 1] > 0 then 1 else 0) else (if py == 3 then (if g5[px + 1] > 0 then 1 else 0) else (if py == 2 then (if g4[px + 1] > 0 then 1 else 0) else (if py == 1 then (if g3[px + 1] > 0 then 1 else 0) else (if py == 0 then (if g2[px + 1] > 0 then 1 else 0) else 0)))))))))))))))))))
|
||||
|
||||
-- Sub-signal 4: I-piece 4th cell collision — check grid[py+1] at px+3
|
||||
-- Only applies to I-piece (piece==1)
|
||||
let blockedI4 = 0
|
||||
every 33 -> blockedI4 = if piece != 1 then 0 else (if py >= 19 then 0 else (if py == 18 then (if g19[px + 3] > 0 then 1 else 0) else (if py == 17 then (if g18[px + 3] > 0 then 1 else 0) else (if py == 16 then (if g17[px + 3] > 0 then 1 else 0) else (if py == 15 then (if g16[px + 3] > 0 then 1 else 0) else (if py == 14 then (if g15[px + 3] > 0 then 1 else 0) else (if py == 13 then (if g14[px + 3] > 0 then 1 else 0) else (if py == 12 then (if g13[px + 3] > 0 then 1 else 0) else (if py == 11 then (if g12[px + 3] > 0 then 1 else 0) else (if py == 10 then (if g11[px + 3] > 0 then 1 else 0) else (if py == 9 then (if g10[px + 3] > 0 then 1 else 0) else (if py == 8 then (if g9[px + 3] > 0 then 1 else 0) else (if py == 7 then (if g8[px + 3] > 0 then 1 else 0) else (if py == 6 then (if g7[px + 3] > 0 then 1 else 0) else (if py == 5 then (if g6[px + 3] > 0 then 1 else 0) else (if py == 4 then (if g5[px + 3] > 0 then 1 else 0) else (if py == 3 then (if g4[px + 3] > 0 then 1 else 0) else (if py == 2 then (if g3[px + 3] > 0 then 1 else 0) else (if py == 1 then (if g2[px + 3] > 0 then 1 else 0) else (if py == 0 then (if g1[px + 3] > 0 then 1 else 0) else 0))))))))))))))))))))
|
||||
|
||||
-- Combined blocked signal: any sub-signal triggers block
|
||||
let blocked = 0
|
||||
|
||||
-- Piece-aware collision: check px+3 for I-piece, py+2 at px+1 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 == 1 then (if g18[px + 3] > 0 then 1 else 0) 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 == 1 then (if g17[px + 3] > 0 then 1 else 0) 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 == 1 then (if g16[px + 3] > 0 then 1 else 0) 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 == 1 then (if g15[px + 3] > 0 then 1 else 0) 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 == 1 then (if g14[px + 3] > 0 then 1 else 0) 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 == 1 then (if g13[px + 3] > 0 then 1 else 0) 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 == 1 then (if g12[px + 3] > 0 then 1 else 0) 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 == 1 then (if g11[px + 3] > 0 then 1 else 0) 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 == 1 then (if g10[px + 3] > 0 then 1 else 0) 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 == 1 then (if g9[px + 3] > 0 then 1 else 0) 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 == 1 then (if g8[px + 3] > 0 then 1 else 0) 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 == 1 then (if g7[px + 3] > 0 then 1 else 0) 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 == 1 then (if g6[px + 3] > 0 then 1 else 0) 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 == 1 then (if g5[px + 3] > 0 then 1 else 0) 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 == 1 then (if g4[px + 3] > 0 then 1 else 0) 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 == 1 then (if g3[px + 3] > 0 then 1 else 0) 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 == 1 then (if g2[px + 3] > 0 then 1 else 0) 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 == 1 then (if g1[px + 3] > 0 then 1 else 0) else (if piece == 6 then (if g2[px + 1] > 0 then 1 else 0) else 0))))) else 0))))))))))))))))))
|
||||
every 33 -> blocked = if blockedWall then 1 else (if blockedTop then 1 else (if blockedFoot then 1 else (if blockedI4 then 1 else 0)))
|
||||
|
||||
-- Gravity tick
|
||||
every 33 -> gravityTick = if paused then gravityTick else (if gameOver then gravityTick else gravityTick + 1)
|
||||
|
||||
-- Auto-drop: only if NOT blocked
|
||||
every 33 -> py = if paused then py else (if gameOver then py else (if blocked then py else (if gravityTick > dropInterval then (if py < 18 then py + 1 else py) else py)))
|
||||
-- Auto-drop: py can go up to 19 (not 18) — blocked wall handles per-piece limits
|
||||
every 33 -> py = if paused then py else (if gameOver then py else (if blocked then py else (if gravityTick > dropInterval then (if py < 19 then py + 1 else py) else py)))
|
||||
every 33 -> gravityTick = if gravityTick > dropInterval then 0 else gravityTick
|
||||
|
||||
-- Lock detection: start counting when blocked
|
||||
|
|
@ -406,7 +423,7 @@ view tetris_game = column [
|
|||
}
|
||||
button "Left" { click: px = if px > 0 then px - 1 else px, variant: "secondary" }
|
||||
button "Right" { click: px = if px < 7 then px + 1 else px, variant: "secondary" }
|
||||
button "Drop" { click: py = if blocked then py else 18, variant: "secondary" }
|
||||
button "Drop" { click: py = if blocked then py else (if piece == 6 then 18 else 19), variant: "secondary" }
|
||||
button "Rotate" { click: rotation = (rotation + 1) % 4, variant: "secondary" }
|
||||
button "Reset" {
|
||||
click: score = 0; lines = 0; level = 1; gameOver = 0; paused = 0; piece = 6; nextPiece = 1; px = 3; py = 0; rotation = 0; g16 = [0,0,0,0,0,0,0,0,0,0]; g17 = [0,0,0,0,0,0,0,0,0,0]; g18 = [0,0,0,0,0,0,0,0,0,0]; g19 = [0,0,0,0,0,0,0,0,0,0],
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue