diff --git a/schafkopf-logic/.gitignore b/schafkopf-logic/.gitignore new file mode 100644 index 0000000..f2f9e58 --- /dev/null +++ b/schafkopf-logic/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock \ No newline at end of file diff --git a/schafkopf-logic/Cargo.toml b/schafkopf-logic/Cargo.toml new file mode 100644 index 0000000..30f55f3 --- /dev/null +++ b/schafkopf-logic/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "schafkopf-logic" +version = "0.1.0" +edition = "2024" + +[dependencies] +strum = "0.27" +strum_macros = "0.27" +rand = "0.9" \ No newline at end of file diff --git a/schafkopf-logic/src/deck/card.rs b/schafkopf-logic/src/deck/card.rs new file mode 100644 index 0000000..4f0a51c --- /dev/null +++ b/schafkopf-logic/src/deck/card.rs @@ -0,0 +1,15 @@ +use std::fmt; + +use crate::deck::{Suit, Rank}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct Card { + pub suit: Suit, + pub rank: Rank, +} + +impl fmt::Display for Card { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{} {}", self.rank, self.suit) + } +} \ No newline at end of file diff --git a/schafkopf-logic/src/deck/mod.rs b/schafkopf-logic/src/deck/mod.rs new file mode 100644 index 0000000..abf6ce6 --- /dev/null +++ b/schafkopf-logic/src/deck/mod.rs @@ -0,0 +1,50 @@ +mod rank; +pub use rank::Rank; + +mod suit; +pub use suit::Suit; + +mod card; +pub use card::Card; + +use strum::IntoEnumIterator; + +use rand::seq::SliceRandom; +use rand::rng; + +pub struct Deck { + cards: Vec, +} + +impl Deck { + pub fn new() -> Self { + let cards = Suit::iter() + .flat_map(|suit| Rank::iter().map(move |rank| Card { suit, rank })) + .collect(); + Self { cards } + } + + pub fn draw(&mut self) -> Option { + self.cards.pop() + } + + pub fn shuffle(&mut self) { + self.cards.shuffle(&mut rng()); + } + + pub fn deal_4x8(&mut self) -> Option<[Vec; 4]> { + if self.cards.len() < 32 { return None; } + let mut hands = [Vec::with_capacity(8), Vec::with_capacity(8), + Vec::with_capacity(8), Vec::with_capacity(8)]; + for _ in 0..8 { + for h in 0..4 { + hands[h].push(self.draw()?); + } + } + Some(hands) + } + + pub fn iter(&self) -> impl Iterator { + self.cards.iter() + } +} \ No newline at end of file diff --git a/schafkopf-logic/src/deck/rank.rs b/schafkopf-logic/src/deck/rank.rs new file mode 100644 index 0000000..1dcb25b --- /dev/null +++ b/schafkopf-logic/src/deck/rank.rs @@ -0,0 +1,43 @@ +use std::fmt; +use strum_macros::EnumIter; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, EnumIter)] +pub enum Rank { + Ass, + Zehn, + Koenig, + Ober, + Unter, + Neun, + Acht, + Sieben, +} + +impl Rank { + pub fn points(&self) -> u8 { + match self { + Rank::Ass => 11, + Rank::Zehn => 10, + Rank::Koenig => 4, + Rank::Ober => 3, + Rank::Unter => 3, + _ => 0 + } + } +} + +impl fmt::Display for Rank { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let name = match self { + Rank::Ass => "Ass", + Rank::Zehn => "Zehn", + Rank::Koenig => "König", + Rank::Ober => "Ober", + Rank::Unter => "Unter", + Rank::Neun => "Neun", + Rank::Acht => "Acht", + Rank::Sieben => "Sieben", + }; + write!(f, "{}", name) + } +} \ No newline at end of file diff --git a/schafkopf-logic/src/deck/suit.rs b/schafkopf-logic/src/deck/suit.rs new file mode 100644 index 0000000..dac890a --- /dev/null +++ b/schafkopf-logic/src/deck/suit.rs @@ -0,0 +1,22 @@ +use std::fmt; +use strum_macros::EnumIter; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, EnumIter)] +pub enum Suit { + Eichel, + Gras, + Herz, + Schell, +} + +impl fmt::Display for Suit { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let name = match self { + Suit::Eichel => "Eichel", + Suit::Gras => "Gras", + Suit::Herz => "Herz", + Suit::Schell => "Schell", + }; + write!(f, "{}", name) + } +} \ No newline at end of file diff --git a/schafkopf-logic/src/main.rs b/schafkopf-logic/src/main.rs new file mode 100644 index 0000000..30fa20b --- /dev/null +++ b/schafkopf-logic/src/main.rs @@ -0,0 +1,29 @@ +mod deck; +use deck::Deck; + +fn main() { + let mut deck = Deck::new(); + deck.shuffle(); + + let [mut hand1, mut hand2, mut hand3, mut hand4] = deck.deal_4x8().unwrap(); + + println!("Player 1 has:"); + for card in hand1.iter() { + println!("{}", card) + } + + println!("\nPlayer 2 has:"); + for card in hand2.iter() { + println!("{}", card) + } + + println!("\nPlayer 3 has:"); + for card in hand3.iter() { + println!("{}", card) + } + + println!("\nPlayer 4 has:"); + for card in hand4.iter() { + println!("{}", card) + } +}