summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKjetil Orbekk <kj@orbekk.com>2022-09-11 11:12:16 -0400
committerKjetil Orbekk <kj@orbekk.com>2022-09-11 11:12:16 -0400
commit3fb6f32a46b0cdfc59643bee255648e1ef401116 (patch)
tree8d96d1dadae5e82b92e6d1ee7f4203724eb08609
parent55a24a3b7d1b3fcc07f0bb8e53b00abf23e651b3 (diff)
Refactor passed contract into Option<Contract>
-rw-r--r--TODO.org5
-rw-r--r--webapp/src/bridge_engine.rs51
-rw-r--r--webapp/src/components/bidding.rs6
-rw-r--r--webapp/src/components/game.rs42
-rw-r--r--webapp/src/components/hand.rs2
-rw-r--r--webapp/src/components/show_bid.rs12
-rw-r--r--webapp/src/main.rs1
7 files changed, 56 insertions, 63 deletions
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<Raise>,
+ 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<Contract> {
+ match self.highest_bid() {
+ None => None,
+ Some(highest_bid) => Some(Contract {
+ highest_bid,
+ modifier: ContractModifier::None,
+ }),
+ }
+ }
+
pub fn bid(mut self, bid: Bid) -> Result<BiddingResult, anyhow::Error> {
// 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<Contract>, Bidding),
}
impl BiddingResult {
@@ -357,7 +357,7 @@ mod tests {
}
}
- fn as_contract(r: BiddingResult) -> Contract {
+ fn as_contract(r: BiddingResult) -> Option<Contract> {
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<Contract>, 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<Option<(Contract, bridge_engine::Bidding)>> = use_state(|| None);
+ let contract: UseStateHandle<Option<(Option<Contract>, 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 {
}
</div>
<div class="hand west">
- <Hand ..(*west).clone() />
+ <Hand ..{ dealt_cards.west.clone().into_iter().collect() }/>
</div>
<div class="hand north">
- <Hand ..(*north).clone() />
+ <Hand ..{ dealt_cards.north.clone().into_iter().collect() }/>
</div>
<div class="hand east">
- <Hand ..(*east).clone() />
+ <Hand ..{ dealt_cards.east.clone().into_iter().collect() }/>
</div>
<div class="hand south">
- <Hand ..(*south).clone() />
+ <Hand ..{ dealt_cards.south.clone().into_iter().collect() }/>
</div>
</>
}
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<CardProps>,
+ pub cards: Vec<CardProps>,
}
impl<C: Into<CardProps>> FromIterator<C> 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<Contract>,
pub bidding: Bidding,
}
@@ -12,7 +11,12 @@ pub struct ShowBidProps {
pub fn show_bid(props: &ShowBidProps) -> Html {
html! {
<>
- <p>{ format!("{}", props.contract) }</p>
+ <p>{
+ match props.contract {
+ None => "Passed".to_string(),
+ Some(c) => format!("{}", c),
+ }
+ }</p>
</>
}
}
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::*;