Add random player

This commit is contained in:
hal8174 2025-07-11 17:22:04 +02:00
parent 7d95a71c5d
commit 027811aa65
Signed by: hal8174
SSH key fingerprint: SHA256:JwuqS+eVfISfKr+DkDQ6NWAbGd1jFAHkPpCM1yCnlTs
3 changed files with 75 additions and 13 deletions

View file

@ -2,13 +2,17 @@ use rand::{seq::SliceRandom, Rng};
pub trait Player {
fn select_card(
&self,
&mut self,
hand: &[Card],
stack: &[Card],
additional_information: &AdditionalInformation,
) -> Card;
}
pub trait PlayerBuilder: Sync {
fn build(&self) -> Box<dyn Player>;
}
#[derive(Debug)]
pub struct AdditionalInformation {}
@ -85,7 +89,16 @@ pub fn playeble(card: Card, hand: &[Card], stack_color: Option<Color>) -> bool {
}
}
pub fn herzen(player: &[Box<dyn Player>], starting_player: usize, rng: &mut impl Rng) -> Vec<u8> {
pub fn herzen(
player_builders: &[Box<dyn PlayerBuilder>],
starting_player: usize,
rng: &mut impl Rng,
) -> Vec<u8> {
let mut player = player_builders
.iter()
.map(|p| p.build())
.collect::<Vec<_>>();
let mut full_deck = (1..=8)
.flat_map(|u| {
[

View file

@ -1,4 +1,4 @@
use game::Player;
use game::PlayerBuilder;
use rand::{rngs::SmallRng, SeedableRng};
mod game;
@ -122,13 +122,10 @@ mod player;
// }
fn main() {
let player: Vec<Box<dyn Player>> = vec![
let player: Vec<Box<dyn PlayerBuilder>> = vec![
Box::new(player::highest::Highest {}),
Box::new(player::highest::Highest {}),
Box::new(player::highest::Highest {}),
Box::new(player::highest::Highest {}),
Box::new(player::highest::Highest {}),
Box::new(player::cli::Cli {}),
Box::new(player::random::Random { seed: 0 }),
// Box::new(player::cli::Cli {}),
];
let mut rng = SmallRng::from_entropy();

View file

@ -1,12 +1,18 @@
pub mod cli {
use crate::game::{playeble, Player};
use crate::game::{playeble, Player, PlayerBuilder};
pub struct Cli {}
impl PlayerBuilder for Cli {
fn build(&self) -> Box<dyn Player> {
Box::new(Cli {})
}
}
impl Player for Cli {
fn select_card(
&self,
&mut self,
hand: &[crate::game::Card],
stack: &[crate::game::Card],
additional_information: &crate::game::AdditionalInformation,
@ -36,13 +42,19 @@ pub mod cli {
pub mod highest {
use std::cmp::Reverse;
use crate::game::{playeble, Player};
use crate::game::{playeble, Player, PlayerBuilder};
pub struct Highest {}
impl PlayerBuilder for Highest {
fn build(&self) -> Box<dyn Player> {
Box::new(Highest {})
}
}
impl Player for Highest {
fn select_card(
&self,
&mut self,
hand: &[crate::game::Card],
stack: &[crate::game::Card],
additional_information: &crate::game::AdditionalInformation,
@ -58,3 +70,43 @@ pub mod highest {
}
}
}
pub mod random {
use rand::{rngs::SmallRng, seq::SliceRandom, SeedableRng};
use crate::game::{playeble, Player, PlayerBuilder};
pub struct Random {
pub seed: u64,
}
impl PlayerBuilder for Random {
fn build(&self) -> Box<dyn Player> {
Box::new(RandomPlayer {
rng: SmallRng::seed_from_u64(self.seed),
})
}
}
struct RandomPlayer {
rng: SmallRng,
}
impl Player for RandomPlayer {
fn select_card(
&mut self,
hand: &[crate::game::Card],
stack: &[crate::game::Card],
additional_information: &crate::game::AdditionalInformation,
) -> crate::game::Card {
let _ = additional_information;
let mut h = hand.to_vec();
h.sort();
h.retain(|&c| playeble(c, hand, stack.first().map(|d| d.color)));
*h.choose(&mut self.rng).unwrap()
}
}
}