Sort the player's hand by rank then suit
This commit is contained in:
@@ -551,6 +551,21 @@ pub fn card_asset(code: &str) -> String {
|
|||||||
|
|
||||||
pub const CARD_BACK: &str = "/assets/cards/back.svg";
|
pub const CARD_BACK: &str = "/assets/cards/back.svg";
|
||||||
|
|
||||||
|
/// Display order key for a hand: rank ascending (01..10, i.e. 1..7 then
|
||||||
|
/// Fante, Cavallo, Re), then suit (denari, coppe, spade, bastoni).
|
||||||
|
/// Malformed codes sort last.
|
||||||
|
pub fn hand_sort_key(code: &str) -> (u8, u8) {
|
||||||
|
let rank = code.get(..2).and_then(|r| r.parse().ok()).unwrap_or(u8::MAX);
|
||||||
|
let suit = match code.get(2..3) {
|
||||||
|
Some("D") => 0,
|
||||||
|
Some("C") => 1,
|
||||||
|
Some("S") => 2,
|
||||||
|
Some("B") => 3,
|
||||||
|
_ => u8::MAX,
|
||||||
|
};
|
||||||
|
(rank, suit)
|
||||||
|
}
|
||||||
|
|
||||||
/// Human-friendly rank+suit label, e.g. `07D` -> "7 of denari".
|
/// Human-friendly rank+suit label, e.g. `07D` -> "7 of denari".
|
||||||
pub fn card_label(code: &str) -> String {
|
pub fn card_label(code: &str) -> String {
|
||||||
if code.len() != 3 {
|
if code.len() != 3 {
|
||||||
@@ -600,6 +615,38 @@ mod tests {
|
|||||||
assert_eq!("7 di denari", card_label("07D"));
|
assert_eq!("7 di denari", card_label("07D"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn hand_sort_orders_ranks_ascending() {
|
||||||
|
let mut hand = vec![
|
||||||
|
"10B".to_string(),
|
||||||
|
"01S".to_string(),
|
||||||
|
"07D".to_string(),
|
||||||
|
"08C".to_string(),
|
||||||
|
];
|
||||||
|
hand.sort_by_key(|c| hand_sort_key(c));
|
||||||
|
assert_eq!(vec!["01S", "07D", "08C", "10B"], hand);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn hand_sort_breaks_ties_by_suit() {
|
||||||
|
let mut hand = vec![
|
||||||
|
"02B".to_string(),
|
||||||
|
"02S".to_string(),
|
||||||
|
"02C".to_string(),
|
||||||
|
"02D".to_string(),
|
||||||
|
"01S".to_string(),
|
||||||
|
];
|
||||||
|
hand.sort_by_key(|c| hand_sort_key(c));
|
||||||
|
assert_eq!(vec!["01S", "02D", "02C", "02S", "02B"], hand);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn hand_sort_puts_malformed_codes_last() {
|
||||||
|
let mut hand = vec!["07D".to_string(), "xx".to_string(), "AB1".to_string()];
|
||||||
|
hand.sort_by_key(|c| hand_sort_key(c));
|
||||||
|
assert_eq!(vec!["07D", "xx", "AB1"], hand);
|
||||||
|
}
|
||||||
|
|
||||||
fn scopone_match() -> MatchSummary {
|
fn scopone_match() -> MatchSummary {
|
||||||
serde_json::from_value(json!({
|
serde_json::from_value(json!({
|
||||||
"id": "m1",
|
"id": "m1",
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use crate::api;
|
|||||||
use crate::components::card::{card_back, card_img};
|
use crate::components::card::{card_back, card_img};
|
||||||
use crate::components::summary::{hand_summary_modal, summary_rows};
|
use crate::components::summary::{hand_summary_modal, summary_rows};
|
||||||
use crate::components::toast::toast;
|
use crate::components::toast::toast;
|
||||||
use crate::model::{card_label, GameView, MoveView, PlayerView, Scores, ServerMessage};
|
use crate::model::{card_label, hand_sort_key, GameView, MoveView, PlayerView, Scores, ServerMessage};
|
||||||
use crate::ws::{self, GameSocket};
|
use crate::ws::{self, GameSocket};
|
||||||
|
|
||||||
fn send_play(socket: Signal<Option<GameSocket>>, card: String, capture: Option<Vec<String>>) {
|
fn send_play(socket: Signal<Option<GameSocket>>, card: String, capture: Option<Vec<String>>) {
|
||||||
@@ -593,7 +593,8 @@ fn table_view(
|
|||||||
let viewer = player_for_seat(&game, viewer_seat);
|
let viewer = player_for_seat(&game, viewer_seat);
|
||||||
let my_captured = viewer.as_ref().map(|p| p.captured_count).unwrap_or(0);
|
let my_captured = viewer.as_ref().map(|p| p.captured_count).unwrap_or(0);
|
||||||
let my_scope = viewer.as_ref().map(|p| p.scope).unwrap_or(0);
|
let my_scope = viewer.as_ref().map(|p| p.scope).unwrap_or(0);
|
||||||
let hand = viewer.and_then(|p| p.hand).unwrap_or_default();
|
let mut hand = viewer.and_then(|p| p.hand).unwrap_or_default();
|
||||||
|
hand.sort_by_key(|c| hand_sort_key(c));
|
||||||
let current_selection = selected.get_clone();
|
let current_selection = selected.get_clone();
|
||||||
let hand_cards = hand
|
let hand_cards = hand
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|||||||
Reference in New Issue
Block a user