modes:pair: refactor using new functions

- Better modelling for Pair::new using Card::rank optional.
- Ordering uses ~Ordering::then_with~ which maps to our previous
  pattern (cleaner)
This commit is contained in:
2026-04-09 19:18:24 +01:00
committed by oreodave
parent e85f8b69d0
commit d993f72958

View File

@@ -1,7 +1,4 @@
use crate::{ use crate::{card::Card, helper::ordered};
card::{Card, PlayingCard},
helper::ordered,
};
#[derive(Eq, Debug, Copy, Clone)] #[derive(Eq, Debug, Copy, Clone)]
pub struct Pair(Card, Card); pub struct Pair(Card, Card);
@@ -19,23 +16,11 @@ impl Pair {
// be that joker. // be that joker.
let [c1, c2] = ordered([c1, c2]); let [c1, c2] = ordered([c1, c2]);
match (c1, c2) { match [c1, c2].map(|c| c.rank()) {
// Can't be a pair if you got two jokers homie. // A Joker and a PlayingCard
(Card::Joker(_), Card::Joker(_)) => None, [None, Some(_)] => Some(Pair(c1, c2)),
// Two PlayingCards of the same rank
// NOTE: c2 cannot be a joker because of prev condition. If you've [Some(r1), Some(r2)] if r1 == r2 => Some(Pair(c1, c2)),
// got a joker you're automatically a pair.
(Card::Joker(_), _) => Some(Pair(c1, c2)),
// NOTE: c1 and c2 cannot be jokers. In which case, check their
// ranks are equivalent.
(
Card::PlayingCard(PlayingCard { rank: r1, .. }),
Card::PlayingCard(PlayingCard { rank: r2, .. }),
) => (r1 == r2).then_some(Pair(c1, c2)),
// Not necessary since the previous patterns technically cover all
// cases. But I love the compiler too much to tell them... 💔
_ => None, _ => None,
} }
} }
@@ -88,12 +73,7 @@ impl Ord for Pair {
equivalent, then compare the last card to get a full ordering. equivalent, then compare the last card to get a full ordering.
Otherwise, use the high card comparison. Otherwise, use the high card comparison.
*/ */
let high_card_comp = self.1.cmp(&other.1); self.1.cmp(&other.1).then_with(|| self.0.cmp(&other.0))
if high_card_comp == Ordering::Equal {
self.0.cmp(&other.0)
} else {
high_card_comp
}
} }
} }
@@ -121,7 +101,10 @@ impl Hash for Pair {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::{card::Rank, modes::tests::test_footstool}; use crate::{
card::{PlayingCard, Rank},
modes::tests::test_footstool,
};
#[test] #[test]
fn new() { fn new() {
@@ -175,11 +158,7 @@ mod tests {
assert!(pair.is_improper(), "Expected {pair} to be improper"); assert!(pair.is_improper(), "Expected {pair} to be improper");
// TEST: Improper pairs have a Joker in Pair::0. // TEST: Improper pairs have a Joker in Pair::0.
assert!( assert!(pair.0.is_joker(), "Expected {} to be a joker", pair.0);
matches!(pair.0, Card::Joker(_)),
"Expected {} to be a joker",
pair.0
);
// TEST: Improper pairs have a playing card in Pair::1. // TEST: Improper pairs have a playing card in Pair::1.
assert!( assert!(