From 06aeab55c9ec91f8bfb8c3570297ee26f321bbf5 Mon Sep 17 00:00:00 2001 From: Kjetil Orbekk Date: Mon, 5 Sep 2022 14:34:55 -0400 Subject: Add card sorting utility --- webapp/src/card.rs | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 3 deletions(-) (limited to 'webapp/src') diff --git a/webapp/src/card.rs b/webapp/src/card.rs index 248b9b5..825694f 100644 --- a/webapp/src/card.rs +++ b/webapp/src/card.rs @@ -1,11 +1,13 @@ +use anyhow::anyhow; use rand::prelude::SliceRandom; use rand::Rng; use std::fmt; +use strum::EnumCount; use strum::IntoEnumIterator; +use strum_macros::EnumCount; use strum_macros::EnumIter; -use anyhow::anyhow; -#[derive(PartialOrd, Ord, PartialEq, Eq, Clone, Copy, EnumIter)] +#[derive(PartialOrd, Ord, PartialEq, Eq, Clone, Copy, EnumIter, EnumCount)] pub enum Suit { Club, Diamond, @@ -159,11 +161,71 @@ fn make_deck() -> Vec { result } +#[derive(Default, PartialEq, Eq)] +pub enum RankOrder { + #[default] + Descending, + Ascending, +} + +pub fn sort_cards>(suits: Suits, ord: RankOrder, cards: &mut [Card]) { + let mut score: [u8; Suit::COUNT] = [0; Suit::COUNT]; + for (i, suit) in suits.enumerate() { + score[suit as usize] = i as u8; + } + cards.sort_by(|&Card(s1, r1), &Card(s2, r2)| { + let order = { + if s1 == s2 { + r1.cmp(&r2) + } else { + score[s2 as usize].cmp(&score[s1 as usize]) + } + }; + if ord == RankOrder::Descending { + order.reverse() + } else { + order + } + }); +} + #[cfg(test)] mod tests { use super::*; use log::info; + #[test] + fn sorting_cards() { + let card = |s: &str| s.parse::().unwrap(); + assert_eq!([card("♥2"), card("♥3"), card("♥4"),], { + let mut cards = [card("♥2"), card("♥4"), card("♥3")]; + sort_cards( + [Suit::Heart, Suit::Spade, Suit::Club, Suit::Diamond].into_iter(), + RankOrder::Ascending, + &mut cards, + ); + cards + }); + assert_eq!([card("♥A"), card("♥3"), card("♥2"),], { + let mut cards = [card("♥2"), card("♥A"), card("♥3")]; + sort_cards( + [Suit::Heart, Suit::Spade, Suit::Club, Suit::Diamond].into_iter(), + RankOrder::Descending, + &mut cards, + ); + cards + }); + assert_eq!([card("♠A"), card("♥A"), card("♣A"), card("♦A"),], { + let mut cards = [card("♣A"), card("♠A"), card("♥A"), card("♦A"),]; + sort_cards( + [Suit::Spade, Suit::Heart, Suit::Club, Suit::Diamond].into_iter(), + RankOrder::Descending, + &mut cards, + ); + cards + }); + } + #[test] fn string_conversion() { crate::tests::test_setup(); @@ -197,5 +259,10 @@ where let west = deck.by_ref().take(13).cloned().collect(); let south = deck.by_ref().take(13).cloned().collect(); let east = deck.by_ref().take(13).cloned().collect(); - Deal { north, west, south, east } + Deal { + north, + west, + south, + east, + } } -- cgit v1.2.3