feat(core): card/pile conversion utils and GameMode-aware scoring (steps 2-prep, 5)
Build and Deploy / build-and-push (push) Failing after 55s
Build and Deploy / build-and-push (push) Failing after 55s
Step 2 prep — card_game dep + type-conversion utilities: - Add card_game = "0.3.0" (registry Quaternions) to workspace + core - suit_to_kl / suit_from_kl, rank_to_kl / rank_from_kl - card_to_kl (drops id, Deck1), card_from_kl (reconstructs stable id from Clubs-first suit×13+rank ordering matching deck.rs) - Ready to wire into KlondikeState pile projection once upstream adds KlondikeState::from_piles() Step 5 — GameMode-aware scoring in the adapter: - score_for_move_with_mode, score_for_flip_with_mode (return 0 in Zen) - apply_undo_score (static, handles Zen + −15 penalty + clamp) - score_for_recycle_with_mode (return 0 in Zen) - game_state.rs: all inline GameMode::Zen checks replaced with adapter calls; adapter is now the single source of truth for "what score does this action give in this mode" 192 tests pass; clippy -D warnings clean. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -275,11 +275,12 @@ impl GameState {
|
||||
stock.cards.push(card);
|
||||
}
|
||||
self.recycle_count = self.recycle_count.saturating_add(1);
|
||||
if self.mode != GameMode::Zen {
|
||||
let penalty =
|
||||
KlondikeAdapter::score_for_recycle(self.recycle_count, self.draw_mode == DrawMode::DrawThree);
|
||||
self.score = (self.score + penalty).max(0);
|
||||
}
|
||||
let penalty = KlondikeAdapter::score_for_recycle_with_mode(
|
||||
self.recycle_count,
|
||||
self.draw_mode == DrawMode::DrawThree,
|
||||
self.mode,
|
||||
);
|
||||
self.score = (self.score + penalty).max(0);
|
||||
self.move_count = self.move_count.saturating_add(1);
|
||||
return Ok(());
|
||||
}
|
||||
@@ -411,11 +412,7 @@ impl GameState {
|
||||
start
|
||||
};
|
||||
|
||||
let score_delta = if self.mode == GameMode::Zen {
|
||||
0
|
||||
} else {
|
||||
self.adapter.score_for_move(&from, &to)
|
||||
};
|
||||
let score_delta = self.adapter.score_for_move_with_mode(&from, &to, self.mode);
|
||||
self.push_snapshot();
|
||||
|
||||
// Execute move
|
||||
@@ -446,8 +443,8 @@ impl GameState {
|
||||
.cards
|
||||
.append(&mut moved);
|
||||
|
||||
let flip_bonus = if flipped && self.mode != GameMode::Zen {
|
||||
self.adapter.score_for_flip()
|
||||
let flip_bonus = if flipped {
|
||||
self.adapter.score_for_flip_with_mode(self.mode)
|
||||
} else {
|
||||
0
|
||||
};
|
||||
@@ -478,11 +475,7 @@ impl GameState {
|
||||
.pop_back()
|
||||
.ok_or(MoveError::UndoStackEmpty)?;
|
||||
self.piles = snapshot.piles;
|
||||
self.score = if self.mode == GameMode::Zen {
|
||||
0
|
||||
} else {
|
||||
(snapshot.score + KlondikeAdapter::score_for_undo()).max(0)
|
||||
};
|
||||
self.score = KlondikeAdapter::apply_undo_score(snapshot.score, self.mode);
|
||||
self.move_count = snapshot.move_count;
|
||||
self.is_won = false;
|
||||
self.is_auto_completable = false;
|
||||
|
||||
Reference in New Issue
Block a user