Skip to content

Commit

Permalink
Adding Alive Substates
Browse files Browse the repository at this point in the history
  • Loading branch information
SaschaAtWork committed Jan 2, 2025
1 parent 03207a3 commit 03e30f1
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 31 deletions.
44 changes: 25 additions & 19 deletions src/logic/depth_first/simulation/d_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,11 @@ where
Some(parent_id) => {
let parent = self.nodes.get(&parent_id).unwrap();
match parent.status() {
DNodeStatus::Alive => {
DNodeStatus::Alive(_) => {
let children_status = self.calc_children(&parent_id);
for (id, status) in children_status {
match status {
DNodeStatus::Alive => {
DNodeStatus::Alive(_) => {
let index = id.direction().unwrap() as usize;
self.queue[index].push(id);
self.queue[index].sort_unstable_by(|id1, id2| {
Expand Down Expand Up @@ -123,18 +123,21 @@ where
results.push(DSimulationDirectionResult::new(d));
}
for (_, node) in self.nodes.iter() {
if node.status() == DNodeStatus::Alive && node.id().len() > 0 {
let direction = node.id().first().unwrap();
let index: usize = *direction as usize;
results[index].states += node.statistics().states.unwrap_or(1);
let depth = node.id().len();
if depth > results[index].depth {
results[index].depth = depth;
results[index].best.clear();
results[index].best.push(node.id().clone());
} else if depth == results[index].depth {
results[index].best.push(node.id().clone());
match node.status() {
DNodeStatus::Alive(_) if node.id().len() > 0 => {
let direction = node.id().first().unwrap();
let index: usize = *direction as usize;
results[index].states += node.statistics().states.unwrap_or(1);
let depth = node.id().len();
if depth > results[index].depth {
results[index].depth = depth;
results[index].best.clear();
results[index].best.push(node.id().clone());
} else if depth == results[index].depth {
results[index].best.push(node.id().clone());
}
}
_ => (),
}
}
DSimulationResult::new(results, self)
Expand All @@ -143,13 +146,16 @@ where
fn calc_children(&mut self, id: &DNodeId) -> Vec<(DNodeId, DNodeStatus)> {
let mut result = Vec::new();
match self.nodes.get(id) {
Some(node) if node.status() == DNodeStatus::Alive => {
let children = node.calc_children();
for child in children.into_iter() {
result.push((child.id().clone(), child.status()));
self.nodes.insert(child.id().clone(), child);
Some(node) => match node.status() {
DNodeStatus::Alive(_) => {
let children = node.calc_children();
for child in children.into_iter() {
result.push((child.id().clone(), child.status()));
self.nodes.insert(child.id().clone(), child);
}
}
}
_ => (),
},
_ => panic!("Node not found"),
}
result
Expand Down
34 changes: 28 additions & 6 deletions src/logic/depth_first/simulation/node/d_optimistic_capture_node.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{DNode, DNodeStatus};
use super::{DNode, DNodeAliveStatus, DNodeStatus};
use crate::logic::depth_first::{
game::{d_direction::DDirection, d_field::DSlowField, d_game_state::DGameState},
simulation::{d_node_id::DNodeId, d_tree::DTreeTime},
Expand All @@ -11,6 +11,7 @@ pub struct DOptimisticCaptureNode {
state: DGameState<DSlowField>,
time: DTreeTime,
status: Cell<DNodeStatus>,
child_alive_helper: Cell<[DNodeAliveStatus; 4]>,
}

impl DOptimisticCaptureNode {
Expand All @@ -25,6 +26,7 @@ impl DOptimisticCaptureNode {
state,
time,
status: Cell::new(status),
child_alive_helper: Cell::new([DNodeAliveStatus::default(); 4]),
}
}

Expand All @@ -37,15 +39,31 @@ impl DOptimisticCaptureNode {
.next_state(moves)
.move_reachable(moves, new_id.len() as u8);
let status = match new_state.get_alive()[0] {
true => DNodeStatus::Alive,
true => DNodeStatus::Alive(self.child_alive_helper.get()[direction as usize]),
false => DNodeStatus::Dead,
};
Self::new(new_id, new_state, self.time.clone(), status)
}

fn calc_moves(&self) -> ArrayVec<DDirection, 4> {
let turn = self.id.len() as u8 + 1;
self.state.scope_moves_optimistic(turn)
let mut child_direction_states = [DNodeAliveStatus::default(); 4];
let optimistic = self.state.scope_moves_optimistic(turn);
let pessimistic = self.state.scope_moves_pessimistic();
for m in pessimistic.iter() {
let direction = m;
let index = *direction as usize;
child_direction_states[index] = DNodeAliveStatus::Always;
}
for m in optimistic.iter() {
let direction = m;
let index = *direction as usize;
if child_direction_states[index] == DNodeAliveStatus::default() {
child_direction_states[index] = DNodeAliveStatus::Sometimes;
}
}
self.child_alive_helper.set(child_direction_states);
optimistic
}
}

Expand All @@ -58,7 +76,8 @@ impl DNode for DOptimisticCaptureNode {
match self.status.get() {
DNodeStatus::Unknown => {
if self.state.get_alive()[0] {
self.status.set(DNodeStatus::Alive);
self.status
.set(DNodeStatus::Alive(DNodeAliveStatus::default()));
} else {
self.status.set(DNodeStatus::Dead);
}
Expand Down Expand Up @@ -113,7 +132,7 @@ mod tests {
simulation::{
d_node_id::DNodeId,
d_tree::DTreeTime,
node::{DNode, DNodeStatus},
node::{DNode, DNodeAliveStatus, DNodeStatus},
},
},
read_game_state,
Expand All @@ -133,7 +152,10 @@ mod tests {
println!("{}", node);
let child_up = node.calc_child(DDirection::Up);
println!("{}", child_up);
assert_eq!(child_up.status(), DNodeStatus::Alive);
assert_eq!(
child_up.status(),
DNodeStatus::Alive(DNodeAliveStatus::Always)
);
let child_left = node.calc_child(DDirection::Left);
assert_eq!(child_left.status(), DNodeStatus::Dead);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::logic::depth_first::{
simulation::{d_node_id::DNodeId, d_tree::DTreeTime},
};

use super::{DNode, DNodeStatus};
use super::{DNode, DNodeAliveStatus, DNodeStatus};

pub struct DPessimisticCaptureNode {
id: DNodeId,
Expand Down Expand Up @@ -41,7 +41,7 @@ impl DPessimisticCaptureNode {
.next_state(moves)
.move_reachable(moves, new_id.len() as u8);
let status = match new_state.get_alive()[0] {
true => DNodeStatus::Alive,
true => DNodeStatus::Alive(DNodeAliveStatus::Always),
false => DNodeStatus::Dead,
};
Self::new(new_id, new_state, self.time.clone(), status)
Expand All @@ -61,7 +61,8 @@ impl DNode for DPessimisticCaptureNode {
match self.status.get() {
DNodeStatus::Unknown => {
if self.state.get_alive()[0] {
self.status.set(DNodeStatus::Alive);
self.status
.set(DNodeStatus::Alive(DNodeAliveStatus::default()));
} else {
self.status.set(DNodeStatus::Dead);
}
Expand Down Expand Up @@ -116,7 +117,7 @@ mod tests {
simulation::{
d_node_id::DNodeId,
d_tree::DTreeTime,
node::{DNode, DNodeStatus},
node::{DNode, DNodeAliveStatus, DNodeStatus},
},
},
read_game_state,
Expand All @@ -136,7 +137,10 @@ mod tests {
println!("{}", node);
let child_up = node.calc_child(DDirection::Up);
println!("{}", child_up);
assert_eq!(child_up.status(), DNodeStatus::Alive);
assert_eq!(
child_up.status(),
DNodeStatus::Alive(DNodeAliveStatus::Always)
);
let child_left = node.calc_child(DDirection::Left);
assert_eq!(child_left.status(), DNodeStatus::Dead);
}
Expand Down
10 changes: 9 additions & 1 deletion src/logic/depth_first/simulation/node/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,20 @@ pub trait DNode {
pub enum DNodeStatus {
#[default]
Unknown,
Alive,
Alive(DNodeAliveStatus),
Dead,
TimedOut,
DeadEnd,
}

#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
pub enum DNodeAliveStatus {
#[default]
Unknown,
Always,
Sometimes,
}

#[derive(Default, Copy, Clone)]
/// Statistics of a node.
/// If statistics refer to individual gamestates, they represent the worst case scenario
Expand Down

0 comments on commit 03e30f1

Please sign in to comment.