summaryrefslogtreecommitdiff
path: root/webapp
diff options
context:
space:
mode:
authorKjetil Orbekk <kj@orbekk.com>2022-09-04 16:36:35 -0400
committerKjetil Orbekk <kj@orbekk.com>2022-09-04 16:38:42 -0400
commit2f310f54829cb368f407373eb95cd4512992ba9e (patch)
tree8f17d97cf84b30fce1d5703de4b7f6d7ba54acfa /webapp
parentca37b1757a92e7b85fc434474642d1506dcd86a3 (diff)
Extract card logic into a separate file
Diffstat (limited to 'webapp')
-rw-r--r--webapp/Cargo.toml3
-rw-r--r--webapp/src/card.rs113
-rw-r--r--webapp/src/main.rs95
3 files changed, 129 insertions, 82 deletions
diff --git a/webapp/Cargo.toml b/webapp/Cargo.toml
index 9abb154..c179533 100644
--- a/webapp/Cargo.toml
+++ b/webapp/Cargo.toml
@@ -8,3 +8,6 @@ yew = "0.19"
console_error_panic_hook = "0.1"
wasm-logger = "0.2"
log = "0.4"
+strum = "0.24"
+strum_macros = "0.24"
+rand = "0.8"
diff --git a/webapp/src/card.rs b/webapp/src/card.rs
new file mode 100644
index 0000000..071f2d1
--- /dev/null
+++ b/webapp/src/card.rs
@@ -0,0 +1,113 @@
+use rand::prelude::SliceRandom;
+use rand::Rng;
+use std::fmt;
+use strum::IntoEnumIterator;
+use strum_macros::EnumIter;
+
+#[derive(PartialOrd, Ord, PartialEq, Eq, Clone, Copy, EnumIter)]
+pub enum Suit {
+ Club,
+ Diamond,
+ Heart,
+ Spade,
+}
+
+#[derive(PartialOrd, Ord, PartialEq, Eq, Clone, Copy, EnumIter)]
+pub enum Rank {
+ Two = 2,
+ Three,
+ Four,
+ Five,
+ Six,
+ Seven,
+ Eight,
+ Nine,
+ Ten,
+ Jack,
+ Queen,
+ King,
+ Ace,
+}
+
+impl fmt::Display for Suit {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
+ f.write_str(match self {
+ Suit::Club => "♣",
+ Suit::Diamond => "♢",
+ Suit::Heart => "♡",
+ Suit::Spade => "♠",
+ })
+ }
+}
+
+impl fmt::Debug for Suit {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
+ write!(f, "{}", self)
+ }
+}
+
+impl fmt::Display for Rank {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
+ f.write_str(match self {
+ Rank::Ace => "A",
+ Rank::King => "K",
+ Rank::Queen => "Q",
+ Rank::Jack => "J",
+ Rank::Ten => "10",
+ Rank::Nine => "9",
+ Rank::Eight => "8",
+ Rank::Seven => "7",
+ Rank::Six => "6",
+ Rank::Five => "5",
+ Rank::Four => "4",
+ Rank::Three => "3",
+ Rank::Two => "2",
+ })
+ }
+}
+
+impl fmt::Debug for Rank {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
+ write!(f, "{}", self)
+ }
+}
+
+#[derive(PartialEq, Eq, Clone, Copy)]
+pub struct Card(Suit, Rank);
+
+impl fmt::Display for Card {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
+ let Card(suit, rank) = self;
+ write!(f, "{}{}", suit, rank)
+ }
+}
+
+impl fmt::Debug for Card {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
+ write!(f, "{}", self)
+ }
+}
+
+fn make_deck() -> Vec<Card> {
+ let mut result = vec![];
+ for suit in Suit::iter() {
+ for rank in Rank::iter() {
+ result.push(Card(suit, rank));
+ }
+ }
+ result
+}
+
+pub fn shuffle_deck<R>(rng: &mut R) -> (Vec<Card>, Vec<Card>, Vec<Card>, Vec<Card>)
+where
+ R: Rng,
+{
+ let mut deck = make_deck();
+ deck.shuffle(rng);
+ let mut deck = deck.iter();
+ let n = deck.by_ref().take(13).cloned().collect();
+ let w = deck.by_ref().take(13).cloned().collect();
+ let s = deck.by_ref().take(13).cloned().collect();
+ let e = deck.by_ref().take(13).cloned().collect();
+ (n, w, s, e)
+}
diff --git a/webapp/src/main.rs b/webapp/src/main.rs
index 2d01713..ed84935 100644
--- a/webapp/src/main.rs
+++ b/webapp/src/main.rs
@@ -1,7 +1,8 @@
+use crate::card::{Rank, Suit};
#[allow(unused_imports)]
use log::{debug, error, info, warn};
-use std::fmt;
use yew::prelude::*;
+pub mod card;
fn main() {
std::panic::set_hook(Box::new(console_error_panic_hook::hook));
@@ -63,6 +64,15 @@ pub fn hand(props: &HandProps) -> Html {
}
}
+pub fn suit_css_class(suit: Suit) -> &'static str {
+ match suit {
+ Suit::Club => "suit-club",
+ Suit::Diamond => "suit-diamond",
+ Suit::Heart => "suit-heart",
+ Suit::Spade => "suit-spade",
+ }
+}
+
#[derive(Clone, Default, PartialEq, Properties)]
pub struct HandProps {
#[prop_or_default]
@@ -70,10 +80,10 @@ pub struct HandProps {
}
#[function_component(Card)]
-pub fn card(props: &CardProps) -> Html {
+pub fn wcard(props: &CardProps) -> Html {
html! {
<div class="card">
- <div class={ props.suit.css_class() }>
+ <div class={ suit_css_class(props.suit) }>
{ props.rank }
</div>
</div>
@@ -85,82 +95,3 @@ pub struct CardProps {
suit: Suit,
rank: Rank,
}
-
-#[derive(PartialOrd, Ord, PartialEq, Eq, Clone, Copy)]
-pub enum Suit {
- Club,
- Diamond,
- Heart,
- Spade,
-}
-
-#[derive(PartialOrd, Ord, PartialEq, Eq, Clone, Copy)]
-pub enum Rank {
- Two = 2,
- Three,
- Four,
- Five,
- Six,
- Seven,
- Eight,
- Nine,
- Ten,
- Jack,
- Queen,
- King,
- Ace,
-}
-
-impl Suit {
- pub fn css_class(&self) -> &'static str {
- match self {
- Suit::Club => "suit-club",
- Suit::Diamond => "suit-diamond",
- Suit::Heart => "suit-heart",
- Suit::Spade => "suit-spade",
- }
- }
-}
-
-impl fmt::Display for Suit {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
- f.write_str(match self {
- Suit::Club => "♣",
- Suit::Diamond => "♢",
- Suit::Heart => "♡",
- Suit::Spade => "♠",
- })
- }
-}
-
-impl fmt::Debug for Suit {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
- write!(f, "{}", self)
- }
-}
-
-impl fmt::Display for Rank {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
- f.write_str(match self {
- Rank::Ace => "A",
- Rank::King => "K",
- Rank::Queen => "Q",
- Rank::Jack => "J",
- Rank::Ten => "10",
- Rank::Nine => "9",
- Rank::Eight => "8",
- Rank::Seven => "7",
- Rank::Six => "6",
- Rank::Five => "5",
- Rank::Four => "4",
- Rank::Three => "3",
- Rank::Two => "2",
- })
- }
-}
-
-impl fmt::Debug for Rank {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
- write!(f, "{}", self)
- }
-}