use crate::cards::StandardCard as Card;
#[repr(C)]
#[derive(
Clone,
Debug,
Default,
serde::Serialize,
serde::Deserialize,
Eq,
PartialEq,
Ord,
PartialOrd,
Hash,
)]
pub(crate) struct Hand(Vec<Card>);
impl Hand {
pub(crate) fn add_card(&mut self, card: Card) {
self.0.push(card)
}
pub(crate) fn score(&self) -> u8 {
self.0
.iter()
.try_fold((0u8, 0u8), |(mut ace_count, mut total), c| {
let val = c.face().value();
if val == 11 {
ace_count = ace_count.checked_add(1)?;
} else {
total = total.checked_add(val)?;
}
Some((ace_count, total))
})
.and_then(|(mut ace_count, mut total)| {
if ace_count >= 1 {
if total <= 10 {
total = total.checked_add(11)?;
} else {
total = total.checked_add(1)?;
}
ace_count = ace_count.checked_sub(1)?;
}
Some(total + ace_count)
})
.unwrap_or(0)
}
pub(crate) fn into_vec(self) -> Vec<Card> {
self.0
}
pub(crate) fn cards_len(&self) -> usize {
self.0.len()
}
pub(crate) fn cards(&self) -> &[Card] {
&self.0
}
}
impl From<Vec<Card>> for Hand {
fn from(cards: Vec<Card>) -> Self {
Self(cards)
}
}
impl Extend<Card> for Hand {
fn extend<I: IntoIterator<Item = Card>>(&mut self, iter: I) {
self.0.extend(iter);
}
}
impl core::iter::FromIterator<Card> for Hand {
fn from_iter<I: IntoIterator<Item = Card>>(iter: I) -> Self {
let mut c = Hand::default();
c.extend(iter);
c
}
}