use crate::card::Card; #[derive(PartialEq, Eq, Clone, Copy, Debug)] pub enum Player { North, West, South, East, } impl Player { pub fn next(&self) -> Self { match self { Self::North => Self::West, Self::West => Self::South, Self::South => Self::East, Self::East => Self::North, } } } #[derive(PartialEq, Eq, Debug)] pub struct Trick { pub leader: Player, pub cards_played: Vec, } #[derive(PartialEq, Eq, Debug)] pub struct Turn { in_progress: Trick, } #[derive(PartialEq, Eq, Debug)] pub enum PlayResult { InProgress(Turn), Trick(Trick), } impl Turn { pub fn new(p: Player) -> Turn { Turn { in_progress: Trick { leader: p, cards_played: Vec::with_capacity(4), }, } } pub fn play(mut self: Turn, card: Card) -> PlayResult { self.in_progress.cards_played.push(card); if self.in_progress.cards_played.len() >= 4 { return PlayResult::Trick(self.in_progress); } PlayResult::InProgress(self) } } #[cfg(test)] mod tests { use super::*; #[test] fn next_player() { let next_players = vec![Player::North, Player::West, Player::South, Player::East] .iter() .map(Player::next) .collect::>(); assert_eq!( next_players, vec![Player::West, Player::South, Player::East, Player::North] ); } fn as_turn(p: PlayResult) -> Turn { if let PlayResult::InProgress(t) = p { t } else { panic!("expected PlayResult::InProgress(): {:?}", p); } } fn as_trick(p: PlayResult) -> Trick { if let PlayResult::Trick(t) = p { t } else { panic!("expected PlayResult::Trick(): {:?}", p); } } #[test] fn play_turn() { let turn = Turn::new(Player::South); let turn = as_turn(turn.play("♣4".parse().unwrap())); let turn = as_turn(turn.play("♥A".parse().unwrap())); let turn = as_turn(turn.play("♣4".parse().unwrap())); let trick = as_trick(turn.play("♣A".parse().unwrap())); assert_eq!( trick, Trick { leader: Player::South, cards_played: ["♣4", "♥A", "♣4", "♣A"] .into_iter() .map(|c| c.parse().unwrap()) .collect() } ); } }