From 3fb6f32a46b0cdfc59643bee255648e1ef401116 Mon Sep 17 00:00:00 2001 From: Kjetil Orbekk Date: Sun, 11 Sep 2022 11:12:16 -0400 Subject: Refactor passed contract into Option --- TODO.org | 5 ++++ webapp/src/bridge_engine.rs | 51 +++++++++++++++------------------------ webapp/src/components/bidding.rs | 6 ++--- webapp/src/components/game.rs | 42 +++++++++++++++----------------- webapp/src/components/hand.rs | 2 +- webapp/src/components/show_bid.rs | 12 ++++++--- webapp/src/main.rs | 1 - 7 files changed, 56 insertions(+), 63 deletions(-) create mode 100644 TODO.org diff --git a/TODO.org b/TODO.org new file mode 100644 index 0000000..b66c2b9 --- /dev/null +++ b/TODO.org @@ -0,0 +1,5 @@ +#+title: Todo + +* Webapp +** TODO Implement restrictions for doubling and redoubling +** TODO Hook up double and redouble buttons in the UI diff --git a/webapp/src/bridge_engine.rs b/webapp/src/bridge_engine.rs index 2161a53..ae15c7d 100644 --- a/webapp/src/bridge_engine.rs +++ b/webapp/src/bridge_engine.rs @@ -255,16 +255,13 @@ impl fmt::Display for ContractModifier { #[derive(Debug, PartialEq, Eq, Copy, Clone)] pub struct Contract { - highest_bid: Option, + highest_bid: Raise, modifier: ContractModifier, } impl fmt::Display for Contract { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> { - match self.highest_bid { - None => write!(f, "Passed"), - Some(bid) => write!(f, "{}{}", bid, self.modifier), - } + write!(f, "{}{}", self.highest_bid, self.modifier) } } @@ -301,9 +298,18 @@ impl Bidding { passes == 3 } + fn contract(&self) -> Option { + match self.highest_bid() { + None => None, + Some(highest_bid) => Some(Contract { + highest_bid, + modifier: ContractModifier::None, + }), + } + } + pub fn bid(mut self, bid: Bid) -> Result { // TODO: Need logic for double and redouble here. - let highest_bid = self.highest_bid(); if bid.as_raise().is_some() && bid.as_raise() <= self.highest_bid() { bail!( "bid too low: {:?} <= {:?}", @@ -313,13 +319,7 @@ impl Bidding { } self.bids.push(bid); if self.passed_out() { - Ok(BiddingResult::Contract( - Contract { - highest_bid, - modifier: ContractModifier::None, - }, - self, - )) + Ok(BiddingResult::Contract(self.contract(), self)) } else { Ok(BiddingResult::InProgress(self)) } @@ -329,7 +329,7 @@ impl Bidding { #[derive(Debug, Clone)] pub enum BiddingResult { InProgress(Bidding), - Contract(Contract, Bidding), + Contract(Option, Bidding), } impl BiddingResult { @@ -357,7 +357,7 @@ mod tests { } } - fn as_contract(r: BiddingResult) -> Contract { + fn as_contract(r: BiddingResult) -> Option { match r { BiddingResult::Contract(contract, _) => contract, _ => panic!("expected BiddingResult::Contract(): {:?}", r), @@ -374,10 +374,10 @@ mod tests { let bidding = as_bidding(bidding.bid(Bid::Pass).unwrap()); let contract = as_contract(bidding.bid(Bid::Pass).unwrap()); assert_eq!( - Contract { - highest_bid: Some("1♦".parse().unwrap()), + Some(Contract { + highest_bid: "1♦".parse().unwrap(), modifier: ContractModifier::None - }, + }), contract ); } @@ -413,18 +413,7 @@ mod tests { format!( "{}", Contract { - highest_bid: None, - modifier: ContractModifier::None - } - ), - "Passed" - ); - - assert_eq!( - format!( - "{}", - Contract { - highest_bid: Some("1♥".parse().unwrap()), + highest_bid: "1♥".parse().unwrap(), modifier: ContractModifier::None } ), @@ -435,7 +424,7 @@ mod tests { format!( "{}", Contract { - highest_bid: Some("1♥".parse().unwrap()), + highest_bid: "1♥".parse().unwrap(), modifier: ContractModifier::Doubled } ), diff --git a/webapp/src/components/bidding.rs b/webapp/src/components/bidding.rs index d142dec..a7e1e43 100644 --- a/webapp/src/components/bidding.rs +++ b/webapp/src/components/bidding.rs @@ -1,13 +1,13 @@ -use crate::bridge_engine::{self, Bid, BiddingResult, Contract, Player}; +use crate::bridge_engine::{self, BiddingResult, Contract, Player}; use crate::components::{BiddingBox, BiddingTable}; -use log::{info, error}; +use log::{error}; use yew::prelude::*; #[derive(PartialEq, Properties, Clone)] pub struct BiddingProperties { pub dealer: Player, - pub on_contract: Callback<(Contract, bridge_engine::Bidding)>, + pub on_contract: Callback<(Option, bridge_engine::Bidding)>, } #[function_component(Bidding)] diff --git a/webapp/src/components/game.rs b/webapp/src/components/game.rs index 0f25fc3..1544f13 100644 --- a/webapp/src/components/game.rs +++ b/webapp/src/components/game.rs @@ -12,20 +12,26 @@ enum Phase { Cardplay, } -#[function_component(Game)] -pub fn game() -> Html { +pub fn deal() -> card::Deal { let mut rng = rand::thread_rng(); let mut deal = card::deal(&mut rng); deal.sort(&SUIT_DISPLAY_ORDER, card::RankOrder::Descending); + 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())); +#[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> = use_state(|| None); + let contract: UseStateHandle, bridge_engine::Bidding)>> = + use_state(|| None); let on_contract = { let contract = contract.clone(); Callback::from(move |c| contract.set(Some(c))) @@ -38,22 +44,12 @@ pub fn game() -> Html { }; let shuffle = { - let north = north.clone(); - let west = west.clone(); - let south = south.clone(); - let east = east.clone(); + let dealt_cards = dealt_cards.clone(); let dealer = dealer.clone(); let contract = contract.clone(); Callback::from(move |_| { - let mut rng = rand::thread_rng(); - let mut deal = card::deal(&mut rng); - deal.sort(&SUIT_DISPLAY_ORDER, card::RankOrder::Descending); - north.set(deal.north.into_iter().collect()); - west.set(deal.west.into_iter().collect()); - south.set(deal.south.into_iter().collect()); - east.set(deal.east.into_iter().collect()); - + dealt_cards.set(deal()); dealer.set(dealer.next()); contract.set(None); }) @@ -77,16 +73,16 @@ pub fn game() -> Html { }
- +
- +
- +
- +
} diff --git a/webapp/src/components/hand.rs b/webapp/src/components/hand.rs index 85b4dd2..bb6e372 100644 --- a/webapp/src/components/hand.rs +++ b/webapp/src/components/hand.rs @@ -20,7 +20,7 @@ pub fn hand(props: &HandProps) -> Html { #[derive(Clone, Default, PartialEq, Properties)] pub struct HandProps { #[prop_or_default] - cards: Vec, + pub cards: Vec, } impl> FromIterator for HandProps { diff --git a/webapp/src/components/show_bid.rs b/webapp/src/components/show_bid.rs index b0c917e..2ab2d5c 100644 --- a/webapp/src/components/show_bid.rs +++ b/webapp/src/components/show_bid.rs @@ -1,10 +1,9 @@ -use crate::bridge_engine::{Bid, Bidding, Contract}; -use crate::components::bid_css_class; +use crate::bridge_engine::{Bidding, Contract}; use yew::prelude::*; #[derive(PartialEq, Properties, Clone)] pub struct ShowBidProps { - pub contract: Contract, + pub contract: Option, pub bidding: Bidding, } @@ -12,7 +11,12 @@ pub struct ShowBidProps { pub fn show_bid(props: &ShowBidProps) -> Html { html! { <> -

{ format!("{}", props.contract) }

+

{ + match props.contract { + None => "Passed".to_string(), + Some(c) => format!("{}", c), + } + }

} } diff --git a/webapp/src/main.rs b/webapp/src/main.rs index cf5eb8e..8a1fccc 100644 --- a/webapp/src/main.rs +++ b/webapp/src/main.rs @@ -1,4 +1,3 @@ -use crate::card::Suit; #[allow(unused_imports)] use log::{debug, error, info, warn}; use yew::prelude::*; -- cgit v1.2.3