diff options
author | Kjetil Orbekk <kj@orbekk.com> | 2023-01-01 20:34:09 -0500 |
---|---|---|
committer | Kjetil Orbekk <kj@orbekk.com> | 2023-01-01 20:34:09 -0500 |
commit | d3fbefad9cf25786fb5f28f96eeceb65d0a8b35b (patch) | |
tree | 156a23b5c04b93d746ecf592971aefbcc127cfd2 /protocol/src/core.rs | |
parent | bb2ed3a2926384df063e476d10613fa310cd7ffa (diff) |
Split bridge_engine into a few separate modules
Diffstat (limited to 'protocol/src/core.rs')
-rw-r--r-- | protocol/src/core.rs | 116 |
1 files changed, 116 insertions, 0 deletions
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<Card> { + 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<Card> { + match self { + Self::West => &mut deal.west, + Self::North => &mut deal.north, + Self::East => &mut deal.east, + Self::South => &mut deal.south, + } + } +} + +impl Distribution<Player> for Standard { + fn sample<R: rand::Rng + ?Sized>(&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<Card>, + pub west: Vec<Card>, + pub south: Vec<Card>, + pub east: Vec<Card>, +} + +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<Deal> for Standard { + fn sample<R: rand::Rng + ?Sized>(&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, + } + } +} |