use rand::{distributions::Standard, prelude::Distribution, seq::SliceRandom, random}; use serde::{Deserialize, Serialize}; use strum::EnumCount; use strum_macros::{EnumCount, EnumIter, FromRepr}; use crate::card::{make_deck, sort_cards, Card, RankOrder, Suit}; #[derive( PartialEq, Eq, Clone, Copy, Debug, FromRepr, EnumCount, Serialize, Deserialize, EnumIter, )] #[repr(u8)] pub enum Player { West = 0, North, East, South, } impl Player { pub fn next(&self) -> Self { self.many_next(1) } pub fn many_next(self, i: usize) -> Self { Player::from_repr(((self as usize + i) % Player::COUNT) as u8).unwrap() } pub fn short_str(&self) -> &str { match self { Self::West => "W", Self::North => "N", Self::East => "E", Self::South => "W", } } pub fn get_cards<'a>(&self, deal: &'a Deal) -> &'a Vec { match self { Self::West => &deal.west, Self::North => &deal.north, Self::East => &deal.east, Self::South => &deal.south, } } pub fn get_cards_mut<'a>(&self, deal: &'a mut Deal) -> &'a mut Vec { match self { Self::West => &mut deal.west, Self::North => &mut deal.north, Self::East => &mut deal.east, Self::South => &mut deal.south, } } } impl Distribution for Standard { fn sample(&self, rng: &mut R) -> Player { let min = Player::West as u8; let max = Player::South as u8; let v = rng.gen_range(min..=max); Player::from_repr(v).unwrap() } } #[derive( PartialEq, Eq, Clone, Copy, Debug, FromRepr, EnumCount, Serialize, Deserialize, EnumIter, )] #[repr(u8)] pub enum Vulnerability { None, NorthSouth, EastWest, All, } impl Distribution for Standard { fn sample(&self, rng: &mut R) -> Vulnerability { let min = Vulnerability::None as u8; let max = Vulnerability::All as u8; let v = rng.gen_range(min..=max); Vulnerability::from_repr(v).unwrap() } } #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] pub struct Deal { pub dealer: Player, pub vulnerability: Vulnerability, pub north: Vec, pub west: Vec, pub south: Vec, pub east: Vec, } impl Deal { pub fn empty(dealer: Player, vulnerability: Vulnerability) -> Self { Self { dealer, vulnerability, north: Vec::with_capacity(13), west: Vec::with_capacity(13), south: Vec::with_capacity(13), east: Vec::with_capacity(13), } } pub fn sort(&mut self, suits: &[Suit; 4], ord: RankOrder) { sort_cards(suits, ord, self.north.as_mut_slice()); sort_cards(suits, ord, self.west.as_mut_slice()); sort_cards(suits, ord, self.south.as_mut_slice()); sort_cards(suits, ord, self.east.as_mut_slice()); } } impl Distribution for Standard { fn sample(&self, rng: &mut R) -> Deal { let mut deck = make_deck(); deck.shuffle(rng); let mut deck = deck.iter(); let north = deck.by_ref().take(13).cloned().collect(); let west = deck.by_ref().take(13).cloned().collect(); let south = deck.by_ref().take(13).cloned().collect(); let east = deck.by_ref().take(13).cloned().collect(); Deal { dealer: random(), vulnerability: random(), north, west, south, east, } } }