refactor: remove card.rs / card_to_id; use card_game::Card directly (#83)
card_to_id was a frankenstein 0..=51 id shim. Replace it with card_game::Card: - feedback_anim deal jitter now seeds off a hash of the Card itself - radial_menu RightClickRadialState.cards: Vec<u32> -> Vec<Card> - wasm CardSnapshot.id: u32 -> Card (serialises transparently as a plain JS number, the same opaque key the renderer already used; new test asserts the JSON id field is a number) - wasm DebugInvariantReport deck-completeness check reworked from a [bool;52] index into a HashSet<Card> + Card::new reference deck; the out-of-range check is dropped since a Card is always valid Delete card.rs entirely: the Card/Deck/Rank/Suit re-exports move to the crate root and the 69 `solitaire_core::card::` import paths flatten to `solitaire_core::`. The JS card.id is purely an opaque identity key (Map key / dataset.cardId, no arithmetic, card faces render from rank+suit), so the value change is safe. cargo test --workspace and clippy --workspace --all-targets -- -D warnings green. Closes #83 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -824,7 +824,7 @@ fn handle_draw(
|
||||
// so we can fire flip events after they land face-up in the waste.
|
||||
// Only relevant when stock is non-empty; a recycle moves waste back to
|
||||
// stock face-down, so no flip events are needed in that case.
|
||||
let drawn_cards: Vec<solitaire_core::card::Card> = {
|
||||
let drawn_cards: Vec<solitaire_core::Card> = {
|
||||
let stock = game.0.stock_cards();
|
||||
if stock.is_empty() {
|
||||
Vec::new()
|
||||
@@ -1013,7 +1013,7 @@ pub fn record_replay_on_win(
|
||||
}
|
||||
}
|
||||
|
||||
fn pile_cards(game: &GameState, pile: &KlondikePile) -> Vec<(solitaire_core::card::Card, bool)> {
|
||||
fn pile_cards(game: &GameState, pile: &KlondikePile) -> Vec<(solitaire_core::Card, bool)> {
|
||||
match pile {
|
||||
KlondikePile::Stock => game.waste_cards(),
|
||||
_ => game.pile(*pile),
|
||||
@@ -1391,7 +1391,7 @@ mod tests {
|
||||
#[test]
|
||||
fn new_game_request_reseeds() {
|
||||
let mut app = test_app(1);
|
||||
let before: Vec<solitaire_core::card::Card> = app
|
||||
let before: Vec<solitaire_core::Card> = app
|
||||
.world()
|
||||
.resource::<GameStateResource>()
|
||||
.0
|
||||
@@ -1407,7 +1407,7 @@ mod tests {
|
||||
});
|
||||
app.update();
|
||||
|
||||
let after: Vec<solitaire_core::card::Card> = app
|
||||
let after: Vec<solitaire_core::Card> = app
|
||||
.world()
|
||||
.resource::<GameStateResource>()
|
||||
.0
|
||||
@@ -1649,7 +1649,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn moving_cards_off_face_up_card_does_not_fire_card_flipped_event() {
|
||||
use solitaire_core::card::{Card, Deck, Rank, Suit};
|
||||
use solitaire_core::{Card, Deck, Rank, Suit};
|
||||
let mut app = test_app(1);
|
||||
// Build a tableau with two face-up cards.
|
||||
{
|
||||
@@ -1706,7 +1706,7 @@ mod tests {
|
||||
// Klondike (unlimited recycles), even if the drawn card cannot be
|
||||
// immediately placed. The game is only stuck when both stock AND waste
|
||||
// are exhausted and no visible card can be moved.
|
||||
use solitaire_core::card::{Card, Deck, Rank, Suit};
|
||||
use solitaire_core::{Card, Deck, Rank, Suit};
|
||||
let mut game = GameState::new(1, DrawStockConfig::DrawOne);
|
||||
for foundation in [
|
||||
Foundation::Foundation1,
|
||||
@@ -1742,7 +1742,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn has_legal_moves_returns_true_when_ace_can_go_to_foundation() {
|
||||
use solitaire_core::card::{Card, Deck, Rank, Suit};
|
||||
use solitaire_core::{Card, Deck, Rank, Suit};
|
||||
let mut game = GameState::new(1, DrawStockConfig::DrawOne);
|
||||
|
||||
// Empty stock and waste so draw is NOT available.
|
||||
@@ -1786,7 +1786,7 @@ mod tests {
|
||||
// If the only legal move involves a face-up card that is NOT the top
|
||||
// card of its column the previous code would return false (softlock)
|
||||
// even though the player can still move that run.
|
||||
use solitaire_core::card::{Card, Deck, Rank, Suit};
|
||||
use solitaire_core::{Card, Deck, Rank, Suit};
|
||||
let mut game = GameState::new(1, DrawStockConfig::DrawOne);
|
||||
|
||||
game.set_test_stock_cards(Vec::new());
|
||||
@@ -1976,7 +1976,7 @@ mod tests {
|
||||
/// to have been a King.
|
||||
#[test]
|
||||
fn foundation_completed_event_does_not_fire_for_non_foundation_moves() {
|
||||
use solitaire_core::card::{Card, Deck, Rank, Suit};
|
||||
use solitaire_core::{Card, Deck, Rank, Suit};
|
||||
|
||||
let mut app = test_app(1);
|
||||
// Reset the world: clear stock + waste so a draw isn't possible,
|
||||
|
||||
Reference in New Issue
Block a user