Untitled
unknown
rust
12 days ago
2.4 kB
10
Indexable
fn from(mut cards: [crate::Card; 5]) -> Self { let mut suits = [false; 4]; let mut ranks = [0; 15]; let mut set4 = None; let mut set3 = None; let mut set2 = [0; 2]; for card in cards { suits[card.suit as usize] = true; ranks[card.rank as usize] += 1; match ranks[card.rank as usize] { 0 => unreachable!(), 1 => {} 2 => { if set2[0] > 0 { debug_assert_eq!(set2[1], 0); set2[1] = card.rank; } else { set2[0] = card.rank; } } 3 => { debug_assert_eq!(set3, None); set3 = Some(card.rank); if set2[0] == card.rank { set2[0] = set2[1]; set2[1] = 0; } else { debug_assert_eq!(set2[1], card.rank); set2[1] = 0; } } 4 => { debug_assert_eq!(set4, None); set4 = Some(card.rank); } 5 => { eprintln!("5 of a kind?") } _ => unreachable!(), } } if let Some(rank) = set4 { PokerHand::FourOfAKind(rank) } else if let Some(rank) = set3 { if set2[0] > 0 { PokerHand::FullHouse(rank, set2[0]) } else { PokerHand::ThreeOfAKind(rank) } } else if set2[1] > 0 { cards.sort_unstable_by_key(|c| std::cmp::Reverse(*c)); PokerHand::TwoPair(set2) } else if set2[0] > 0 { PokerHand::Pair(set2[0]) } else { cards.sort_unstable_by_key(|c| std::cmp::Reverse(*c)); let is_flush = suits.into_iter().filter(|y| *y).count() == 1; let is_straight = cards.windows(2) .all(|p| p[0].rank == p[1].rank + 1 || p[0].rank == 14 && p[1].rank == 5); // Handle Ace being high or low. let straight_rank = if ranks[2] > 0 { 5 } else { cards[0].rank }; match (is_flush, is_straight) { (true, true) => PokerHand::StraightFlush(straight_rank), (true, false) => PokerHand::Flush(cards.map(|c| c.rank)), (false, true) => PokerHand::Straight(straight_rank), (false, false) => PokerHand::High(cards.map(|c| c.rank)), } } }
Editor is loading...
Leave a Comment