feat(core): add klondike v0.2.0 dep and KlondikeAdapter (integration steps 1, 3, 4)
Build and Deploy / build-and-push (push) Failing after 1m0s
Build and Deploy / build-and-push (push) Failing after 1m0s
Step 1 — Cargo & registry: - Add .cargo/config.toml with Quaternions sparse registry (https://git.aleshym.co/api/packages/Quaternions/cargo/) - Add klondike = "0.2.0" to workspace deps (+ card_game v0.3.0, arrayvec v0.7.6 as transitives via the Quaternions registry) - Add klondike as a solitaire_core dep Step 3 — KlondikeConfig / MoveFromFoundationConfig: - KlondikeAdapter::new(draw_mode, take_from_foundation) builds a KlondikeConfig with the correct DrawStockConfig and MoveFromFoundationConfig (Allowed/Disallowed); exposes it via klondike_config() for future solver and pile-mapping steps Step 4 — Scoring via ScoringConfig: - GameState.adapter (serde(skip)) owns the authoritative KlondikeConfig with ScoringConfig::DEFAULT (WXP values) - score_for_move/flip/undo/recycle replace direct scoring.rs calls; scoring.rs retained for reference and future deletion - score_for_recycle implements the WXP free-recycle allowance rule that ScoringConfig::recycle cannot express (flat delta) - PartialEq/Eq for KlondikeAdapter compare draw_stock and move_from_foundation only (scoring is always DEFAULT) All 192 solitaire_core tests pass; clippy -D warnings clean. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,10 +3,8 @@ use crate::deck::{Deck, deal_klondike};
|
||||
use crate::error::MoveError;
|
||||
use crate::pile::{Pile, PileType};
|
||||
use crate::rules::{can_place_on_foundation, can_place_on_tableau, is_valid_tableau_sequence};
|
||||
use crate::scoring::{
|
||||
compute_time_bonus as scoring_time_bonus, score_flip, score_move, score_recycle,
|
||||
score_undo as scoring_undo,
|
||||
};
|
||||
use crate::klondike_adapter::KlondikeAdapter;
|
||||
use crate::scoring::compute_time_bonus as scoring_time_bonus;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
|
||||
@@ -166,6 +164,8 @@ pub struct GameState {
|
||||
#[serde(default = "schema_v1")]
|
||||
pub schema_version: u32,
|
||||
#[serde(skip)]
|
||||
pub adapter: KlondikeAdapter,
|
||||
#[serde(skip)]
|
||||
undo_stack: VecDeque<StateSnapshot>,
|
||||
}
|
||||
|
||||
@@ -208,6 +208,7 @@ impl GameState {
|
||||
recycle_count: 0,
|
||||
take_from_foundation: true,
|
||||
schema_version: GAME_STATE_SCHEMA_VERSION,
|
||||
adapter: KlondikeAdapter::new(draw_mode, true),
|
||||
undo_stack: VecDeque::new(),
|
||||
}
|
||||
}
|
||||
@@ -276,7 +277,7 @@ impl GameState {
|
||||
self.recycle_count = self.recycle_count.saturating_add(1);
|
||||
if self.mode != GameMode::Zen {
|
||||
let penalty =
|
||||
score_recycle(self.recycle_count, self.draw_mode == DrawMode::DrawThree);
|
||||
KlondikeAdapter::score_for_recycle(self.recycle_count, self.draw_mode == DrawMode::DrawThree);
|
||||
self.score = (self.score + penalty).max(0);
|
||||
}
|
||||
self.move_count = self.move_count.saturating_add(1);
|
||||
@@ -413,7 +414,7 @@ impl GameState {
|
||||
let score_delta = if self.mode == GameMode::Zen {
|
||||
0
|
||||
} else {
|
||||
score_move(&from, &to)
|
||||
self.adapter.score_for_move(&from, &to)
|
||||
};
|
||||
self.push_snapshot();
|
||||
|
||||
@@ -446,7 +447,7 @@ impl GameState {
|
||||
.append(&mut moved);
|
||||
|
||||
let flip_bonus = if flipped && self.mode != GameMode::Zen {
|
||||
score_flip()
|
||||
self.adapter.score_for_flip()
|
||||
} else {
|
||||
0
|
||||
};
|
||||
@@ -480,7 +481,7 @@ impl GameState {
|
||||
self.score = if self.mode == GameMode::Zen {
|
||||
0
|
||||
} else {
|
||||
(snapshot.score + scoring_undo()).max(0)
|
||||
(snapshot.score + KlondikeAdapter::score_for_undo()).max(0)
|
||||
};
|
||||
self.move_count = snapshot.move_count;
|
||||
self.is_won = false;
|
||||
@@ -726,6 +727,7 @@ impl GameState {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::card::{Card, Rank, Suit};
|
||||
use crate::klondike_adapter::KlondikeAdapter;
|
||||
|
||||
fn new_game() -> GameState {
|
||||
GameState::new(42, DrawMode::DrawOne)
|
||||
@@ -1126,7 +1128,7 @@ mod tests {
|
||||
let score_before = g.score;
|
||||
g.draw().unwrap();
|
||||
g.undo().unwrap();
|
||||
let expected = (score_before + scoring_undo()).max(0);
|
||||
let expected = (score_before + KlondikeAdapter::score_for_undo()).max(0);
|
||||
assert_eq!(g.score, expected);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user