summaryrefslogtreecommitdiff
path: root/protocol
diff options
context:
space:
mode:
authorKjetil Orbekk <kj@orbekk.com>2022-12-22 19:09:17 -0500
committerKjetil Orbekk <kj@orbekk.com>2022-12-22 19:09:17 -0500
commit58aa2e4764f90528270ae5b9a61de576260e5483 (patch)
treeb8b9ce071637fa66335108e7430cce849f872933 /protocol
parenta60500b47c81d15c9b970b58b1c871821dbe934a (diff)
Fixes to the engine enough that the random bot can finish a game
Diffstat (limited to 'protocol')
-rw-r--r--protocol/src/bridge_engine.rs84
-rw-r--r--protocol/src/simple_bots.rs13
2 files changed, 75 insertions, 22 deletions
diff --git a/protocol/src/bridge_engine.rs b/protocol/src/bridge_engine.rs
index 7699a22..bacee56 100644
--- a/protocol/src/bridge_engine.rs
+++ b/protocol/src/bridge_engine.rs
@@ -213,15 +213,19 @@ impl DealInPlay {
})
}
TurnInPlayResult::Trick(trick) => {
- DealInPlayResult::InProgress(Self {
- in_progress: TurnInPlay::new(trick.winner()),
- tricks_played: {
- let mut tricks = self.tricks_played;
- tricks.push(trick);
- tricks
- },
- deal: self.deal,
- })
+ let trick_winner = trick.winner();
+ let mut tricks = self.tricks_played;
+ tricks.push(trick);
+
+ if player_cards.is_empty() {
+ DealInPlayResult::PlayFinished(tricks)
+ } else {
+ DealInPlayResult::InProgress(Self {
+ in_progress: TurnInPlay::new(trick_winner),
+ tricks_played: tricks,
+ deal: self.deal,
+ })
+ }
}
})
}
@@ -630,10 +634,7 @@ impl PlayState {
self.playing_deal.current_player()
}
- pub fn play(
- self,
- card: Card,
- ) -> Result<PlayStateResult, anyhow::Error> {
+ pub fn play(self, card: Card) -> Result<PlayStateResult, anyhow::Error> {
Ok(match self.playing_deal.play(card)? {
DealInPlayResult::InProgress(playing_deal) => {
PlayStateResult::InProgress(Self {
@@ -663,6 +664,12 @@ pub enum GameState {
Play(PlayState),
}
+impl Into<GameState> for PlayState {
+ fn into(self) -> GameState {
+ GameState::Play(self)
+ }
+}
+
impl GameState {
pub fn new(deal: Deal, dealer: Player) -> Self {
Self::Bidding(BiddingState {
@@ -709,18 +716,29 @@ impl GameState {
}
}
+ pub fn bidding(&self) -> Result<&BiddingState, anyhow::Error> {
+ match self {
+ GameState::Bidding(bidding_state) => Ok(bidding_state),
+ _ => Err(anyhow::anyhow!("not currently bidding")),
+ }
+ }
+
+ pub fn play_state(&self) -> Result<&PlayState, anyhow::Error> {
+ match self {
+ GameState::Play(play_state) => Ok(play_state),
+ _ => Err(anyhow::anyhow!("not currently playing")),
+ }
+ }
+
pub fn bid(
self,
bid: Bid,
) -> Result<MoveResult<GameState, GameResult>, anyhow::Error> {
- let (dealer, deal, bidding) = match self {
- GameState::Bidding(BiddingState {
- dealer,
- deal,
- bidding,
- }) => (dealer, deal, bidding),
- _ => bail!("not currently bidding: {self:?}"),
- };
+ let BiddingState {
+ dealer,
+ deal,
+ bidding,
+ } = self.bidding()?.clone();
Ok(match bidding.bid(bid)? {
BiddingResult::InProgress(bidding) => {
MoveResult::Stay(GameState::Bidding(BiddingState {
@@ -739,11 +757,31 @@ impl GameState {
}
})
}
+
+ pub fn play(
+ self,
+ card: Card,
+ ) -> Result<MoveResult<GameState, GameResult>, anyhow::Error> {
+ Ok(match self.play_state()?.clone().play(card)? {
+ PlayStateResult::InProgress(play_state) => {
+ MoveResult::Stay(play_state.into())
+ }
+ PlayStateResult::PlayFinished(result) => {
+ MoveResult::Go(result.into())
+ }
+ })
+ }
}
#[derive(PartialEq, Eq, Clone, Debug, Serialize, Deserialize)]
pub struct GameResult;
+impl Into<GameResult> for PlayResult {
+ fn into(self) -> GameResult {
+ GameResult
+ }
+}
+
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
pub struct Deal {
pub north: Vec<Card>,
@@ -803,7 +841,9 @@ impl PlayStatePlayerView {
contract: play_state.contract,
dummy: None,
declarer_tricks: 0,
- hand: player_position.get_cards(&play_state.deal).clone(),
+ hand: player_position
+ .get_cards(&play_state.playing_deal.deal)
+ .clone(),
previous_trick: Trick {
leader: random(),
cards_played: vec![],
diff --git a/protocol/src/simple_bots.rs b/protocol/src/simple_bots.rs
index 3df7b5d..501f1f4 100644
--- a/protocol/src/simple_bots.rs
+++ b/protocol/src/simple_bots.rs
@@ -147,4 +147,17 @@ mod tests {
(AlwaysPassBiddingBot {}).bid(&player_view).await
);
}
+
+ #[tokio::test]
+ async fn play_until_completion() {
+ crate::tests::test_setup();
+ let bot = RandomPlayingBot {};
+ let mut result = PlayStateResult::InProgress(example_play_state());
+ while let PlayStateResult::InProgress(play_state) = result {
+ info!("Play state: {play_state:#?}");
+ let player_state = PlayStatePlayerView::from_play_state(&play_state, play_state.current_player());
+ let card = bot.play(&player_state).await;
+ result = play_state.play(card).unwrap();
+ }
+ }
}