refactor(core): derive draw_mode/is_won/move_count/is_auto_completable from session

Remove the draw_mode, move_count, is_won, and is_auto_completable fields
from GameState; they are now &self methods deriving from the underlying
card_game session (draw_mode from session config, move_count from history
length, is_won/is_auto_completable from check_win/check_auto_complete).

Tests previously fabricated these via direct field writes, which is no
longer possible. Add gated test-support overrides on TestPileState
(won/auto_completable/move_count) plus setters set_test_won,
set_test_auto_completable, set_test_move_count, and set_test_draw_mode
(re-deals the seed). All compiled out in production builds.

Fix the field->method ripple across solitaire_data, solitaire_wasm, and
solitaire_engine. Add a test-support dev-dependency to solitaire_data for
the won-game storage test.

cargo test --workspace and cargo clippy --workspace -- -D warnings pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
funman300
2026-06-10 09:24:03 -07:00
parent 1438fd6265
commit 056459619b
20 changed files with 187 additions and 120 deletions
+6 -6
View File
@@ -76,14 +76,14 @@ fn detect_auto_complete(
}
changed.clear();
if game.0.is_won {
if game.0.is_won() {
state.active = false;
return;
}
if game.0.is_auto_completable && !state.active {
if game.0.is_auto_completable() && !state.active {
state.active = true;
state.cooldown = AUTO_COMPLETE_INITIAL_DELAY;
} else if !game.0.is_auto_completable && state.active {
} else if !game.0.is_auto_completable() && state.active {
// `is_auto_completable` only becomes false after an explicit undo
// (which puts a card back on the tableau or re-fills the stock/waste)
// or a new-game reset — never as a transient gap during a normal
@@ -209,7 +209,7 @@ mod tests {
Tableau::Tableau1,
vec![solitaire_core::card::Card::new(Deck::Deck1, Suit::Clubs, Rank::Ace)],
);
g.is_auto_completable = true;
g.set_test_auto_completable(true);
let expected = (
KlondikePile::Tableau(Tableau::Tableau1),
KlondikePile::Foundation(Foundation::Foundation1),
@@ -228,7 +228,7 @@ mod tests {
fn detect_activates_when_auto_completable() {
let mut app = headless_app();
let mut g = GameState::new(42, DrawMode::DrawOne);
g.is_auto_completable = true;
g.set_test_auto_completable(true);
app.world_mut().resource_mut::<GameStateResource>().0 = g;
app.world_mut().write_message(StateChangedEvent);
app.update();
@@ -263,7 +263,7 @@ mod tests {
let mut app = headless_app();
// Inject a won game state — active should not be set.
let (mut gs, _) = seeded_state_with_auto_move();
gs.is_won = true;
gs.set_test_won(true);
app.world_mut().resource_mut::<GameStateResource>().0 = gs;
app.world_mut().write_message(StateChangedEvent);
app.update();