npc_engine_core/
domain.rs1use std::collections::{BTreeMap, BTreeSet};
7use std::hash::Hash;
8
9use ordered_float::NotNan;
10use rand_chacha::ChaCha8Rng;
11
12use crate::{AgentId, Behavior, Edges, IdleTask, MCTSConfiguration, Node, StateDiffRef, Task};
13
14pub type AgentValue = NotNan<f32>;
16
17pub trait Domain: Sized + 'static {
19 type State: std::fmt::Debug + Sized;
21 type Diff: std::fmt::Debug + Default + Clone + Hash + Eq;
23 type DisplayAction: std::fmt::Debug + Default;
26
27 fn list_behaviors() -> &'static [&'static dyn Behavior<Self>];
29
30 fn get_current_value(tick: u64, state_diff: StateDiffRef<Self>, agent: AgentId) -> AgentValue;
32
33 fn update_visible_agents(
35 start_tick: u64,
36 tick: u64,
37 state_diff: StateDiffRef<Self>,
38 agent: AgentId,
39 agents: &mut BTreeSet<AgentId>,
40 );
41
42 fn get_tasks(
44 tick: u64,
45 state_diff: StateDiffRef<'_, Self>,
46 agent: AgentId,
47 ) -> Vec<Box<dyn Task<Self>>> {
48 let mut actions = Vec::new();
49 Self::list_behaviors()
50 .iter()
51 .for_each(|behavior| behavior.add_tasks(tick, state_diff, agent, &mut actions));
52
53 actions.dedup();
54 actions
55 }
56
57 fn get_state_description(_state_diff: StateDiffRef<Self>) -> String {
60 String::new()
61 }
62
63 fn get_new_agents(_state_diff: StateDiffRef<Self>) -> Vec<AgentId> {
65 vec![]
66 }
67
68 fn display_action_task_idle() -> Self::DisplayAction {
70 Default::default()
71 }
72
73 fn display_action_task_planning() -> Self::DisplayAction {
75 Default::default()
76 }
77}
78
79pub trait StateValueEstimator<D: Domain>: Send {
81 #[allow(clippy::too_many_arguments)]
85 fn estimate(
86 &mut self,
87 rnd: &mut ChaCha8Rng,
88 config: &MCTSConfiguration,
89 initial_state: &D::State,
90 start_tick: u64,
91 node: &Node<D>,
92 edges: &Edges<D>,
93 depth: u32,
94 ) -> Option<BTreeMap<AgentId, f32>>;
95}
96
97pub trait DomainWithPlanningTask: Domain {
99 fn fallback_task(_agent: AgentId) -> Box<dyn Task<Self>> {
101 Box::new(IdleTask)
102 }
103}