naive astar
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
|
||||
use crate::lib::screen::{Screen, BoardCommand};
|
||||
use crate::World;
|
||||
use crate::Point;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
#[derive(Hash, PartialEq, Eq, Clone, Debug, Copy)]
|
||||
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