- Replace PileType with typed KlondikePile (Foundation/Tableau variants)
throughout solitaire_core, solitaire_wasm, and solitaire_engine;
ReplayMove now uses SavedKlondikePile for serialisation stability
- Split replay_overlay.rs into replay_overlay/ module (mod, format,
input, update, tests) for maintainability
- Add klondike dep to solitaire_engine and solitaire_data Cargo.toml
- Add TestPileState infrastructure to game_state.rs for engine unit tests
- Rebuild solitaire_wasm pkg (js + wasm artefacts updated)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
These were scaffolded for a future KlondikeState::from_piles() path
that never materialised. card_from_kl (used by sync_piles_from_session)
is retained; suit_from_kl / rank_from_kl are narrowed to pub(crate).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Step 2 prep — card_game dep + type-conversion utilities:
- Add card_game = "0.3.0" (registry Quaternions) to workspace + core
- suit_to_kl / suit_from_kl, rank_to_kl / rank_from_kl
- card_to_kl (drops id, Deck1), card_from_kl (reconstructs stable id
from Clubs-first suit×13+rank ordering matching deck.rs)
- Ready to wire into KlondikeState pile projection once upstream
adds KlondikeState::from_piles()
Step 5 — GameMode-aware scoring in the adapter:
- score_for_move_with_mode, score_for_flip_with_mode (return 0 in Zen)
- apply_undo_score (static, handles Zen + −15 penalty + clamp)
- score_for_recycle_with_mode (return 0 in Zen)
- game_state.rs: all inline GameMode::Zen checks replaced with
adapter calls; adapter is now the single source of truth for
"what score does this action give in this mode"
192 tests pass; clippy -D warnings clean.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Step 1 — Cargo & registry:
- Add .cargo/config.toml with Quaternions sparse registry
(https://git.aleshym.co/api/packages/Quaternions/cargo/)
- Add klondike = "0.2.0" to workspace deps (+ card_game v0.3.0,
arrayvec v0.7.6 as transitives via the Quaternions registry)
- Add klondike as a solitaire_core dep
Step 3 — KlondikeConfig / MoveFromFoundationConfig:
- KlondikeAdapter::new(draw_mode, take_from_foundation) builds a
KlondikeConfig with the correct DrawStockConfig and
MoveFromFoundationConfig (Allowed/Disallowed); exposes it via
klondike_config() for future solver and pile-mapping steps
Step 4 — Scoring via ScoringConfig:
- GameState.adapter (serde(skip)) owns the authoritative KlondikeConfig
with ScoringConfig::DEFAULT (WXP values)
- score_for_move/flip/undo/recycle replace direct scoring.rs calls;
scoring.rs retained for reference and future deletion
- score_for_recycle implements the WXP free-recycle allowance rule
that ScoringConfig::recycle cannot express (flat delta)
- PartialEq/Eq for KlondikeAdapter compare draw_stock and
move_from_foundation only (scoring is always DEFAULT)
All 192 solitaire_core tests pass; clippy -D warnings clean.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>