classifier: refactor for new PlayingCard type
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
use crate::card::Card;
|
use crate::card::{Card, PlayingCard, Rank, Suit};
|
||||||
use crate::hand::{Hand, PokerType};
|
use crate::hand::{Hand, PokerType};
|
||||||
|
|
||||||
impl Hand {
|
impl Hand {
|
||||||
@@ -63,44 +63,57 @@ fn is_triple(num_jokers: usize, c1: Card, c2: Card, c3: Card) -> bool {
|
|||||||
fn try_poker_hand(num_jokers: usize, cards: &[Card]) -> Option<PokerType> {
|
fn try_poker_hand(num_jokers: usize, cards: &[Card]) -> Option<PokerType> {
|
||||||
// FIXME: So ugly. Any way we can make this better?
|
// FIXME: So ugly. Any way we can make this better?
|
||||||
|
|
||||||
let playing_cards = &cards[num_jokers..];
|
// playing_cards is a mapping of all the valid playing cards in the input
|
||||||
let num_jokers = num_jokers as i32;
|
// cardset.
|
||||||
|
let mut playing_cards =
|
||||||
|
[PlayingCard::new(0, Rank::Three, Suit::Diamond); 5];
|
||||||
|
let playing_cards = {
|
||||||
|
let cards_slice = &cards[num_jokers..];
|
||||||
|
for i in 0..cards_slice.len() {
|
||||||
|
playing_cards[i] = match cards_slice[i] {
|
||||||
|
Card::Joker(_) => {
|
||||||
|
unreachable!("should be a valid playing card")
|
||||||
|
}
|
||||||
|
Card::PlayingCard(c) => c,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
&playing_cards[..cards_slice.len()]
|
||||||
|
};
|
||||||
|
|
||||||
|
let num_jokers = num_jokers as i32;
|
||||||
let mut counter_ranks = [0; 13];
|
let mut counter_ranks = [0; 13];
|
||||||
let mut counter_suits = [0; 13];
|
let mut counter_suits = [0; 4];
|
||||||
for card in playing_cards {
|
for card in playing_cards {
|
||||||
let rank = card.rank().unwrap() as usize;
|
let rank = card.rank as usize;
|
||||||
let suit = card.suit().unwrap() as usize;
|
let suit = card.suit as usize;
|
||||||
counter_ranks[rank] += 1;
|
counter_ranks[rank] += 1;
|
||||||
counter_suits[suit] += 1;
|
counter_suits[suit] += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
let highest_rank_freq = *counter_ranks.iter().max().unwrap();
|
let (highest_rank_freq, num_pairs) = {
|
||||||
let num_pairs = counter_ranks.iter().filter(|&count| *count == 2).count();
|
let mut highest_rank_freq = 0;
|
||||||
let is_straight = is_straight(num_jokers, playing_cards);
|
let mut num_pairs = 0;
|
||||||
|
for i in 0..counter_ranks.len() {
|
||||||
|
let rank_freq = counter_ranks[i];
|
||||||
|
highest_rank_freq = std::cmp::max(rank_freq, highest_rank_freq);
|
||||||
|
if rank_freq == 2 {
|
||||||
|
num_pairs += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(highest_rank_freq, num_pairs)
|
||||||
|
};
|
||||||
let is_flush = counter_suits.contains(&playing_cards.len());
|
let is_flush = counter_suits.contains(&playing_cards.len());
|
||||||
|
let is_straight = is_straight(num_jokers, playing_cards);
|
||||||
|
|
||||||
if is_straight && is_flush || num_jokers == 4 {
|
match (num_pairs, num_jokers, highest_rank_freq) {
|
||||||
Some(PokerType::StraightFlush)
|
_ if is_straight && is_flush => Some(PokerType::StraightFlush),
|
||||||
} else if num_jokers + highest_rank_freq == 5 {
|
(_, x, y) if x + y == 5 => Some(PokerType::FiveKind),
|
||||||
Some(PokerType::FiveKind)
|
(_, x, y) if x + y == 4 => Some(PokerType::FourKind),
|
||||||
} else if num_jokers + highest_rank_freq == 4 {
|
(1, _, 3) | (2, 1, _) => Some(PokerType::FullHouse),
|
||||||
Some(PokerType::FourKind)
|
_ if is_straight => Some(PokerType::Straight),
|
||||||
} else if (num_pairs == 1 && highest_rank_freq == 3)
|
_ if is_flush => Some(PokerType::Flush),
|
||||||
|| (num_jokers == 1 && num_pairs == 2)
|
(2, ..) | (1, 1, _) | (_, 2, 1) => Some(PokerType::TwoPair),
|
||||||
{
|
_ => None,
|
||||||
Some(PokerType::FullHouse)
|
|
||||||
} else if is_straight {
|
|
||||||
Some(PokerType::Straight)
|
|
||||||
} else if is_flush {
|
|
||||||
Some(PokerType::Flush)
|
|
||||||
} else if (num_pairs == 2)
|
|
||||||
|| (num_jokers == 1 && num_pairs == 1)
|
|
||||||
|| (num_jokers == 2 && highest_rank_freq == 1)
|
|
||||||
{
|
|
||||||
Some(PokerType::TwoPair)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +121,7 @@ fn try_poker_hand(num_jokers: usize, cards: &[Card]) -> Option<PokerType> {
|
|||||||
3) No jokers in the sequence of cards provided.
|
3) No jokers in the sequence of cards provided.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fn is_straight(num_jokers: i32, cards: &[Card]) -> bool {
|
fn is_straight(num_jokers: i32, cards: &[PlayingCard]) -> bool {
|
||||||
/** Given a slice `nums` (presumed ascending ordered) and the amount of allowed
|
/** Given a slice `nums` (presumed ascending ordered) and the amount of allowed
|
||||||
* `gaps`, figure out if the nums are actually a consecutive sequence.
|
* `gaps`, figure out if the nums are actually a consecutive sequence.
|
||||||
*/
|
*/
|
||||||
@@ -134,9 +147,8 @@ fn is_straight(num_jokers: i32, cards: &[Card]) -> bool {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
let rank_nums = cards.iter().map(|x| x.rank().unwrap() as i32);
|
let rank_nums = cards.iter().map(|x| x.rank as i32);
|
||||||
let ord_rank_nums =
|
let ord_rank_nums = cards.iter().map(|x| x.rank.ordinary_order());
|
||||||
cards.iter().map(|x| x.rank().unwrap().ordinary_order());
|
|
||||||
|
|
||||||
strictly_consecutive_numbers(rank_nums, num_jokers)
|
strictly_consecutive_numbers(rank_nums, num_jokers)
|
||||||
|| strictly_consecutive_numbers(ord_rank_nums, num_jokers)
|
|| strictly_consecutive_numbers(ord_rank_nums, num_jokers)
|
||||||
@@ -144,13 +156,10 @@ fn is_straight(num_jokers: i32, cards: &[Card]) -> bool {
|
|||||||
|
|
||||||
fn all_same_rank(cards: &[Card]) -> bool {
|
fn all_same_rank(cards: &[Card]) -> bool {
|
||||||
let rank = cards[0].rank().unwrap();
|
let rank = cards[0].rank().unwrap();
|
||||||
cards[1..]
|
cards[1..].iter().all(|card| rank == card.rank().unwrap())
|
||||||
.iter()
|
|
||||||
.map(|card| card.rank().unwrap())
|
|
||||||
.all(|other_rank| rank == other_rank)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mod traits {
|
mod traits_display {
|
||||||
use super::*;
|
use super::*;
|
||||||
use std::fmt::{Display, Formatter, Result};
|
use std::fmt::{Display, Formatter, Result};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user