summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKjetil Orbekk <kj@orbekk.com>2022-09-10 14:49:38 -0400
committerKjetil Orbekk <kj@orbekk.com>2022-09-10 14:49:38 -0400
commit55a24a3b7d1b3fcc07f0bb8e53b00abf23e651b3 (patch)
treee85911ccc1eca8c820d7b4f40c9e3b36aa121034
parent5ad23c12d718e5b4b6f9076ef2d29de5addd40fc (diff)
Add nav bar with context
-rw-r--r--webapp/src/bridge_engine.rs55
-rw-r--r--webapp/src/components.rs2
-rw-r--r--webapp/src/components/bidding.rs4
-rw-r--r--webapp/src/components/game.rs28
-rw-r--r--webapp/src/components/show_bid.rs18
-rw-r--r--webapp/src/default.css26
6 files changed, 120 insertions, 13 deletions
diff --git a/webapp/src/bridge_engine.rs b/webapp/src/bridge_engine.rs
index fd52c33..2161a53 100644
--- a/webapp/src/bridge_engine.rs
+++ b/webapp/src/bridge_engine.rs
@@ -243,12 +243,31 @@ pub enum ContractModifier {
Redoubled,
}
+impl fmt::Display for ContractModifier {
+ fn fmt(&self, f: &mut fmt::Formatter) -> std::result::Result<(), std::fmt::Error> {
+ match self {
+ ContractModifier::None => Ok(()),
+ ContractModifier::Doubled => write!(f, "x"),
+ ContractModifier::Redoubled => write!(f, "xx"),
+ }
+ }
+}
+
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub struct Contract {
highest_bid: Option<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),
+ }
+ }
+}
+
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Bidding {
pub dealer: Player,
@@ -389,6 +408,42 @@ mod tests {
}
#[test]
+ fn fmt_contract() {
+ assert_eq!(
+ format!(
+ "{}",
+ Contract {
+ highest_bid: None,
+ modifier: ContractModifier::None
+ }
+ ),
+ "Passed"
+ );
+
+ assert_eq!(
+ format!(
+ "{}",
+ Contract {
+ highest_bid: Some("1♥".parse().unwrap()),
+ modifier: ContractModifier::None
+ }
+ ),
+ "1♡"
+ );
+
+ assert_eq!(
+ format!(
+ "{}",
+ Contract {
+ highest_bid: Some("1♥".parse().unwrap()),
+ modifier: ContractModifier::Doubled
+ }
+ ),
+ "1♡x"
+ );
+ }
+
+ #[test]
fn bid_ord() {
let bid = |s| Raise::from_str(s).unwrap();
assert!(bid("2♦") < bid("3♦"));
diff --git a/webapp/src/components.rs b/webapp/src/components.rs
index 6d9a5ec..5deedb5 100644
--- a/webapp/src/components.rs
+++ b/webapp/src/components.rs
@@ -5,12 +5,14 @@ mod hand;
mod bidding_table;
mod bidding_box;
mod bidding;
+mod show_bid;
mod game;
pub use self::card::*;
pub use self::bidding_box::*;
pub use self::bidding_table::*;
pub use self::bidding::*;
+pub use self::show_bid::*;
pub use self::game::*;
pub use self::hand::*;
diff --git a/webapp/src/components/bidding.rs b/webapp/src/components/bidding.rs
index 26a4426..d142dec 100644
--- a/webapp/src/components/bidding.rs
+++ b/webapp/src/components/bidding.rs
@@ -46,13 +46,13 @@ pub fn bidding(props: &BiddingProperties) -> Html {
html! {
<>
- <p>{ "Bidding table" }</p>
- <BiddingTable bidding={ (*bidding).clone() } />
<p>{ "Bidding box" }</p>
<BiddingBox
current_bid={ bidding.highest_bid().clone() }
{ on_bid }
/>
+ <p>{ "Bidding table" }</p>
+ <BiddingTable bidding={ (*bidding).clone() } />
</>
}
}
diff --git a/webapp/src/components/game.rs b/webapp/src/components/game.rs
index 33fb5b7..0f25fc3 100644
--- a/webapp/src/components/game.rs
+++ b/webapp/src/components/game.rs
@@ -1,11 +1,17 @@
use crate::bridge_engine::{self, Contract, Player};
use crate::card;
use crate::card::Suit;
-use crate::components::{Bidding, Hand, HandProps};
+use crate::components::{Bidding, Hand, HandProps, ShowBid};
use yew::prelude::*;
pub const SUIT_DISPLAY_ORDER: [Suit; 4] = [Suit::Diamond, Suit::Club, Suit::Heart, Suit::Spade];
+#[derive(Debug)]
+enum Phase {
+ Bidding,
+ Cardplay,
+}
+
#[function_component(Game)]
pub fn game() -> Html {
let mut rng = rand::thread_rng();
@@ -25,12 +31,19 @@ pub fn game() -> Html {
Callback::from(move |c| contract.set(Some(c)))
};
+ let phase = if contract.is_none() {
+ Phase::Bidding
+ } else {
+ Phase::Cardplay
+ };
+
let shuffle = {
let north = north.clone();
let west = west.clone();
let south = south.clone();
let east = east.clone();
let dealer = dealer.clone();
+ let contract = contract.clone();
Callback::from(move |_| {
let mut rng = rand::thread_rng();
@@ -42,19 +55,26 @@ pub fn game() -> Html {
east.set(deal.east.into_iter().collect());
dealer.set(dealer.next());
+ contract.set(None);
})
};
html! {
<>
+ <div class="nav">
+ if let Some((contract, bidding)) = &*contract {
+ <ShowBid contract={contract.clone()} bidding={bidding.clone()}/>
+ }
+ <p>{ format!("Phase: {:?}", phase) }</p>
+ <button onclick={shuffle}>{ "Shuffle" }</button>
+ </div>
<div class="center">
<p>{ format!("Dealer: {:?}", *dealer) }</p>
- if let Some((contract, bidding)) = &*contract {
- { format!("Got contract {:?}. Bidding was {:?}", contract, bidding) }
+ if let Some(_) = &*contract {
+ { "Let's play" }
} else {
<Bidding {on_contract} dealer={ *dealer } />
}
- <button onclick={shuffle}>{ "Shuffle" }</button>
</div>
<div class="hand west">
<Hand ..(*west).clone() />
diff --git a/webapp/src/components/show_bid.rs b/webapp/src/components/show_bid.rs
new file mode 100644
index 0000000..b0c917e
--- /dev/null
+++ b/webapp/src/components/show_bid.rs
@@ -0,0 +1,18 @@
+use crate::bridge_engine::{Bid, Bidding, Contract};
+use crate::components::bid_css_class;
+use yew::prelude::*;
+
+#[derive(PartialEq, Properties, Clone)]
+pub struct ShowBidProps {
+ pub contract: Contract,
+ pub bidding: Bidding,
+}
+
+#[function_component(ShowBid)]
+pub fn show_bid(props: &ShowBidProps) -> Html {
+html! {
+ <>
+ <p>{ format!("{}", props.contract) }</p>
+ </>
+}
+}
diff --git a/webapp/src/default.css b/webapp/src/default.css
index be10692..2dc6a3d 100644
--- a/webapp/src/default.css
+++ b/webapp/src/default.css
@@ -12,15 +12,27 @@ body {
.app {
display: grid;
- grid-template-areas: ". north ."
- "west center east"
- ". south .";
- grid-template-rows: 100px 1fr 100px;
- grid-template-columns: 100px 1fr 100px;
+ grid-template-areas: "north north north nav"
+ "west center east nav"
+ "south south south nav";
+ grid-template-rows: 10vw 1fr 10vw;
+ grid-template-columns: 10vw 1fr 10vw 10vw;
width: 100vw;
height: 100vh;
}
+.nav {
+ grid-area: nav;
+ display: grid;
+ background-color: #ccc;
+ align-content: start;
+}
+
+.nav p, .nav div {
+ background-color: #edc;
+ margin-bottom: 1vw;
+}
+
.west {
grid-area: west;
/* transform: rotate(90deg); */
@@ -61,8 +73,8 @@ body {
}
.card {
- min-width: 50px;
- min-height: 50px;
+ min-width: 30px;
+ min-height: 20px;
border-radius: 5px;
border: 2px solid #444;
transition: 0.1s;