From cad8f84e88c1816fb4f852a1aea3c98026627c70 Mon Sep 17 00:00:00 2001 From: Kjetil Orbekk Date: Sat, 17 Sep 2022 19:52:01 -0400 Subject: Add state machine for gameplay --- webapp/src/card.rs | 2 +- webapp/src/components/game.rs | 123 ++++++++++++++++++++++++++++-------------- webapp/src/components/hand.rs | 2 +- 3 files changed, 84 insertions(+), 43 deletions(-) diff --git a/webapp/src/card.rs b/webapp/src/card.rs index 58e322d..621bae1 100644 --- a/webapp/src/card.rs +++ b/webapp/src/card.rs @@ -240,7 +240,7 @@ mod tests { } } -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq, Clone)] pub struct Deal { pub north: Vec, pub west: Vec, diff --git a/webapp/src/components/game.rs b/webapp/src/components/game.rs index d6341ac..21b0966 100644 --- a/webapp/src/components/game.rs +++ b/webapp/src/components/game.rs @@ -1,5 +1,6 @@ use crate::bridge_engine::{self, Contract, Player}; use crate::card; +use crate::card::Deal; use crate::card::Suit; use crate::components::{Bidding, Hand, ShowBid}; use log::info; @@ -13,6 +14,35 @@ enum Phase { Cardplay, } +#[derive(Debug)] +enum GameState { + Bidding { + dealer: Player, + deal: Deal, + }, + PassedOut { + dealer: Player, + deal: Deal, + bidding: bridge_engine::Bidding, + }, + Play { + dealer: Player, + deal: Deal, + contract: Contract, + bidding: bridge_engine::Bidding, + }, +} + +impl GameState { + fn deal(&self) -> &Deal { + match self { + Self::Bidding { deal, .. } => deal, + Self::PassedOut { deal, .. } => deal, + Self::Play { deal, .. } => deal, + } + } +} + pub fn deal() -> card::Deal { let mut rng = rand::thread_rng(); let mut deal = card::deal(&mut rng); @@ -20,78 +50,89 @@ pub fn deal() -> card::Deal { deal } +fn init_state() -> GameState { + let dealer = Player::East; + let deal = deal(); + GameState::Bidding { dealer, deal } +} + #[function_component(Game)] pub fn game() -> Html { - let dealt_cards = use_state(|| deal()); - - // let north = use_state(|| HandProps::from_iter(deal.north.into_iter())); - // let west = use_state(|| HandProps::from_iter(deal.west.into_iter())); - // let south = use_state(|| HandProps::from_iter(deal.south.into_iter())); - // let east = use_state(|| HandProps::from_iter(deal.east.into_iter())); - - let dealer = use_state(|| Player::East); - - let contract: UseStateHandle, bridge_engine::Bidding)>> = - use_state(|| None); - let on_contract = { - let contract = contract.clone(); - Callback::from(move |c| contract.set(Some(c))) - }; - - let phase = if contract.is_none() { - Phase::Bidding - } else { - Phase::Cardplay - }; + let state = use_state(|| init_state()); let shuffle = { - let dealt_cards = dealt_cards.clone(); - let dealer = dealer.clone(); - let contract = contract.clone(); - + let state = state.clone(); Callback::from(move |_| { - dealt_cards.set(deal()); - dealer.set(dealer.next()); - contract.set(None); + state.set(init_state()); }) }; let on_card_clicked = { Callback::from(move |card| info!("Card clicked: {}", card)) }; + let center = match &*state { + GameState::Bidding { dealer, deal } => { + let on_contract = { + let state = state.clone(); + let dealer = dealer.clone(); + let deal = deal.clone(); + Callback::from(move |(contract, bidding)| { + state.set(match contract { + Some(contract) => GameState::Play { + dealer: dealer, + deal: deal.clone(), + contract, + bidding, + }, + None => GameState::PassedOut { + dealer: dealer, + deal: deal.clone(), + bidding, + }, + }); + }) + }; + html! { + + } + } + GameState::Play { + dealer, + deal, + contract, + bidding, + } => html! {

{ "Time to play" }

}, + GameState::PassedOut { .. } => html! {

{ "Everyone passed" }

}, + }; + html! { <>
-

{ format!("Dealer: {:?}", *dealer) }

- if let Some(_) = &*contract { - { "Let's play." } - } else { - - } + { center }
-
-
-
-
diff --git a/webapp/src/components/hand.rs b/webapp/src/components/hand.rs index 9e1f993..411a173 100644 --- a/webapp/src/components/hand.rs +++ b/webapp/src/components/hand.rs @@ -1,4 +1,4 @@ -use crate::components::card::{Card, CardProps}; +use crate::components::card::{Card}; use crate::card; use yew::prelude::*; -- cgit v1.2.3