diff options
| author | Kjetil Orbekk <kj@orbekk.com> | 2022-09-04 19:42:57 -0400 |
|---|---|---|
| committer | Kjetil Orbekk <kj@orbekk.com> | 2022-09-04 19:44:53 -0400 |
| commit | ab68d26c6b16f973642d378900f5e6ac2be221b7 (patch) | |
| tree | 357206052643d3ee0b065fd4ee6cb8af928e11f9 /webapp/src/bridge_engine.rs | |
| parent | b7180143745c5ebe571936b0116cca403d082e8d (diff) | |
Add turn/trick representation
Includes convenience test and parsing utilities
Diffstat (limited to 'webapp/src/bridge_engine.rs')
| -rw-r--r-- | webapp/src/bridge_engine.rs | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/webapp/src/bridge_engine.rs b/webapp/src/bridge_engine.rs new file mode 100644 index 0000000..48c0fd2 --- /dev/null +++ b/webapp/src/bridge_engine.rs @@ -0,0 +1,108 @@ +use crate::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<card::Card>, +} + +#[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::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::<Vec<_>>(); + 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() + } + ); + } +} |
