use std::collections::{HashMap, HashSet};
use std::fmt::Debug;
use std::hash::Hash;
use crate::payoffs::Payoffs;
pub trait State<G: Game>: Debug + Eq + Clone + Hash + Sized + Sync + Send {
fn current_players(&self) -> HashSet<G::Player>;
fn is_over(&self) -> bool;
fn moves(&self, player: &G::Player) -> G::MoveIterator<'_>;
fn next(&self, moves: &HashMap<G::Player, G::Move>) -> Option<Self>;
fn payoffs(&self) -> Payoffs<G>;
}
pub trait Game: Clone + Default + Sized {
fn name() -> String;
type Player: Debug + PartialEq + Eq + PartialOrd + Ord + Hash + Clone;
type Move: Debug + PartialEq + Eq + Hash + Clone;
type MoveIterator<'l>: Iterator<Item=Self::Move>;
type State: State<Self>;
type Config: Debug + Eq + Hash + Clone + Send;
fn new(config: &Self::Config) -> Self;
fn players(&self) -> HashSet<Self::Player>;
fn start(&self) -> Self::State;
}