Commit Graph

4 Commits

Author SHA1 Message Date
swipelab
6f7d2f4db2 lang migration: rename signed integer types sN -> iN
Mechanical sweep of all .sx sources, plan docs, and tests/expected
snapshots for the sx language rename (s8/s16/s32/s64 -> i8/i16/i32/i64).
Verified: tools/run_tests.sh 23/23.

Note: the ios-sim build has 2 pre-existing 'restart' dot-call errors
from the sx opt-in UFCS change (sx a47ea14) — independent of this
rename (present pre-sweep); migrated in the follow-up commit.
2026-06-12 09:36:51 +03:00
swipelab
a7b41ccbca migrate to the new for-loop syntax
Drop the ':' before captures (for xs (x) / for 0..n (i)); the index
capture becomes the trailing open range (for xs, 0.. (x, i)). 136
headers across 26 files, mechanical.

Five headless tests (banner_layout, hit_test, swipe_commit,
swipe_intent, swipe_reshuffle) also gain a direct
#import "modules/ui/types.sx" — they named Point/Frame through a
transitive import, which bare visibility no longer permits.

Gates: sx build --target ios-sim main.sx links; tools/run_tests.sh
23/23.
2026-06-10 20:39:59 +03:00
swipelab
e77c470546 P7.1: freeze finished level — reject moves after won/lost
play_turn now checks level_status before committing: a won or lost
level rejects the swap (accepted=false) with no move spent and no
score change, until restart returns it to in_progress. Adds an
accepted flag to TurnResult so the renderer can show the move was
ignored. Regression in tests/level.sx asserts post-won and post-lost
play_turn leaves score/moves/status unchanged and that restart
re-enables play.
2026-06-05 08:37:28 +03:00
swipelab
a40a994ae1 P7.1: turn / goal state machine (pure sx)
Add a thin, deterministic level loop over the headless model in board.sx:

- target_score: per-level score goal (DEFAULT_TARGET_SCORE=1500), seeded by init.
- Status (in_progress/won/lost) derived purely from score/target/move budget via
  level_status; won is checked before lost so meeting the goal on the final move
  wins. status_name for the HUD/snapshots.
- has_legal_swap: allocation-free deadlock probe (first legal pair short-circuits).
- reshuffle: Fisher-Yates over existing gems via the board's seeded RNG until the
  arrangement has no immediate match and at least one legal move; consumes no
  move, terminates via MAX_RESHUFFLE_TRIES.
- restart: reseed a fresh, reproducible level (resets cells/score/moves/goal).
- play_turn / TurnResult: commit_swap then reshuffle on deadlock while in
  progress, reporting the resulting status.

tests/level.sx (golden tests/expected/level.{stdout,exit}) asserts: start
in_progress; one legal swap crossing a low goal -> won transition; budget
exhausted below an unreachable goal -> lost transition; a provably deadlocked
diagonal Latin-square board ((col-row) mod 6) reshuffles to >=1 legal move with
no immediate match and no move spent; restart resets progress and a fixed seed
reproduces the same starting board.

Gate: sx build --target ios-sim main.sx (exit 0); bash tools/run_tests.sh
(17 passed, 0 failed).
2026-06-05 08:25:08 +03:00