use std::collections::{BTreeMap, BTreeSet};
use std::hash::Hash;
use ordered_float::NotNan;
use rand_chacha::ChaCha8Rng;
use crate::{AgentId, Behavior, Edges, IdleTask, MCTSConfiguration, Node, StateDiffRef, Task};
pub type AgentValue = NotNan<f32>;
pub trait Domain: Sized + 'static {
type State: std::fmt::Debug + Sized;
type Diff: std::fmt::Debug + Default + Clone + Hash + Eq;
type DisplayAction: std::fmt::Debug + Default;
fn list_behaviors() -> &'static [&'static dyn Behavior<Self>];
fn get_current_value(tick: u64, state_diff: StateDiffRef<Self>, agent: AgentId) -> AgentValue;
fn update_visible_agents(
start_tick: u64,
tick: u64,
state_diff: StateDiffRef<Self>,
agent: AgentId,
agents: &mut BTreeSet<AgentId>,
);
fn get_tasks(
tick: u64,
state_diff: StateDiffRef<'_, Self>,
agent: AgentId,
) -> Vec<Box<dyn Task<Self>>> {
let mut actions = Vec::new();
Self::list_behaviors()
.iter()
.for_each(|behavior| behavior.add_tasks(tick, state_diff, agent, &mut actions));
actions.dedup();
actions
}
fn get_state_description(_state_diff: StateDiffRef<Self>) -> String {
String::new()
}
fn get_new_agents(_state_diff: StateDiffRef<Self>) -> Vec<AgentId> {
vec![]
}
fn display_action_task_idle() -> Self::DisplayAction {
Default::default()
}
fn display_action_task_planning() -> Self::DisplayAction {
Default::default()
}
}
pub trait StateValueEstimator<D: Domain>: Send {
#[allow(clippy::too_many_arguments)]
fn estimate(
&mut self,
rnd: &mut ChaCha8Rng,
config: &MCTSConfiguration,
initial_state: &D::State,
start_tick: u64,
node: &Node<D>,
edges: &Edges<D>,
depth: u32,
) -> Option<BTreeMap<AgentId, f32>>;
}
pub trait DomainWithPlanningTask: Domain {
fn fallback_task(_agent: AgentId) -> Box<dyn Task<Self>> {
Box::new(IdleTask)
}
}