use crate::types::arrays::two_card::TwoCard;
use crate::types::playing_cards::PlayingCards;
use crate::types::ranges::two_cards::TwoCards;
use ckc_rs::PokerCard;
use serde::{Deserialize, Serialize};
use std::collections::hash_set::Iter;
use std::collections::HashSet;
#[derive(Serialize, Deserialize, Clone, Debug, Default, Eq, PartialEq)]
pub struct TwoCardsSet {
pub hands: HashSet<TwoCard>,
}
impl TwoCardsSet {
#[must_use]
pub fn every() -> TwoCardsSet {
TwoCardsSet::from(PlayingCards::deck())
}
#[must_use]
pub fn contains(&self, cards: &TwoCard) -> bool {
self.hands.contains(cards)
}
#[must_use]
pub fn difference(&self, other: &TwoCardsSet) -> TwoCardsSet {
TwoCardsSet {
hands: self.hands.difference(&other.hands).copied().collect(),
}
}
pub fn insert(&mut self, cards: TwoCard) -> bool {
if self.contains(&cards) {
false
} else {
self.hands.insert(cards)
}
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.hands.is_empty()
}
#[must_use]
pub fn iter(&self) -> Iter<'_, TwoCard> {
self.hands.iter()
}
#[must_use]
pub fn len(&self) -> usize {
self.hands.len()
}
#[must_use]
pub fn overlap(&self, other: &TwoCardsSet) -> TwoCardsSet {
TwoCardsSet::from(
self.hands
.intersection(&other.hands)
.copied()
.collect::<HashSet<TwoCard>>(),
)
}
#[must_use]
pub fn pairs(&self) -> TwoCardsSet {
TwoCardsSet::from(&self.two_cards_vec().pairs().hands)
}
pub fn remove(&mut self, cards: &TwoCard) -> bool {
self.hands.remove(cards)
}
pub fn sample(&mut self) -> Option<TwoCard> {
let sampled = self.two_cards_vec().sample();
match sampled {
Some(s) => {
if self.remove(&s) {
Some(s)
} else {
None
}
}
None => None,
}
}
#[must_use]
pub fn sampler(&mut self, number: usize) -> TwoCardsSet {
let mut sampler = TwoCardsSet::default();
for _ in 0..number {
match self.sample() {
Some(s) => sampler.insert(s),
None => false,
};
}
sampler
}
#[must_use]
pub fn suited(&self) -> TwoCardsSet {
TwoCardsSet::from(&self.two_cards_vec().suited().hands)
}
#[must_use]
pub fn union(&self, other: &TwoCardsSet) -> TwoCardsSet {
TwoCardsSet {
hands: self.hands.union(&other.hands).copied().collect(),
}
}
#[must_use]
pub fn two_cards_vec(&self) -> TwoCards {
TwoCards::from(self.clone())
}
#[must_use]
pub fn to_vec(&self) -> Vec<TwoCard> {
self.hands.clone().into_iter().collect()
}
}
impl From<HashSet<TwoCard>> for TwoCardsSet {
fn from(hands: HashSet<TwoCard>) -> Self {
TwoCardsSet { hands }
}
}
impl From<PlayingCards> for TwoCardsSet {
fn from(deck: PlayingCards) -> Self {
if deck.len() < 2 {
return TwoCardsSet::default();
}
let mut range = TwoCardsSet::default();
for v in deck.combinations(2) {
range.insert(
TwoCard::new(v.get(0).unwrap().as_u32(), v.get(1).unwrap().as_u32()).unwrap(),
);
}
range
}
}
impl From<&Vec<TwoCard>> for TwoCardsSet {
fn from(hands: &Vec<TwoCard>) -> Self {
TwoCardsSet::from(hands.iter().copied().collect::<HashSet<_>>())
}
}
#[cfg(test)]
#[allow(non_snake_case)]
mod types_ranges_two_cards_set_tests {
use super::*;
#[test]
fn every() {
assert_eq!(TwoCardsSet::every().len(), 1326);
}
#[test]
fn difference() {
let mut range1 = TwoCardsSet::default();
let mut range2 = TwoCardsSet::default();
let aces = TwoCard::try_from("AS AC").unwrap();
let kings = TwoCard::try_from("KS KC").unwrap();
let queens = TwoCard::try_from("QS QC").unwrap();
range1.insert(aces);
range1.insert(kings);
range2.insert(kings);
range2.insert(queens);
}
#[test]
fn insert() {
let mut range = TwoCardsSet::default();
let two = TwoCard::try_from("AS AC").unwrap();
let actual = range.insert(two);
assert!(actual);
assert!(!range.insert(two));
}
#[test]
fn is_empty() {
assert!(TwoCardsSet::default().is_empty());
}
#[test]
fn len() {
assert_eq!(0, TwoCardsSet::default().len());
}
#[test]
fn pairs() {
assert_eq!(TwoCardsSet::every().pairs().len(), 78);
}
#[test]
fn remove() {
let mut range = TwoCardsSet::default();
let aces = TwoCard::try_from("AS AC").unwrap();
let kings = TwoCard::try_from("KS KC").unwrap();
range.insert(aces);
range.insert(kings);
assert!(range.remove(&kings));
assert!(range.remove(&aces));
assert!(!range.remove(&kings));
assert!(!range.remove(&aces));
}
#[test]
fn sample() {
let mut sampled = TwoCardsSet::every();
let sample = sampled.sample().unwrap();
assert!(!sampled.contains(&sample));
assert!(sampled.insert(sample));
assert!(sampled.contains(&sample));
}
#[test]
fn sample__empty() {
let sample = TwoCardsSet::default().sample();
assert!(sample.is_none());
}
#[test]
fn sampler__empty() {
let sampler = TwoCardsSet::default().sampler(2);
assert!(sampler.is_empty());
}
#[test]
fn suited() {
assert_eq!(TwoCardsSet::every().suited().len(), 312);
}
#[test]
fn default() {
let range = TwoCardsSet::default();
assert!(range.is_empty());
}
#[test]
fn from__playing_cards() {
let cards = PlayingCards::try_from("AS KS AH KH").unwrap();
let range = TwoCardsSet::from(cards);
assert_eq!(range.len(), 6);
assert!(range.contains(&TwoCard::try_from("AS AH").unwrap()));
assert!(range.contains(&TwoCard::try_from("AS KS").unwrap()));
assert!(range.contains(&TwoCard::try_from("AS KH").unwrap()));
assert!(range.contains(&TwoCard::try_from("AS KS").unwrap()));
assert!(range.contains(&TwoCard::try_from("AH KS").unwrap()));
assert!(range.contains(&TwoCard::try_from("AH KH").unwrap()));
assert!(range.contains(&TwoCard::try_from("KS KH").unwrap()));
assert!(!range.contains(&TwoCard::try_from("AS JH").unwrap()));
}
#[test]
fn from__playing_cards__not_enough() {
let cards = PlayingCards::try_from("AS").unwrap();
let range = TwoCardsSet::from(cards);
assert!(range.is_empty());
}
}