use super::card::Card;
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct Hand(u64);
impl Hand {
pub fn empty() -> Self {
Self(0)
}
pub fn size(&self) -> usize {
self.0.count_ones() as usize
}
pub fn add(lhs: Self, rhs: Self) -> Self {
assert!(u64::from(lhs) & u64::from(rhs) == 0);
Self(lhs.0 | rhs.0)
}
pub fn complement(&self) -> Self {
Self(self.0 ^ ((1 << 52) - 1))
}
}
impl From<u64> for Hand {
fn from(n: u64) -> Self {
Self(n)
}
}
impl From<Hand> for u64 {
fn from(h: Hand) -> Self {
h.0
}
}
impl From<Hand> for Vec<Card> {
fn from(h: Hand) -> Self {
let mut value = h.0;
let mut index = 0u8;
let mut cards = Vec::new();
while value > 0 {
if value & 1 == 1 {
cards.push(Card::from(index));
}
value = value >> 1;
index = index + 1;
}
cards
}
}
impl From<Vec<Card>> for Hand {
fn from(cards: Vec<Card>) -> Self {
Self(
cards
.into_iter()
.map(|c| u64::from(c))
.fold(0u64, |a, b| a | b),
)
}
}
impl std::fmt::Display for Hand {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
for card in Vec::<Card>::from(*self) {
write!(f, "{}", card)?;
}
Ok(())
}
}