diff options
author | Kjetil Orbekk <kj@orbekk.com> | 2022-12-22 11:35:14 -0500 |
---|---|---|
committer | Kjetil Orbekk <kj@orbekk.com> | 2022-12-22 11:35:14 -0500 |
commit | 0ba28546b94a794d56c56bba35f035200fd0a434 (patch) | |
tree | 3baa019b135043f46587b968e5d5e41478e33778 | |
parent | 42f6ef6d44e893b47e5e2a49496b5dd2122df232 (diff) |
Support bidding→playing transition in GameState
Introduce a generic type to represent result of playing moves
-rw-r--r-- | protocol/src/bridge_engine.rs | 92 | ||||
-rw-r--r-- | protocol/src/lib.rs | 1 | ||||
-rw-r--r-- | protocol/src/play_result.rs | 20 |
3 files changed, 55 insertions, 58 deletions
diff --git a/protocol/src/bridge_engine.rs b/protocol/src/bridge_engine.rs index 35eb90f..a2766f0 100644 --- a/protocol/src/bridge_engine.rs +++ b/protocol/src/bridge_engine.rs @@ -1,4 +1,7 @@ -use crate::card::{make_deck, sort_cards, Card, RankOrder, Suit}; +use crate::{ + card::{make_deck, sort_cards, Card, RankOrder, Suit}, + play_result::MoveResult, +}; use anyhow::{anyhow, bail}; use log::{error, info}; use rand::{ @@ -628,7 +631,7 @@ impl PlayState { } pub fn play( - mut self, + self, card: Card, ) -> Result<PlayStateResult, anyhow::Error> { Ok(match self.playing_deal.play(card)? { @@ -658,11 +661,6 @@ pub enum PlayStateResult { pub enum GameState { Bidding(BiddingState), Play(PlayState), - PassedOut { - dealer: Player, - deal: Deal, - bidding: Bidding, - }, } impl GameState { @@ -677,7 +675,6 @@ impl GameState { pub fn deal(&self) -> &Deal { match self { Self::Bidding(BiddingState { deal, .. }) => deal, - Self::PassedOut { deal, .. } => deal, Self::Play(PlayState { playing_deal, .. }) => &playing_deal.deal(), } } @@ -685,22 +682,14 @@ impl GameState { pub fn dealer(&self) -> Player { match self { Self::Bidding(BiddingState { dealer, .. }) => *dealer, - Self::PassedOut { dealer, .. } => *dealer, Self::Play(play_state) => play_state.dealer(), } } - pub fn current_player(&self) -> Option<Player> { + pub fn current_player(&self) -> Player { match self { - GameState::Bidding(bidding) => { - Some(bidding.bidding.current_bidder()) - } - GameState::Play(_) => todo!(), - GameState::PassedOut { - dealer, - deal, - bidding, - } => None, + GameState::Bidding(bidding) => bidding.bidding.current_bidder(), + GameState::Play(play) => play.current_player(), } } @@ -720,7 +709,10 @@ impl GameState { } } - pub fn bid(self, bid: Bid) -> Result<Self, anyhow::Error> { + pub fn bid( + self, + bid: Bid, + ) -> Result<MoveResult<GameState, GameResult>, anyhow::Error> { let (dealer, deal, bidding) = match self { GameState::Bidding(BiddingState { dealer, @@ -731,24 +723,27 @@ impl GameState { }; Ok(match bidding.bid(bid)? { BiddingResult::InProgress(bidding) => { - GameState::Bidding(BiddingState { + MoveResult::Stay(GameState::Bidding(BiddingState { dealer, deal, bidding, - }) + })) + } + BiddingResult::Contract(None, _bidding) => { + MoveResult::Go(GameResult) } - BiddingResult::Contract(None, bidding) => GameState::PassedOut { - dealer, - deal, - bidding, - }, BiddingResult::Contract(Some(contract), bidding) => { - GameState::Play(PlayState::new(deal, contract, bidding)) + MoveResult::Stay(GameState::Play(PlayState::new( + deal, contract, bidding, + ))) } }) } } +#[derive(Debug)] +pub struct GameResult; + #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] pub struct Deal { pub north: Vec<Card>, @@ -829,26 +824,7 @@ impl PlayStatePlayerView { #[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug)] pub enum GameStatePlayerView { Bidding(BiddingStatePlayerView), - PassedOut { - dealer: Player, - player_position: Player, - deal: Deal, - bidding: Bidding, - }, - Lead { - dealer: Player, - player_position: Player, - contract: Contract, - hand: Vec<Card>, - }, - Play { - dealer: Player, - player_position: Player, - contract: Contract, - trick: Trick, - dummy: Vec<Card>, - hand: Vec<Card>, - }, + Playing(PlayStatePlayerView), } impl GameStatePlayerView { @@ -863,7 +839,6 @@ impl GameStatePlayerView { player_position, ), ), - GameState::PassedOut { .. } => todo!(), GameState::Play { .. } => todo!(), } } @@ -874,13 +849,9 @@ impl GameStatePlayerView { hand, .. }) => hand, - GameStatePlayerView::PassedOut { - deal, - player_position, - .. - } => player_position.get_cards(deal), - GameStatePlayerView::Lead { hand, .. } => hand, - GameStatePlayerView::Play { hand, .. } => hand, + GameStatePlayerView::Playing(PlayStatePlayerView { + hand, .. + }) => hand, } } } @@ -1128,14 +1099,19 @@ mod tests { info!("Start bidding with game state {game_state:#?}"); let raise = |s| Bid::Raise(Raise::from_str(s).unwrap()); - let game_state = game_state.bid(raise("1H")).unwrap(); - assert_eq!(game_state.is_bidding(), true); + let game_state = game_state.bid(raise("1H")).unwrap().stay().unwrap(); let game_state = game_state .bid(Bid::Pass) .unwrap() + .stay() + .unwrap() .bid(Bid::Pass) .unwrap() + .stay() + .unwrap() .bid(Bid::Pass) + .unwrap() + .stay() .unwrap(); info!("Start playing with game state {game_state:#?}"); assert_eq!(game_state.is_bidding(), false); diff --git a/protocol/src/lib.rs b/protocol/src/lib.rs index 8b48fec..3fbf1e0 100644 --- a/protocol/src/lib.rs +++ b/protocol/src/lib.rs @@ -4,6 +4,7 @@ pub mod card; pub mod bridge_engine; pub mod bot; pub mod simple_bots; +pub mod play_result; #[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug)] pub struct UserInfo { diff --git a/protocol/src/play_result.rs b/protocol/src/play_result.rs new file mode 100644 index 0000000..21961ee --- /dev/null +++ b/protocol/src/play_result.rs @@ -0,0 +1,20 @@ +pub enum MoveResult<Stay, Go> { + Stay(Stay), + Go(Go), +} + +impl<Stay, Go> MoveResult<Stay, Go> { + pub fn stay(self) -> Result<Stay, anyhow::Error> { + match self { + MoveResult::Stay(o) => Ok(o), + MoveResult::Go(_) => Err(anyhow::anyhow!("Not in stay state")), + } + } + + pub fn go(self) -> Result<Go, anyhow::Error> { + match self { + MoveResult::Go(f) => Ok(f), + MoveResult::Stay(_) => Err(anyhow::anyhow!("Not in go state")), + } + } +} |