use crate::types::arrays::five_card::FiveCard;
use crate::types::arrays::seven_card::SevenCard;
use crate::types::arrays::Vectorable;
use crate::types::playing_card::PlayingCard;
use crate::types::playing_cards::PlayingCards;
use ckc_rs::cards::binary_card::{BinaryCard, BC64};
use ckc_rs::cards::five::Five;
use ckc_rs::cards::seven::Seven;
use ckc_rs::cards::{HandRanker, HandValidator};
use ckc_rs::hand_rank::HandRankValue;
use serde::{Deserialize, Serialize};
use std::error::Error;
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct SimpleBinaryCardMap {
pub bc: BinaryCard,
pub rank: HandRankValue,
}
impl SimpleBinaryCardMap {
#[must_use]
pub fn new(bc: BinaryCard, rank: HandRankValue) -> SimpleBinaryCardMap {
SimpleBinaryCardMap { bc, rank }
}
}
impl From<BinaryCardMap> for SimpleBinaryCardMap {
fn from(bcm: BinaryCardMap) -> Self {
SimpleBinaryCardMap::new(bcm.best, bcm.rank)
}
}
#[derive(Serialize, Deserialize, Clone, Copy, Debug, Default, PartialEq)]
pub struct BinaryCardMap {
pub bc: BinaryCard,
pub best: BinaryCard,
pub rank: HandRankValue,
}
impl BinaryCardMap {
pub fn generate(path: &str) -> Result<(), Box<dyn Error>> {
let mut wtr = csv::Writer::from_path(path)?;
let deck = PlayingCards::deck();
for b in deck.combinations(5) {
wtr.serialize(BinaryCardMap::from(b))?;
}
for b in deck.combinations(7) {
wtr.serialize(BinaryCardMap::from(b))?;
}
wtr.flush()?;
Ok(())
}
#[must_use]
pub fn is_blank(&self) -> bool {
*self == BinaryCardMap::default()
}
}
impl From<Five> for BinaryCardMap {
fn from(five: Five) -> Self {
if five.is_blank() {
return BinaryCardMap::default();
}
let (rank, five) = five.hand_rank_value_and_hand();
let bc = BinaryCard::from_five(five);
let best = bc;
BinaryCardMap { bc, best, rank }
}
}
impl From<Seven> for BinaryCardMap {
fn from(seven: Seven) -> Self {
if !seven.is_valid() {
return BinaryCardMap::default();
}
let (rank, five) = seven.hand_rank_value_and_hand();
let bc = BinaryCard::from_seven(seven);
let best = BinaryCard::from_five(five);
BinaryCardMap { bc, best, rank }
}
}
impl From<Vec<&PlayingCard>> for BinaryCardMap {
fn from(v: Vec<&PlayingCard>) -> Self {
match v.len() {
5 => {
let five_card_result = FiveCard::try_from(v);
let five = match five_card_result {
Ok(five_card) => five_card.to_five(),
Err(_) => Five::default(),
};
BinaryCardMap::from(five)
}
7 => {
let seven_card_result = SevenCard::try_from(v);
let seven = match seven_card_result {
Ok(seven_card) => seven_card.to_seven(),
Err(_) => Seven::default(),
};
BinaryCardMap::from(seven)
}
_ => BinaryCardMap::default(),
}
}
}
#[cfg(test)]
#[allow(non_snake_case)]
mod generic_tests {
use super::*;
#[test]
fn from_five() {
let five = Five::try_from("A♠ K♠ Q♠ J♠ T♠").unwrap();
let sut = BinaryCardMap::from(five);
assert_eq!(sut.rank, 1);
assert_eq!(sut.bc, 4_362_862_139_015_168);
assert_eq!(sut.best, 4_362_862_139_015_168);
}
#[test]
fn from_five__default() {
assert_eq!(
BinaryCardMap::default(),
BinaryCardMap::from(Five::default())
);
}
#[test]
fn is_blank() {
assert!(BinaryCardMap::default().is_blank());
assert!(!BinaryCardMap::from(Five::try_from("A♠ K♠ Q♠ J♠ T♠").unwrap()).is_blank());
}
}