use rand::prelude::*;
use rand::rng;
use rand::seq::SliceRandom;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum Suit {
Clubs,
Diamonds,
Hearts,
Spades,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub enum Rank {
Ace,
Two,
Three,
Four,
Five,
Six,
Seven,
Eight,
Nine,
Ten,
Jack,
Queen,
King,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Card {
pub suit: Suit,
pub rank: Rank,
}
impl fmt::Display for Card {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let symbol = match (&self.rank, &self.suit) {
(Rank::Ace, Suit::Spades) => "🂡",
(Rank::Two, Suit::Spades) => "🂢",
(Rank::Three, Suit::Spades) => "🂣",
(Rank::Four, Suit::Spades) => "🂤",
(Rank::Five, Suit::Spades) => "🂥",
(Rank::Six, Suit::Spades) => "🂦",
(Rank::Seven, Suit::Spades) => "🂧",
(Rank::Eight, Suit::Spades) => "🂨",
(Rank::Nine, Suit::Spades) => "🂩",
(Rank::Ten, Suit::Spades) => "🂪",
(Rank::Jack, Suit::Spades) => "🂫",
(Rank::Queen, Suit::Spades) => "🂭",
(Rank::King, Suit::Spades) => "🂮",
(Rank::Ace, Suit::Hearts) => "🂱",
(Rank::Two, Suit::Hearts) => "🂲",
(Rank::Three, Suit::Hearts) => "🂳",
(Rank::Four, Suit::Hearts) => "🂴",
(Rank::Five, Suit::Hearts) => "🂵",
(Rank::Six, Suit::Hearts) => "🂶",
(Rank::Seven, Suit::Hearts) => "🂷",
(Rank::Eight, Suit::Hearts) => "🂸",
(Rank::Nine, Suit::Hearts) => "🂹",
(Rank::Ten, Suit::Hearts) => "🂺",
(Rank::Jack, Suit::Hearts) => "🂻",
(Rank::Queen, Suit::Hearts) => "🂽",
(Rank::King, Suit::Hearts) => "🂾",
(Rank::Ace, Suit::Diamonds) => "🃁",
(Rank::Two, Suit::Diamonds) => "🃂",
(Rank::Three, Suit::Diamonds) => "🃃",
(Rank::Four, Suit::Diamonds) => "🃄",
(Rank::Five, Suit::Diamonds) => "🃅",
(Rank::Six, Suit::Diamonds) => "🃆",
(Rank::Seven, Suit::Diamonds) => "🃇",
(Rank::Eight, Suit::Diamonds) => "🃈",
(Rank::Nine, Suit::Diamonds) => "🃉",
(Rank::Ten, Suit::Diamonds) => "🃊",
(Rank::Jack, Suit::Diamonds) => "🃋",
(Rank::Queen, Suit::Diamonds) => "🃍",
(Rank::King, Suit::Diamonds) => "🃎",
(Rank::Ace, Suit::Clubs) => "🃑",
(Rank::Two, Suit::Clubs) => "🃒",
(Rank::Three, Suit::Clubs) => "🃓",
(Rank::Four, Suit::Clubs) => "🃔",
(Rank::Five, Suit::Clubs) => "🃕",
(Rank::Six, Suit::Clubs) => "🃖",
(Rank::Seven, Suit::Clubs) => "🃗",
(Rank::Eight, Suit::Clubs) => "🃘",
(Rank::Nine, Suit::Clubs) => "🃙",
(Rank::Ten, Suit::Clubs) => "🃚",
(Rank::Jack, Suit::Clubs) => "🃛",
(Rank::Queen, Suit::Clubs) => "🃝",
(Rank::King, Suit::Clubs) => "🃞",
};
write!(f, "{symbol} ")
}
}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct Shoe {
deck_count: u8,
reshuffle_threshold: f32,
cards: Vec<Card>,
}
impl Shoe {
pub fn new(deck_count: u8, reshuffle_threshold: f32) -> Self {
Self {
deck_count,
reshuffle_threshold,
cards: Self::build_cards(deck_count),
}
}
pub fn draw_card(&mut self) -> Card {
if self.cards.len()
< ((self.deck_count as usize * 52) as f32 * self.reshuffle_threshold) as usize
{
self.cards = Self::build_cards(self.deck_count);
}
self.cards.pop().unwrap()
}
pub fn shuffle(&mut self) {
self.cards = Self::build_cards(self.deck_count);
}
fn build_cards(deck_count: u8) -> Vec<Card> {
let deck = deck();
let mut shoe = vec![];
for _i in 1..deck_count {
let mut next_deck = deck.clone();
shoe.append(&mut next_deck);
}
let mut rng = rng();
shoe.shuffle(&mut rng);
shoe
}
}
pub fn deck() -> Vec<Card> {
let suits = [Suit::Clubs, Suit::Diamonds, Suit::Hearts, Suit::Spades];
let ranks = [
Rank::Ace,
Rank::Two,
Rank::Three,
Rank::Four,
Rank::Five,
Rank::Six,
Rank::Seven,
Rank::Eight,
Rank::Nine,
Rank::Ten,
Rank::Jack,
Rank::Queen,
Rank::King,
];
let mut cards = vec![];
for suit in suits {
for rank in &ranks {
let card = Card {
suit: suit.clone(),
rank: rank.clone(),
};
cards.push(card);
}
}
let mut rng = rng();
cards.shuffle(&mut rng);
cards
}
pub fn random_card() -> Card {
let suits = [Suit::Clubs, Suit::Diamonds, Suit::Hearts, Suit::Spades];
let ranks = [
Rank::Ace,
Rank::Two,
Rank::Three,
Rank::Four,
Rank::Five,
Rank::Six,
Rank::Seven,
Rank::Eight,
Rank::Nine,
Rank::Ten,
Rank::Jack,
Rank::Queen,
Rank::King,
];
let mut rng = rng();
let suit = suits.choose(&mut rng).unwrap().clone();
let rank = ranks.choose(&mut rng).unwrap().clone();
Card { suit, rank }
}