refactor: migrate PileType → KlondikePile across core/wasm/engine
Build and Deploy / build-and-push (push) Failing after 1m24s

- 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>
This commit is contained in:
funman300
2026-06-01 13:13:35 -07:00
parent ca612f51f1
commit 9260ca7994
36 changed files with 7429 additions and 7064 deletions
+11 -10
View File
@@ -28,7 +28,7 @@
use bevy::ecs::message::MessageReader;
use bevy::prelude::*;
use solitaire_core::pile::PileType;
use klondike::KlondikePile;
use crate::card_plugin::CardEntity;
use crate::events::StateChangedEvent;
@@ -50,7 +50,7 @@ use crate::ui_theme::ACCENT_PRIMARY;
#[derive(Resource, Debug, Default)]
pub struct TouchSelectionState {
/// Currently selected source pile and the card ids to move (bottom-to-top).
pub selected: Option<(PileType, Vec<u32>)>,
pub selected: Option<(KlondikePile, Vec<u32>)>,
}
impl TouchSelectionState {
@@ -60,12 +60,12 @@ impl TouchSelectionState {
}
/// Takes the current selection, leaving `selected` as `None`.
pub fn take(&mut self) -> Option<(PileType, Vec<u32>)> {
pub fn take(&mut self) -> Option<(KlondikePile, Vec<u32>)> {
self.selected.take()
}
/// Sets the current selection.
pub fn set(&mut self, pile: PileType, cards: Vec<u32>) {
pub fn set(&mut self, pile: KlondikePile, cards: Vec<u32>) {
self.selected = Some((pile, cards));
}
@@ -186,6 +186,7 @@ fn spawn_touch_highlight(
#[cfg(test)]
mod tests {
use super::*;
use klondike::Tableau;
#[test]
fn selection_state_default_is_idle() {
@@ -197,12 +198,12 @@ mod tests {
#[test]
fn set_and_take_roundtrip() {
let mut state = TouchSelectionState::default();
state.set(PileType::Tableau(0), vec![1, 2, 3]);
state.set(KlondikePile::Tableau(Tableau::Tableau1), vec![1, 2, 3]);
assert!(state.has_selection());
let taken = state.take();
assert!(taken.is_some());
let (pile, cards) = taken.unwrap();
assert_eq!(pile, PileType::Tableau(0));
assert_eq!(pile, KlondikePile::Tableau(Tableau::Tableau1));
assert_eq!(cards, vec![1, 2, 3]);
assert!(!state.has_selection());
}
@@ -210,7 +211,7 @@ mod tests {
#[test]
fn clear_removes_selection() {
let mut state = TouchSelectionState::default();
state.set(PileType::Waste, vec![42]);
state.set(KlondikePile::Stock, vec![42]);
state.clear();
assert!(!state.has_selection());
}
@@ -225,10 +226,10 @@ mod tests {
#[test]
fn set_overwrites_previous_selection() {
let mut state = TouchSelectionState::default();
state.set(PileType::Tableau(0), vec![1]);
state.set(PileType::Tableau(3), vec![7, 8]);
state.set(KlondikePile::Tableau(Tableau::Tableau1), vec![1]);
state.set(KlondikePile::Tableau(Tableau::Tableau4), vec![7, 8]);
let (pile, cards) = state.take().unwrap();
assert_eq!(pile, PileType::Tableau(3));
assert_eq!(pile, KlondikePile::Tableau(Tableau::Tableau4));
assert_eq!(cards, vec![7, 8]);
}
}