refactor: replace local DrawMode with upstream klondike::DrawStockConfig (#82)

DrawMode was a 1:1 mirror of klondike::DrawStockConfig (DrawOne/DrawThree).
Delete it and use the upstream type everywhere; re-export DrawStockConfig from
solitaire_core. config_for assigns draw_stock directly and draw_mode() returns
session.config().inner.draw_stock.

Serde is unchanged — DrawStockConfig serialises to the same "DrawOne"/"DrawThree"
named variants, so persisted game_state.json / replay JSON stay byte-compatible
(no migration). Field/method/variable names containing draw_mode are unchanged.

35 files, mechanical type swap across all crates. Implemented via a multi-agent
workflow (core → per-crate consumers → verify). cargo test --workspace and
clippy --workspace --all-targets -- -D warnings green.

Closes #82

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
funman300
2026-06-11 16:01:11 -07:00
parent d045781119
commit 5c992cbdca
35 changed files with 257 additions and 274 deletions
+6 -6
View File
@@ -36,7 +36,7 @@ use bevy::prelude::*;
use bevy::window::{CursorIcon, PrimaryWindow, SystemCursorIcon};
use solitaire_core::card::Card;
use solitaire_core::{Foundation, KlondikePile, Tableau};
use solitaire_core::{DrawMode, game_state::GameState};
use solitaire_core::{DrawStockConfig, game_state::GameState};
use crate::card_plugin::RightClickHighlight;
use crate::layout::{Layout, LayoutResource};
@@ -437,7 +437,7 @@ fn tableau_or_stack_pos(
base.x,
base.y - layout.card_size.y * layout.tableau_fan_frac * (index as f32),
)
} else if matches!(pile, KlondikePile::Stock) && game.draw_mode() == DrawMode::DrawThree {
} else if matches!(pile, KlondikePile::Stock) && game.draw_mode() == DrawStockConfig::DrawThree {
let pile_len = game.waste_cards().len();
let visible_start = pile_len.saturating_sub(3);
let slot = index.saturating_sub(visible_start) as f32;
@@ -563,9 +563,9 @@ mod tests {
#[test]
fn cursor_over_draggable_returns_false_for_empty_game() {
use crate::layout::compute_layout;
use solitaire_core::{DrawMode, game_state::GameState};
use solitaire_core::{DrawStockConfig, game_state::GameState};
let game = GameState::new(42, DrawMode::DrawOne);
let game = GameState::new(42, DrawStockConfig::DrawOne);
let layout = compute_layout(Vec2::new(1280.0, 800.0), 0.0, 0.0, true);
// A cursor far off-screen should never hit anything.
assert!(!cursor_over_draggable(
@@ -581,7 +581,7 @@ mod tests {
use crate::layout::compute_layout;
use solitaire_core::card::{Card, Deck, Rank, Suit};
use solitaire_core::{DrawMode, game_state::{GameMode, GameState}};
use solitaire_core::{DrawStockConfig, game_state::{GameMode, GameState}};
/// Builds an `App` with `MinimalPlugins` and the overlay system
/// registered, plus the resources the system needs. Callers
@@ -629,7 +629,7 @@ mod tests {
// 5 of Spades (black) onto Tableau(2)'s 6 of Clubs (also black)
// — same colour family, illegal. Tableau(2) must NOT be
// highlighted.
let mut game = GameState::new_with_mode(7, DrawMode::DrawOne, GameMode::Classic);
let mut game = GameState::new_with_mode(7, DrawStockConfig::DrawOne, GameMode::Classic);
set_tableau_top(
&mut game,
2,