use crate::card::Rank;
use crate::hand::Hand;
use super::flush::find_flush;
use super::four_of_a_kind::find_four_of_a_kind;
use super::full_house::find_full_house;
use super::pair::find_pair;
use super::score::{calculate_hand_score, HandRank};
use super::straight::find_straight;
use super::three_of_a_kind::find_three_of_a_kind;
use super::two_pair::find_two_pair;
pub fn evaluate(hand: &Hand) -> u32 {
let mut hand_desc = hand.clone();
hand_desc
.sort_by_rank(false)
.expect("Failed to sort by rank");
let flush_ranks_desc = find_flush(&hand_desc);
if let Some(flush_ranks) = &flush_ranks_desc {
if let Some(straight_flush_rank) = find_straight(&flush_ranks) {
return calculate_hand_score(vec![straight_flush_rank], HandRank::StraightFlush);
}
}
let ranks_desc = hand_desc.get_ranks();
let mut ranks_desc_no_dup = ranks_desc.clone();
ranks_desc_no_dup.dedup();
let num_duplicates = ranks_desc.len() - ranks_desc_no_dup.len();
if num_duplicates > 2 {
if let Some(four_of_a_kind) = find_four_of_a_kind(&ranks_desc) {
return calculate_hand_score(four_of_a_kind, HandRank::FourOfAKind);
}
if let Some(full_house) = find_full_house(&ranks_desc) {
return calculate_hand_score(full_house, HandRank::FullHouse);
}
}
if let Some(ref flush_ranks_desc) = flush_ranks_desc {
let flush_ranks = &flush_ranks_desc[0..5];
return calculate_hand_score(flush_ranks.to_vec(), HandRank::Flush);
}
if let Some(straight_rank) = find_straight(&ranks_desc_no_dup) {
return calculate_hand_score(vec![straight_rank], HandRank::Straight);
}
if num_duplicates > 1 {
if let Some(three_of_a_kind) = find_three_of_a_kind(&ranks_desc) {
return calculate_hand_score(three_of_a_kind, HandRank::ThreeOfAKind);
}
if let Some(two_pair) = find_two_pair(&ranks_desc) {
return calculate_hand_score(two_pair, HandRank::TwoPair);
}
panic!("No paired hand found but expected.");
}
if num_duplicates > 0 {
if let Some(pair) = find_pair(&ranks_desc) {
return calculate_hand_score(pair, HandRank::OnePair);
}
panic!("No paired hand found but expected.");
}
let high_cards: Vec<Rank>;
if ranks_desc.len() < 5 {
high_cards = ranks_desc.clone();
} else {
high_cards = ranks_desc[0..5].to_vec();
}
return calculate_hand_score(high_cards.to_vec(), HandRank::HighCard);
}