initial commit

This commit is contained in:
JOLIMAITRE Matthieu 2022-05-30 00:33:36 +03:00
commit 08592261b3
12 changed files with 822 additions and 0 deletions

View file

@ -0,0 +1,45 @@
use std::collections::{HashSet, VecDeque};
use crate::{
algorithm::{Context, Guess, Insight},
Algorithm, Pos,
};
/// [`Algorithm`] traversing the [`crate::Maze`] as a common graph.
/// Storing each possible paths form shortest to longest and extending the shortest ones first.
/// Most effective when the resolution is among the shortest possible paths.
pub struct BreathFirst {
paths: VecDeque<Vec<Pos>>,
visited: HashSet<Pos>,
last_path: Vec<Pos>,
}
impl BreathFirst {
/// Constructor.
pub fn new() -> Self {
Self {
paths: VecDeque::new(),
visited: HashSet::new(),
last_path: Vec::new(),
}
}
}
impl Algorithm for BreathFirst {
fn progress(&mut self, insight: &Insight, ctx: &mut Context) -> Guess {
self.visited.insert(insight.position());
let path = self.last_path.clone();
for &branch in insight.paths() {
if self.visited.contains(&branch) {
continue;
}
let mut new_path = path.clone();
new_path.push(branch);
self.paths.push_back(new_path);
}
let path = self.paths.pop_front().expect("no more options");
self.last_path = path.clone();
ctx.guess(path)
}
}

View file

@ -0,0 +1,55 @@
use std::collections::HashSet;
use crate::{
algorithm::{Context, Guess, Insight},
Algorithm, Pos,
};
/// Frame of the stack used by a [`DepthFirst`] to retain its path and possible branches.
pub struct Frame {
position: Pos,
remaining_branches: Vec<Pos>,
}
/// [`Algorithm`] driving the resolution of a [`crate::Maze`] traversing it as a common graph in a depth-first fashion.
/// Stores the current path and possible branches in a stack.
pub struct DepthFirst {
visited: HashSet<Pos>,
stack: Vec<Frame>,
}
impl DepthFirst {
/// constructor.
pub fn new() -> Self {
Self {
visited: HashSet::new(),
stack: Vec::new(),
}
}
}
impl Algorithm for DepthFirst {
fn progress(&mut self, insight: &Insight, ctx: &mut Context) -> Guess {
let position = insight.position();
let branches = insight.paths().iter().cloned().collect();
self.visited.insert(position);
self.stack.push(Frame {
position,
remaining_branches: branches,
});
loop {
let last = self.stack.last_mut().expect("no more options");
if let Some(branch) = last.remaining_branches.pop() {
if !self.visited.contains(&branch) {
let mut path: Vec<_> = self.stack.iter().map(|f| f.position).collect();
path.push(branch);
return ctx.guess(path);
}
} else {
self.stack.pop();
}
}
}
}