From d3fbefad9cf25786fb5f28f96eeceb65d0a8b35b Mon Sep 17 00:00:00 2001 From: Kjetil Orbekk Date: Sun, 1 Jan 2023 20:34:09 -0500 Subject: Split bridge_engine into a few separate modules --- protocol/src/core.rs | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 protocol/src/core.rs (limited to 'protocol/src/core.rs') diff --git a/protocol/src/core.rs b/protocol/src/core.rs new file mode 100644 index 0000000..7939fb2 --- /dev/null +++ b/protocol/src/core.rs @@ -0,0 +1,116 @@ +use rand::{prelude::Distribution, distributions::Standard, seq::SliceRandom}; +use strum::EnumCount; +use strum_macros::{EnumCount, FromRepr, EnumIter}; +use serde::{Serialize, Deserialize}; + +use crate::card::{Card, Suit, RankOrder, sort_cards, make_deck}; + +#[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(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] +pub struct Deal { + pub north: Vec, + pub west: Vec, + pub south: Vec, + pub east: Vec, +} + +impl Deal { + pub fn empty() -> Self { + Self { + 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 { + north, + west, + south, + east, + } + } +} -- cgit v1.2.3