summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKjetil Orbekk <kj@orbekk.com>2022-09-11 12:44:10 -0400
committerKjetil Orbekk <kj@orbekk.com>2022-09-11 12:44:10 -0400
commit9656f8ce14360dc0eb83e2b65ed25eef79c02e42 (patch)
treef071f3fc864061837c35367974d3bdcad325e872
parent3fb6f32a46b0cdfc59643bee255648e1ef401116 (diff)
Add declarer logic
-rw-r--r--webapp/src/bridge_engine.rs48
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