diff options
author | Kjetil Orbekk <kj@orbekk.com> | 2022-09-05 14:34:55 -0400 |
---|---|---|
committer | Kjetil Orbekk <kj@orbekk.com> | 2022-09-05 14:34:55 -0400 |
commit | 06aeab55c9ec91f8bfb8c3570297ee26f321bbf5 (patch) | |
tree | 14f0aa8d41fe4e530753daca37145abf9d69d182 /webapp/src | |
parent | 5391187338b6f3dafe840ecc92fa91bd82f5c670 (diff) |
Add card sorting utility
Diffstat (limited to 'webapp/src')
-rw-r--r-- | webapp/src/card.rs | 73 |
1 files changed, 70 insertions, 3 deletions
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,12 +161,72 @@ fn make_deck() -> Vec<Card> { result } +#[derive(Default, PartialEq, Eq)] +pub enum RankOrder { + #[default] + Descending, + Ascending, +} + +pub fn sort_cards<Suits: Iterator<Item = Suit>>(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::<Card>().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(); info!("deck: {:?}", make_deck()); @@ -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, + } } |