use std::sync::mpsc;
use std::thread;
use std::vec;
use rusty_planner::dstar_lite;
use rusty_planner::planner;
struct Maze {
maze: [[f64; 6]; 6],
}
impl planner::ProblemSpace for Maze {
type State = (usize, usize);
type Iter = vec::IntoIter<(Self::State, f64)>;
fn heuristic(&self, p: &Self::State, q: &Self::State) -> f64 {
let x = (p.0 as i32 - q.0 as i32).abs();
let y = (p.1 as i32 - q.1 as i32).abs();
((x).pow(2) as f64 + (y).pow(2) as f64).sqrt()
}
fn succ(&self, s: &Self::State) -> Self::Iter {
let mut res = Vec::new();
if s.1 > 0 && self.maze[s.0][s.1 - 1] != -1. {
res.push(((s.0, s.1 - 1), self.maze[s.0][s.1 - 1]));
}
if s.1 + 1 < 6 && self.maze[s.0][s.1 + 1] != -1. {
res.push(((s.0, s.1 + 1), self.maze[s.0][s.1 + 1]));
}
if s.0 > 0 && self.maze[s.0 - 1][s.1] != -1. {
res.push(((s.0 - 1, s.1), self.maze[s.0 - 1][s.1]));
}
if s.0 + 1 < 6 && self.maze[s.0 + 1][s.1] != -1. {
res.push(((s.0 + 1, s.1), self.maze[s.0 + 1][s.1]));
}
res.into_iter()
}
fn pred(&self, s: &Self::State) -> Self::Iter {
self.succ(s)
}
}
impl planner::Lifelong for Maze {
fn update(&mut self, state: &Self::State) {
if state.0 == 3 && state.1 == 4 {
self.maze[state.0][state.1] = 1.;
}
}
}
fn callback(path: Vec<(usize, usize)>) {
print!("start");
for x in &path {
print!(" -> ({}, {})", x.0, x.1);
}
print!("\n");
}
fn main() {
let (tx, rx) = mpsc::channel();
let env = [
[-1., 1., 1., 1., 1., 1.],
[-1., 1., -1., -1., -1., 2.],
[-1., 1., 1., -1., -1., 2.],
[-1., -1., 1., 1., -1., 2.],
[-1., -1., -1., 1., -1., 2.],
[1., 2., 2., 2., 2., 2.],
];
let mut maze = Maze { maze: env };
let plnr = thread::spawn(move || {
dstar_lite::solve(&mut maze, (5, 0), (0, 5), rx, callback);
});
tx.send(((3, 4), (5, 2))).unwrap();
tx.send(((0, 0), (0, 5))).unwrap();
plnr.join().unwrap();
}