Skip to content

Add Forty Thieves game variant - #61

Merged
austin-smith merged 3 commits into
mainfrom
forty-thieves-variant
Jul 13, 2026
Merged

austin-smith merged 3 commits into
mainfrom
forty-thieves-variant

Conversation

@austin-smith

Copy link
Copy Markdown
Owner

What Changed

  • Adds Forty Thieves: two decks dealt into ten columns of four face-up cards, tableau built down by suit with strictly single-card moves, eight player-built foundations that lock once a card lands, and a draw-one stock with a single pass and no recycle. Rules follow Add Forty Thieves game variant #49 exactly, verified against all three of its references; deliberate rule choices are documented in docs/rules/fortythieves.md.
  • Solver-backed hints via a new FortyThievesPlanner — a Spider-family cached improving-line best-first search with two-deck-aware canonicalization (twin-top and same-suit-foundation dedup, first-empty-column) and a monotone stock-tap fallback that structurally cannot loop. Wired into HintPlanner with a 0.3s interactive budget.
  • New GameVariant.allowsFoundationRollback separates locked foundations from Klondike-style rollback foundations; the tap policy gains a Forty Thieves-specific safe-banking rule (rank r is safe once both same-suit foundations reach r − 2), and auto-finish fires once the stock is empty, playing tableau tops and the waste.
  • Full variant surface: top-row and mini-board views, in-app rules/scoring/terms, README rows, generated screenshot fixture, hint-probe wiring with a recorded ledger baseline, and per-variant test suites.
  • Fixes two review findings in the shared tableau deal flight (Spider/Scorpion): a gameplay move landing mid-flight now lands the flight instead of finishing against a stale frame (mirroring the undo path's existing rule), and the pre-flight frame wait no longer stalls 240ms when a dealt card completes a run and banks on arrival.

Why

Closes #49. Forty Thieves is the best-known two-deck patience and builds on the two-deck support introduced for Spider, while being the app's first variant to combine two decks with player-built foundations — hence the new rollback distinction rather than overloading playerBuildsFoundations.

Validation

  • 493 unit tests pass on macOS (43 new across Forty Thieves rules/session/persistence/planner suites); iOS Simulator build green.
  • Hint probe, 500 seeded deals: fortythieves 3.4% hint-following vs 0.0% random control, every loss an honest deadlock, zero stalemate loops, zero revisit events (now gated like Yukon's); baseline and measured tuning directions recorded in the ledger. The scorpion baseline reproduces exactly post-merge (14.8% / 2.8%), confirming the sync changed nothing behaviorally.
  • Played end-to-end in the iOS simulator: deal shape, same-suit builds, empty-column fills, waste plays, foundation banking, locked foundations, no stock recycle, hint highlighting, and the mode picker; Scorpion's three-card deal flight re-verified after the animation fixes.

UI Changes

  • New Forty Thieves board: stock and waste on the left with eight foundation slots aligned 1:1 over the ten tableau columns, plus a matching mode-picker mini-board slotted between Golf and Yukon.
  • New in-app Rules & Scoring content for the variant.

# Conflicts:
#	ComputerSolitaire/Fixtures/ScreenshotFixtures.swift
#	ComputerSolitaire/Game/Shared/AutoMoveAdvisor.swift
#	ComputerSolitaire/Game/Shared/GameMode.swift
#	ComputerSolitaire/Game/Shared/GamePersistence.swift
#	ComputerSolitaire/Game/Shared/GameSessionInteraction.swift
#	ComputerSolitaire/Game/Shared/GameState.swift
#	ComputerSolitaire/Game/Shared/GameVariant.swift
#	ComputerSolitaire/Game/Shared/HintAdvisor.swift
#	ComputerSolitaire/Game/Shared/TapMovePolicy.swift
#	ComputerSolitaire/Views/RulesAndScoringView.swift
#	ComputerSolitaire/Views/Shared/ContentView.swift
#	ComputerSolitaire/Views/Shared/GameModePickerView.swift
#	ComputerSolitaire/Views/StatisticsView.swift
#	ComputerSolitaireTests/Shared/ScreenshotFixtureTests.swift
#	README.md
#	tools/hint-probe/README.md
#	tools/hint-probe/main.swift
#	tools/hint-probe/run.sh
a gameplay move landing during a deal flight could relocate a card the
overlay was still flying toward (a scorpion group move carries an
in-flight card away with the cards beneath it), so the flight now lands
the moment any other move arrives, matching the undo path's existing
rule. the pre-flight frame wait also stalled 240ms whenever a dealt
card completed a run and banked on arrival — run piles publish only
their top card's frame — so the wait now covers only cards still on
the tableau, the only cards that ever publish a landing frame.
@austin-smith
austin-smith merged commit 013cfbc into main Jul 13, 2026
2 checks passed
@austin-smith
austin-smith deleted the forty-thieves-variant branch July 13, 2026 22:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Forty Thieves game variant

1 participant