diff options
author | Kjetil Orbekk <kj@orbekk.com> | 2022-09-11 12:44:10 -0400 |
---|---|---|
committer | Kjetil Orbekk <kj@orbekk.com> | 2022-09-11 12:44:10 -0400 |
commit | 9656f8ce14360dc0eb83e2b65ed25eef79c02e42 (patch) | |
tree | f071f3fc864061837c35367974d3bdcad325e872 | |
parent | 3fb6f32a46b0cdfc59643bee255648e1ef401116 (diff) |
Add declarer logic
-rw-r--r-- | webapp/src/bridge_engine.rs | 48 |
1 files changed, 36 insertions, 12 deletions
diff --git a/webapp/src/bridge_engine.rs b/webapp/src/bridge_engine.rs index ae15c7d..2a10063 100644 --- a/webapp/src/bridge_engine.rs +++ b/webapp/src/bridge_engine.rs @@ -6,24 +6,33 @@ use regex::Regex; use std::cmp::Ordering; use std::fmt; use std::str::FromStr; -use strum::IntoEnumIterator; -use strum_macros::EnumIter; +use strum::{EnumCount, IntoEnumIterator}; +use strum_macros::{EnumCount as EnumCountMacro, EnumIter, FromRepr}; -#[derive(PartialEq, Eq, Clone, Copy, Debug)] +#[derive(PartialEq, Eq, Clone, Copy, Debug, FromRepr, EnumCountMacro)] +#[repr(u8)] pub enum Player { - West, + West = 0, North, - South, East, + South, } impl Player { pub fn next(&self) -> Self { + self.many_next(1) + } + + pub fn many_next(self, i: usize) -> Self { + Player::from_repr(((self as usize + i) % Player::COUNT) as u8).unwrap() + } + + pub fn short_str(&self) -> &str { match self { - Self::West => Self::North, - Self::North => Self::East, - Self::East => Self::South, - Self::South => Self::West, + Self::West => "W", + Self::North => "N", + Self::East => "E", + Self::South => "W", } } } @@ -255,13 +264,14 @@ impl fmt::Display for ContractModifier { #[derive(Debug, PartialEq, Eq, Copy, Clone)] pub struct Contract { + declarer: Player, highest_bid: Raise, modifier: ContractModifier, } impl fmt::Display for Contract { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> { - write!(f, "{}{}", self.highest_bid, self.modifier) + write!(f, "{}{}{}", self.highest_bid, self.declarer.short_str(), self.modifier) } } @@ -279,6 +289,11 @@ impl Bidding { } } + fn declarer(&self) -> Player { + // Bids are: [..., winning bid, pass, pass, pass]. + self.dealer.many_next(self.bids.len() - 4) + } + pub fn highest_bid(&self) -> Option<Raise> { for bid in self.bids.iter().rev() { if let Some(raise) = bid.as_raise() { @@ -302,6 +317,7 @@ impl Bidding { match self.highest_bid() { None => None, Some(highest_bid) => Some(Contract { + declarer: self.declarer(), highest_bid, modifier: ContractModifier::None, }), @@ -375,6 +391,7 @@ mod tests { let contract = as_contract(bidding.bid(Bid::Pass).unwrap()); assert_eq!( Some(Contract { + declarer: Player::West, highest_bid: "1♦".parse().unwrap(), modifier: ContractModifier::None }), @@ -413,22 +430,24 @@ mod tests { format!( "{}", Contract { + declarer: Player::West, highest_bid: "1♥".parse().unwrap(), modifier: ContractModifier::None } ), - "1♡" + "1♡W" ); assert_eq!( format!( "{}", Contract { + declarer: Player::East, highest_bid: "1♥".parse().unwrap(), modifier: ContractModifier::Doubled } ), - "1♡x" + "1♡Ex" ); } @@ -468,6 +487,11 @@ mod tests { ); } + #[test] + fn many_next_player() { + assert_eq!(Player::South, Player::South.many_next(4 * 1234567890)); + } + fn as_turn(p: PlayResult) -> PlayTurn { if let PlayResult::InProgress(t) = p { t |