fix(multi): resolve 14 bugs from second comprehensive review
Build and Deploy / build-and-push (push) Successful in 4m2s
Build and Deploy / build-and-push (push) Successful in 4m2s
Core (solitaire_core): - fix(scoring): apply -15 penalty for Foundation→Tableau moves when take_from_foundation is enabled; update test - fix(solver): is_won() validates full Ace→King suit sequence, not just card count — prevents hint system from emitting invalid paths Engine — animation / layout: - fix(animation): guard CardAnim advance against duration=0 to prevent NaN-poisoned Transform (analogous to CardAnimation's instant-snap path) - fix(card_plugin): align TABLEAU_FAN_FRAC (0.25→0.18) and TABLEAU_FACEDOWN_FAN_FRAC (0.20→0.14) with layout.rs so the initial layout and first dynamic update produce identical fan spacing - fix(layout): update tableau_fan_frac doc comment from 0.25→0.18 Engine — ECS / modal guards: - fix(auto_complete): drive_auto_complete now checks PausedResource so cooldown does not tick while paused (prevents instant-move on unpause) - fix(play_by_seed): handle_open_dialog checks global ModalScrim guard to prevent stacking over an existing modal - fix(win_summary): spawn_win_summary_after_delay checks global ModalScrim guard; collect_session_achievements uses .next() not .last() to avoid draining the new_games stream Engine — message registration: - fix(leaderboard): register InfoToastEvent in LeaderboardPlugin::build so opt-in/opt-out toasts work under MinimalPlugins - fix(replay_playback): register StateChangedEvent in ReplayPlaybackPlugin::build to prevent panic when used standalone Security: - fix(sync_setup): zero password SyncFieldBuffer immediately after spawning auth task — credential must not linger in ECS components Server: - fix(auth): replace MIME contains-chain with exact match for avatar upload; removes illusory starts_with guard and dead ALLOWED_IMAGE_TYPES Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -298,9 +298,16 @@ impl SolverState {
|
||||
}
|
||||
}
|
||||
|
||||
/// True when every foundation slot has 13 cards.
|
||||
/// True when every foundation slot holds a complete Ace-through-King sequence.
|
||||
fn is_won(&self) -> bool {
|
||||
self.foundation.iter().all(|f| f.len() == 13)
|
||||
self.foundation.iter().all(|pile| {
|
||||
pile.len() == 13
|
||||
&& pile[0].rank == crate::card::Rank::Ace
|
||||
&& pile.windows(2).all(|w| {
|
||||
w[0].suit == w[1].suit
|
||||
&& w[1].rank.value() == w[0].rank.value() + 1
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the foundation slot that already claims `suit`, or the
|
||||
|
||||
Reference in New Issue
Block a user