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/card.rs | |
| parent | 5391187338b6f3dafe840ecc92fa91bd82f5c670 (diff) | |
Add card sorting utility
Diffstat (limited to 'webapp/src/card.rs')
| -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, +    }  }  | 
