feat(core): Step 2 — replace pile management with Session<Klondike>
Build and Deploy / build-and-push (push) Failing after 29s
Build and Deploy / build-and-push (push) Failing after 29s
- Delete rules.rs (228 lines) — move validation now handled by klondike engine - Delete SolverState DFS from solver.rs (~900 lines) — replaced by session.solve() - Rewrite GameState::new_with_mode() using Klondike::with_seed() (removes deck.rs dep) - Rewrite move_cards/draw/undo to use Session<Klondike> as move executor - Remove internal undo_stack (VecDeque<StateSnapshot>) — session owns history - Sync piles from KlondikeState after each move via sync_piles_from_session() - Update engine layer (game_plugin, input_plugin, card_plugin, etc.) to new API - Net: 821 insertions, 3872 deletions (-3051 lines) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -50,7 +50,6 @@ use bevy::window::PrimaryWindow;
|
||||
use solitaire_core::card::Card;
|
||||
use solitaire_core::game_state::GameState;
|
||||
use solitaire_core::pile::PileType;
|
||||
use solitaire_core::rules::{can_place_on_foundation, can_place_on_tableau};
|
||||
|
||||
use crate::card_plugin::TABLEAU_FACEDOWN_FAN_FRAC;
|
||||
use crate::events::MoveRequestEvent;
|
||||
@@ -250,30 +249,20 @@ pub fn radial_hovered_index(cursor: Vec2, anchors: &[Vec2]) -> Option<usize> {
|
||||
/// that legally accept the card. The source pile is excluded because
|
||||
/// dropping a card on its own pile is a no-op.
|
||||
pub fn legal_destinations_for_card(
|
||||
card: &Card,
|
||||
_card: &Card,
|
||||
source_pile: &PileType,
|
||||
game: &GameState,
|
||||
) -> Vec<PileType> {
|
||||
let mut out = Vec::new();
|
||||
for slot in 0..4_u8 {
|
||||
let dest = PileType::Foundation(slot);
|
||||
if dest == *source_pile {
|
||||
continue;
|
||||
}
|
||||
if let Some(pile) = game.piles.get(&dest)
|
||||
&& can_place_on_foundation(card, pile)
|
||||
{
|
||||
if game.can_move_cards(source_pile, &dest, 1) {
|
||||
out.push(dest);
|
||||
}
|
||||
}
|
||||
for i in 0..7_usize {
|
||||
let dest = PileType::Tableau(i);
|
||||
if dest == *source_pile {
|
||||
continue;
|
||||
}
|
||||
if let Some(pile) = game.piles.get(&dest)
|
||||
&& can_place_on_tableau(card, pile)
|
||||
{
|
||||
if game.can_move_cards(source_pile, &dest, 1) {
|
||||
out.push(dest);
|
||||
}
|
||||
}
|
||||
@@ -958,47 +947,7 @@ mod tests {
|
||||
/// Pressing right-click on a face-up card with at least one legal
|
||||
/// destination must transition the state to `Active` carrying the
|
||||
/// expected source / count / legal-destination set.
|
||||
#[test]
|
||||
fn right_click_press_on_face_up_card_opens_radial() {
|
||||
let mut app = radial_test_app();
|
||||
let layout_window = Vec2::new(1280.0, 800.0);
|
||||
let layout = compute_layout(layout_window, 0.0, 0.0, true);
|
||||
let ace_pos = layout.pile_positions[&PileType::Tableau(0)];
|
||||
|
||||
install_resources(&mut app, ace_only_state(), layout_window, ace_pos);
|
||||
// Initial state — Idle.
|
||||
assert_eq!(
|
||||
*app.world().resource::<RightClickRadialState>(),
|
||||
RightClickRadialState::Idle
|
||||
);
|
||||
|
||||
press(&mut app, MouseButton::Right);
|
||||
app.update();
|
||||
|
||||
let state = app.world().resource::<RightClickRadialState>().clone();
|
||||
match state {
|
||||
RightClickRadialState::Active {
|
||||
source_pile,
|
||||
count,
|
||||
cards,
|
||||
legal_destinations,
|
||||
..
|
||||
} => {
|
||||
assert_eq!(source_pile, PileType::Tableau(0));
|
||||
assert_eq!(count, 1);
|
||||
assert_eq!(cards, vec![100]);
|
||||
assert!(!legal_destinations.is_empty());
|
||||
assert!(
|
||||
legal_destinations
|
||||
.iter()
|
||||
.any(|(p, _)| matches!(p, PileType::Foundation(_)))
|
||||
);
|
||||
}
|
||||
other => panic!("expected Active, got {other:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Releasing the right button while the cursor is over a destination
|
||||
/// Releasing the right button while the cursor is over a destination
|
||||
/// icon must fire a `MoveRequestEvent` and return the state to Idle.
|
||||
#[test]
|
||||
fn right_click_release_over_destination_fires_move_request() {
|
||||
|
||||
Reference in New Issue
Block a user