use rand::thread_rng;
use rand::seq::SliceRandom;
use std::fmt;
use std::cmp::Ordering;
use serde::{Serialize, Deserialize};
#[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "server", derive(oasgen::OaSchema))]
pub enum Suit {
Blank = 0,
Club = 1,
Diamond = 2,
Heart = 3,
Spade = 4,
}
impl fmt::Debug for Suit {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Suit::Blank => write!(f, " "),
Suit::Club => write!(f, "\u{2667}"),
Suit::Diamond => write!(f, "\u{2662}"),
Suit::Heart => write!(f, "\u{2661}"),
Suit::Spade => write!(f, "\u{2664}"),
}
}
}
#[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "server", derive(oasgen::OaSchema))]
pub enum Rank {
Blank = 0,
Two = 2,
Three = 3,
Four = 4,
Five = 5,
Six = 6,
Seven = 7,
Eight = 8,
Nine = 9,
Ten = 10,
Jack = 11,
Queen = 12,
King = 13,
Ace = 14
}
impl fmt::Debug for Rank {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Rank::Blank => write!(f, " "),
Rank::Two => write!(f, "2"),
Rank::Three => write!(f, "3"),
Rank::Four => write!(f, "4"),
Rank::Five => write!(f, "5"),
Rank::Six => write!(f, "6"),
Rank::Seven => write!(f, "7"),
Rank::Eight => write!(f, "8"),
Rank::Nine => write!(f, "9"),
Rank::Ten => write!(f, "10"),
Rank::Jack => write!(f, "J"),
Rank::Queen => write!(f, "Q"),
Rank::King => write!(f, "K"),
Rank::Ace => write!(f, "A"),
}
}
}
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "server", derive(oasgen::OaSchema))]
pub struct Card {
pub suit: Suit,
pub rank: Rank
}
impl fmt::Debug for Card {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?} {:?}",self.suit , self.rank)
}
}
impl Ord for Card {
fn cmp(&self, other: &Card) -> Ordering {
((self.suit as u64) * 15 + (self.rank as u64)).cmp(&(((other.suit as u64)* 15) + (other.rank as u64)))
}
}
impl PartialOrd for Card {
fn partial_cmp(&self, other: &Card) -> Option<Ordering> {
Some(((self.suit as u64) * 15 + (self.rank as u64)).cmp(&(((other.suit as u64)* 15) + (other.rank as u64))))
}
}
pub fn get_trick_winner(index: usize, others: &[Card ; 4]) -> usize {
let mut winning_index = index;
let mut max_card = &others[index];
for i in 0..4 {
let other = &others[i];
if other.suit == max_card.suit {
if other.rank as u8 > max_card.rank as u8 {
max_card = &other;
winning_index = i;
}
} else if other.suit == Suit::Spade {
max_card = &other;
winning_index = i;
}
}
return winning_index;
}
pub fn new_deck() -> Vec<Card> {
let ranks: Vec<Rank> = vec![
Rank::Two,
Rank::Three,
Rank::Four,
Rank::Five,
Rank::Six,
Rank::Seven,
Rank::Eight,
Rank::Nine,
Rank::Ten,
Rank::Jack,
Rank::Queen,
Rank::King,
Rank::Ace
];
let suits: Vec<Suit> = vec![
Suit::Club,
Suit::Diamond,
Suit::Heart,
Suit::Spade,
];
let mut cards = Vec::new();
for s in &suits {
for r in &ranks {
cards.push(Card {suit:s.clone(), rank:r.clone()});
}
}
shuffle(&mut cards);
return cards;
}
pub fn new_pot() -> [Card; 4] {
[
Card { suit: Suit::Blank, rank: Rank::Blank},
Card { suit: Suit::Blank, rank: Rank::Blank},
Card { suit: Suit::Blank, rank: Rank::Blank},
Card { suit: Suit::Blank, rank: Rank::Blank}
]
}
pub fn shuffle(cards: &mut Vec<Card>) {
let mut rng = thread_rng();
cards.shuffle(&mut rng);
}
pub fn deal_four_players(cards: &mut Vec<Card>) -> Vec<Vec<Card>> {
assert_eq!(cards.len(), 52);
shuffle(cards);
let mut hands = vec![vec![], vec![], vec![], vec![]];
let mut i = 0;
while cards.len() > 0 {
hands[i].push(cards.pop().unwrap());
i = (i + 1) % 4;
}
return hands;
}