use std::fmt::{Debug, Display, Error, Formatter};
use crate::{Card, CardCollection, Suit, ACE};
pub type Foundation = Vec<Card>;
#[derive(Clone, Default, Eq, Hash, PartialEq)]
pub struct Foundations(pub [Foundation; 4]);
impl Foundations {
pub fn new() -> Foundations {
Foundations([Vec::new(), Vec::new(), Vec::new(), Vec::new()])
}
pub fn foundation(&self, suit: Suit) -> &Foundation {
&self.0[suit as usize]
}
}
impl CardCollection for Foundations {
fn add_card(&self, card: Card) -> Result<Self, ()> {
if self.foundation(card.suit).is_empty() {
if card.rank != ACE {
return Err(());
}
} else if
card.rank == ACE ||
self.foundation(card.suit).last().unwrap().rank + 1 != card.rank
{
return Err(());
}
let mut clone = self.clone();
clone.0[card.suit as usize].push(card);
Ok(clone)
}
fn pop_card(&self) -> Vec<(Self, Card)> {
Vec::new()
}
}
impl Display for Foundations {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
let foundation_strings: Vec<String> = self.0.iter().map(
|foundation|
if foundation.is_empty() {
"Empty".to_string()
} else {
format!("Up to {}", foundation.last().unwrap().to_string())
}
).collect();
write!(f, "Foundations: {}", foundation_strings.join(", "))
}
}
impl Debug for Foundations {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
write!(f, "Foundations:")?;
for foundation in &self.0 {
if !foundation.is_empty() {
write!(f, " {:?}", foundation.last().unwrap())?;
}
}
Ok(())
}
}