initial commit
This commit is contained in:
commit
08592261b3
12 changed files with 822 additions and 0 deletions
45
src/implementations/breath_first.rs
Normal file
45
src/implementations/breath_first.rs
Normal 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)
|
||||
}
|
||||
}
|
55
src/implementations/depth_first.rs
Normal file
55
src/implementations/depth_first.rs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue