summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKjetil Orbekk <kj@orbekk.com>2022-09-05 14:34:55 -0400
committerKjetil Orbekk <kj@orbekk.com>2022-09-05 14:34:55 -0400
commit06aeab55c9ec91f8bfb8c3570297ee26f321bbf5 (patch)
tree14f0aa8d41fe4e530753daca37145abf9d69d182
parent5391187338b6f3dafe840ecc92fa91bd82f5c670 (diff)
Add card sorting utility
-rw-r--r--webapp/src/card.rs73
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,
+ }
}