feat(difficulty): add difficulty-tier game mode with seed catalogs and home UI
Adds DifficultyLevel (Easy/Medium/Hard/Expert/Grandmaster/Random) to solitaire_core::game_state alongside GameMode::Difficulty(DifficultyLevel). Five seed catalogs (40 seeds each) are pre-verified by the new gen_difficulty_seeds binary using tiered solver budgets (1K–200K moves). DifficultyPlugin resolves StartDifficultyRequestEvent → catalog seed → NewGameRequestEvent; Random uses a system-time seed and bypasses the winnable-only filter. The home overlay gets an expandable Difficulty section between Draw Mode and the mode grid; last-played tier persists in Settings. Difficulty wins pool into Classic stats. 5 unit tests in difficulty_plugin. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+24
-15
@@ -6,21 +6,28 @@ project follows [Semantic Versioning](https://semver.org/).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
**`395a322`** — double-tap auto-move (2026-05-08).
|
||||
**`0cb1587`** — Play-by-Seed dialog (2026-05-08).
|
||||
**`2062bd0`** — 75 new challenge seeds + gen_seeds binary (2026-05-08).
|
||||
**`45436d0`** — gate handle_fullscreen to non-Android (2026-05-08).
|
||||
**`2c822ba`** — JNI clipboard bridge for Android Stats share-link (2026-05-08).
|
||||
**`f281425`** — Android Keystore AES-GCM token storage via JNI (2026-05-08).
|
||||
See [0.21.9] for the committed detail once cut.
|
||||
## [0.22.0] — 2026-05-08
|
||||
|
||||
## [0.21.9] — pending cut
|
||||
|
||||
Closes the "Prev/Next selector chips spawn site" punch-list item from
|
||||
v0.19.0.
|
||||
Adds difficulty-tier game selection, Android JNI bridges for keystore and
|
||||
clipboard, Play-by-Seed dialog, and double-tap auto-move on touch screens.
|
||||
Also closes the Prev/Next replay-selector spawn-site item carried since v0.19.0.
|
||||
|
||||
### Added
|
||||
|
||||
- **Difficulty-tier game mode** (this release).
|
||||
`DifficultyLevel` enum (`Easy / Medium / Hard / Expert / Grandmaster /
|
||||
Random`) added to `solitaire_core::game_state` alongside a new
|
||||
`GameMode::Difficulty(DifficultyLevel)` variant. Five pre-verified seed
|
||||
catalogs (40 seeds each, 200 total) are generated by the new
|
||||
`gen_difficulty_seeds` binary in `solitaire_assetgen`; each catalog
|
||||
contains seeds proven winnable at progressively larger solver budgets
|
||||
(1 K → 200 K moves). `DifficultyPlugin` resolves `StartDifficultyRequestEvent`
|
||||
→ catalog seed → `NewGameRequestEvent`; the `Random` tier uses a
|
||||
system-time seed and intentionally bypasses the winnable-only filter.
|
||||
The home overlay gains an expandable `▶ Difficulty` section between the
|
||||
Draw Mode row and the mode-card grid; the last-played tier is persisted
|
||||
in `Settings::last_difficulty` and pre-expands/highlights on re-open.
|
||||
Difficulty wins pool into Classic stats (no separate buckets).
|
||||
- **Prev/Next replay selector in the Stats overlay** (`a449f60`).
|
||||
`ReplayPrevButton`, `ReplayNextButton`, `ReplaySelectorCaption`, and
|
||||
`ReplaySelectorDetail` nodes now spawn inside `spawn_stats_screen`
|
||||
@@ -116,11 +123,13 @@ confirmed end-to-end device run.
|
||||
|
||||
### Stats
|
||||
|
||||
- Tests: **1292 passing** / 0 failing (+10 from double-tap + Play-by-Seed tests)
|
||||
- Tests: **1300+ passing** / 0 failing
|
||||
- Clippy: clean
|
||||
- Crates touched: `solitaire_engine` (input_plugin, events, home_plugin,
|
||||
play_by_seed_plugin, lib), `solitaire_app` (lib.rs), `solitaire_data`
|
||||
(challenge.rs), `solitaire_assetgen` (gen_seeds binary, Cargo.toml)
|
||||
- Crates touched: `solitaire_core` (game_state), `solitaire_data`
|
||||
(settings, stats, difficulty_seeds, challenge), `solitaire_engine`
|
||||
(events, difficulty_plugin, home_plugin, hud_plugin, win_summary_plugin,
|
||||
input_plugin, play_by_seed_plugin, lib), `solitaire_app` (lib.rs),
|
||||
`solitaire_assetgen` (gen_difficulty_seeds + gen_seeds binaries)
|
||||
|
||||
## [0.21.8] — 2026-05-08
|
||||
|
||||
|
||||
Reference in New Issue
Block a user