|
|
@ -217,13 +217,26 @@ impl Unit {
|
|
|
|
.collect()
|
|
|
|
.collect()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn reachable(&self, square: &Square, map: &Map) -> HashSet<Square> {
|
|
|
|
fn reachable(&self, square: &Square, map: &Map) -> HashMap<Square, usize> {
|
|
|
|
let distances = map.distances(square);
|
|
|
|
let in_range = self.in_range(&map);
|
|
|
|
self.in_range(&map)
|
|
|
|
map.distances(square)
|
|
|
|
.into_iter()
|
|
|
|
.into_iter()
|
|
|
|
.filter(|x| distances.contains_key(x))
|
|
|
|
.filter(|(x, _)| in_range.contains(x))
|
|
|
|
.collect()
|
|
|
|
.collect()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn next_step(&self, square: &Square, map: &Map) -> Option<Square> {
|
|
|
|
|
|
|
|
self.reachable(&square, &map)
|
|
|
|
|
|
|
|
.into_iter()
|
|
|
|
|
|
|
|
.fold(HashMap::new(), |mut m, (s, d)| {
|
|
|
|
|
|
|
|
let v = m.entry(d).or_insert_with(Vec::new);
|
|
|
|
|
|
|
|
v.push(s);
|
|
|
|
|
|
|
|
m
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
.iter()
|
|
|
|
|
|
|
|
.min_by_key(|(&x, _)| x)
|
|
|
|
|
|
|
|
.and_then(|(_, x)| x.iter().min().cloned()) // Is there a way to avoid this clone?
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[test]
|
|
|
@ -260,7 +273,10 @@ fn test_unit_targets() {
|
|
|
|
assert!(vec![(1, 3), (2, 2), (3, 1), (3, 3)]
|
|
|
|
assert!(vec![(1, 3), (2, 2), (3, 1), (3, 3)]
|
|
|
|
.iter()
|
|
|
|
.iter()
|
|
|
|
.map(|&x| Square(x))
|
|
|
|
.map(|&x| Square(x))
|
|
|
|
.all(|x| reachable.contains(&x)));
|
|
|
|
.all(|x| reachable.contains_key(&x)));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let next_step = unit.next_step(&square, &map);
|
|
|
|
|
|
|
|
assert_eq!(next_step.unwrap().0, (1, 3));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Eq, PartialEq)]
|
|
|
|
#[derive(Debug, Eq, PartialEq)]
|
|
|
|