naive astar
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
use crate::lib::screen::{Screen, BoardCommand};
|
use crate::lib::screen::{Screen, BoardCommand};
|
||||||
use crate::World;
|
use crate::World;
|
||||||
use crate::Point;
|
use crate::Point;
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
#[derive(Hash, PartialEq, Eq, Clone, Debug, Copy)]
|
#[derive(Hash, PartialEq, Eq, Clone, Debug, Copy)]
|
||||||
pub struct Point(pub i32, pub i32);
|
pub struct Point(pub i32, pub i32);
|
||||||
|
|
||||||
@@ -11,3 +13,75 @@ impl Point {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn manhattan(c1: &Point, c2: &Point) -> i32 {
|
||||||
|
return (c2.0 - c1.0).abs() + (c2.1 - c1.1).abs();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn astar(start: &Point, goal: &Point) -> Vec<Point> {
|
||||||
|
let mut open_set : HashSet<Point> = HashSet::new();
|
||||||
|
open_set.insert(*start);
|
||||||
|
|
||||||
|
let mut came_from: HashMap<Point, Point> = HashMap::new();
|
||||||
|
|
||||||
|
let mut gscore: HashMap<Point, i32> = HashMap::new();
|
||||||
|
gscore.insert(*start, 0);
|
||||||
|
|
||||||
|
let mut fscore: HashMap<Point, i32> = HashMap::new();
|
||||||
|
fscore.insert(*start, manhattan(&start, &goal));
|
||||||
|
|
||||||
|
let mut answer = Vec::new();
|
||||||
|
|
||||||
|
let mut current: Point = *start;
|
||||||
|
while !open_set.is_empty() {
|
||||||
|
let mut min_score = i32::MAX;
|
||||||
|
for c in open_set.iter() {
|
||||||
|
let val = fscore[c];
|
||||||
|
current = if val < min_score { c.clone() } else { current };
|
||||||
|
min_score = if val < min_score { val } else { min_score };
|
||||||
|
}
|
||||||
|
|
||||||
|
if current == *goal {
|
||||||
|
answer.push(current.clone());
|
||||||
|
while came_from.contains_key(¤t) {
|
||||||
|
current = came_from[¤t].clone();
|
||||||
|
answer.push(current.clone());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
open_set.remove(¤t);
|
||||||
|
|
||||||
|
let current_gscore = gscore[¤t];
|
||||||
|
|
||||||
|
let all_neighbors: Vec<Point> = current.get_neighbors();
|
||||||
|
for neighbor in all_neighbors.iter() {
|
||||||
|
let neighbor_score = if gscore.contains_key(&neighbor) {
|
||||||
|
gscore[neighbor]
|
||||||
|
} else {
|
||||||
|
i32::MAX
|
||||||
|
};
|
||||||
|
let score = current_gscore + 1;
|
||||||
|
if score < neighbor_score {
|
||||||
|
gscore.insert(neighbor.clone(), score);
|
||||||
|
fscore.insert(neighbor.clone(), score + manhattan(&neighbor, &goal));
|
||||||
|
came_from.insert(neighbor.clone(), current.clone());
|
||||||
|
open_set.insert(neighbor.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
answer
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_astar() {
|
||||||
|
let start = Point(0, 0);
|
||||||
|
|
||||||
|
let goal = Point(10, 10);
|
||||||
|
let answers: Vec<Point> = astar(&start, &goal);
|
||||||
|
|
||||||
|
for a in answers.iter() {
|
||||||
|
println!("{:?}", &a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user