Commit Graph

9 Commits

Author SHA1 Message Date
funman300 862f7e4b48 chore(core): delete deck.rs and scoring.rs
Build and Deploy / build-and-push (push) Failing after 1m18s
- deck.rs (193 lines) — Deck/deal_klondike replaced by Klondike::with_seed()
- scoring.rs (152 lines) — scoring fns superseded by KlondikeAdapter; move
  compute_time_bonus to klondike_adapter.rs, update win_summary_plugin import
- Remove rand dep from solitaire_core (only used by deck.rs)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-29 17:42:30 -07:00
funman300 6496e130f3 feat(core): Step 2 — replace pile management with Session<Klondike>
Build and Deploy / build-and-push (push) Failing after 29s
- Delete rules.rs (228 lines) — move validation now handled by klondike engine
- Delete SolverState DFS from solver.rs (~900 lines) — replaced by session.solve()
- Rewrite GameState::new_with_mode() using Klondike::with_seed() (removes deck.rs dep)
- Rewrite move_cards/draw/undo to use Session<Klondike> as move executor
- Remove internal undo_stack (VecDeque<StateSnapshot>) — session owns history
- Sync piles from KlondikeState after each move via sync_piles_from_session()
- Update engine layer (game_plugin, input_plugin, card_plugin, etc.) to new API
- Net: 821 insertions, 3872 deletions (-3051 lines)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-29 17:31:09 -07:00
funman300 f1914b4398 feat(core): add klondike v0.2.0 dep and KlondikeAdapter (integration steps 1, 3, 4)
Build and Deploy / build-and-push (push) Failing after 1m0s
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>
2026-05-29 14:34:22 -07:00
funman300 8a5fa8751c feat(core,engine): Klondike solver and "Winnable deals only" toggle
Closes Quat investigation #1. Today some Klondike deals are
unwinnable from the start and the player has no signal that the
deal they were given is solvable. A new Settings → Gameplay toggle
"Winnable deals only" (default off) makes the engine retry seeds
at deal-time until the solver returns Winnable, up to a cap.

Solver

solitaire_core::solver is a hand-rolled iterative-DFS solver with
memoisation on a 64-bit canonical state hash. Move enumeration is
priority-ordered: foundation moves first (zero choice when an Ace
or rank-up exists), inter-tableau moves second, waste-to-tableau
third, stock-draw last. The draw is skipped when the cycle counter
shows we've recirculated the entire stock without progress —
Klondike's deterministic stock cycle means further draws can't
unlock anything new.

Two budget knobs (move_budget = 100k, state_budget = 200k by
default) cap pathological cases at Inconclusive; the caller treats
Inconclusive as "winnable" so the player isn't penalised for the
solver giving up. Median solve time is 2 ms; pathological
inconclusives top out near 120 ms.

Switched from recursive to iterative DFS after a real-deal solve
overflowed Rust's default 8 MB thread stack. Behaviour identical;
the change is invisible to callers.

Pure logic — solitaire_core has no Bevy or I/O. Same input always
yields the same SolverResult.

Settings

Settings.winnable_deals_only is a #[serde(default)] bool; legacy
files load to false. SOLVER_DEAL_RETRY_CAP = 50 caps the retry
loop. The Settings → Gameplay toggle reads as "Winnable deals only"
with a "(may take a moment when on)" caption.

Engine integration

handle_new_game's seed-selection path now branches on the toggle.
When on AND mode is Classic AND no specific seed was requested
(daily challenges, replays, and explicit-seed requests bypass the
solver), choose_winnable_seed walks seed N, N+1, N+2, … calling
try_solve until it finds Winnable or Inconclusive. If the cap is
hit without a verdict, the latest tried seed is used so the player
always gets a deal rather than spinning forever.

19 new tests (11 solver, 3 settings, 5 engine including the
choose_winnable_seed unit). Two ignored bench/scan helpers
(solver_bench, find_unwinnable) for ad-hoc profiling.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 23:02:22 +00:00
funman300 82fa584cbb feat(core): add achievement module with 14 unlock conditions
Introduces AchievementContext (stats + last-win snapshot), AchievementDef,
ALL_ACHIEVEMENTS, and check_achievements. Adds undo_count to GameState
so the no_undo and speed_and_skill conditions are evaluable.

Skipped achievements that depend on features not yet built:
daily_devotee (progress), comeback (recycle counter), zen_winner (modes),
perfectionist (max-score calc). They land in later phases.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-24 12:50:46 -07:00
Solitaire Quest 58f1465927 feat(core): add GameState with draw, move_cards, undo, win/auto-complete detection
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 11:13:49 -07:00
Solitaire Quest 17bbec054c feat(core): add pile, error, deck, rules, scoring modules with tests
Implements PileType/Pile, MoveError (thiserror), Deck with seeded shuffle,
deal_klondike layout, foundation/tableau placement rules, and Windows XP
Standard scoring — 41 tests, clippy clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 11:07:58 -07:00
Solitaire Quest fcf878b403 feat(core): add Card, Suit, Rank types with tests
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 11:05:08 -07:00
Solitaire Quest 684f07746d feat(workspace): initialize all seven crates with stubs and blank Bevy window
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 11:00:42 -07:00