use std::collections::HashMap;
use crate::{cards::CardID, create_valid_identification, identifications::MutID};
use card_stack::NonEmptyInput;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct PlayerID(usize);
impl NonEmptyInput for PlayerID {}
impl PlayerID {
pub fn new(id: usize) -> Self {
PlayerID(id)
}
pub fn value(&self) -> usize {
self.0
}
fn next_player_id(&self, max_players: usize) -> Self {
PlayerID((self.0 + 1) % max_players)
}
}
impl std::fmt::Display for PlayerID {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
use crate as card_game;
create_valid_identification!(ValidPlayerID, PlayerID, with_copy);
impl From<ValidPlayerID<ActivePlayer>> for ValidPlayerID<()> {
fn from(valid_id: ValidPlayerID<ActivePlayer>) -> Self {
ValidPlayerID(valid_id.0, std::marker::PhantomData::default())
}
}
impl<F> ValidPlayerID<F> {
pub(crate) fn new(player_id: PlayerID) -> Self {
ValidPlayerID(player_id, std::marker::PhantomData::default())
}
}
impl ValidPlayerID<()> {
pub fn try_new<P>(
player_manager: &PlayerManager<P>,
player_id: PlayerID,
) -> Result<Self, PlayerDoesNotExist> {
if player_manager.players.contains_key(&player_id) {
Ok(ValidPlayerID(
player_id,
std::marker::PhantomData::default(),
))
} else {
Err(PlayerDoesNotExist(player_id))
}
}
}
#[derive(thiserror::Error, Debug)]
#[error("player {0} does not exist")]
pub struct PlayerDoesNotExist(PlayerID);
#[derive(Debug)]
pub struct ActivePlayer;
#[derive(Debug, Clone)]
pub struct PlayerManager<P> {
pub(crate) players: HashMap<PlayerID, P>,
}
impl<P> PlayerManager<P> {
pub fn new(players: HashMap<PlayerID, P>) -> Self {
PlayerManager { players }
}
pub fn player_count(&self) -> usize {
self.players.len()
}
pub fn players(&self) -> impl Iterator<Item = ValidPlayerID<()>> {
self.players
.keys()
.copied()
.map(|player_id| ValidPlayerID::new(player_id))
}
pub fn get_player(&self, player_id: PlayerID) -> Option<&P> {
self.players.get(&player_id)
}
pub fn get_player_mut(&mut self, player_id: MutID<PlayerID>) -> Option<&mut P> {
self.players.get_mut(player_id.id())
}
pub fn valid_player<F>(&self, valid_player_id: &ValidPlayerID<F>) -> &P {
self.get_player(valid_player_id.id()).unwrap()
}
pub fn valid_player_mut<F>(&mut self, valid_player_id: MutID<ValidPlayerID<F>>) -> &mut P {
self.players.get_mut(&valid_player_id.id().id()).unwrap()
}
}
pub struct PlayerIDBuilder {
next_player_id: usize,
}
impl PlayerIDBuilder {
pub(crate) fn new() -> Self {
PlayerIDBuilder { next_player_id: 0 }
}
pub fn generate_player_id(&mut self) -> PlayerID {
let player_id = PlayerID(self.next_player_id);
self.next_player_id += 1;
player_id
}
}