1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
use std::collections::HashMap;
use crate::coord::Coord;
use crate::grid::Grid;
use crate::search::Search;
pub use crate::search::SearchOpts;
pub fn find_path(grid: &Grid, start: Coord, end: Coord, opts: Option<SearchOpts>) -> Option<Vec<Coord>> {
let end_on_unstoppable = match &opts {
None => false,
Some(opts) => match opts.end_on_unstoppable {
None => false,
Some(end_on_unstoppable) => end_on_unstoppable,
}
};
if Coord::equals(Some(start), Some(end)) {
Some(vec![])
} else if !grid.is_coord_stoppable(&end.x, &end.y) & !end_on_unstoppable {
None
} else {
let mut search = Search::new(start, Some(end), opts);
let start_node = search.coordinate_to_node(None, &start.x, &start.y, &0);
search.push(start_node);
calculate(&mut search, &grid);
match search.pop() {
None => None,
Some(node) => Some(node.format_path(&search)),
}
}
}
pub fn find_walkable(grid: &Grid, source: Vec<Coord>, opts: Option<SearchOpts>) -> Vec<Coord> {
let mut search = Search::new(*source.first().unwrap(), None, opts);
for coord in source {
let node = search.coordinate_to_node(None, &coord.x, &coord.y, &0);
search.push(node);
}
calculate(&mut search, &grid);
let coords = &mut vec![];
for node in search.traversed_nodes() {
if grid.is_coord_walkable(&node.x, &node.y) {
coords.push(Coord::new(node.x, node.y));
}
}
coords.sort();
coords.to_owned()
}
pub fn to_coord_map(coords: Vec<Coord>) -> HashMap<i32, HashMap<i32, bool>> {
let hash = &mut HashMap::new();
for Coord{x, y} in coords {
match hash.get_mut(&y) {
None => {
let mut inner_hash = HashMap::new();
inner_hash.insert(x, true);
hash.insert(y, inner_hash);
},
Some(inner_hash) => {
inner_hash.insert(x, true);
},
};
}
hash.to_owned()
}
fn calculate(search: &mut Search, grid: &Grid) {
match search.size() {
0 => (),
_ => {
if search.reached_destination() {
()
} else {
let mut node = search.pop().unwrap();
node.visited = true;
search.cache(node);
if grid.in_grid(node.x, node.y - 1) {
search.check_adjacent_node(grid, &node, 0, -1)
}
if !grid.is_cardinal() & grid.in_grid(node.x + 1, node.y - 1) {
search.check_adjacent_node(grid, &node, 1, -1)
}
if grid.in_grid(node.x + 1, node.y) {
search.check_adjacent_node(grid, &node, 1, 0)
}
if grid.is_intercardinal() & grid.in_grid(node.x + 1, node.y + 1) {
search.check_adjacent_node(grid, &node, 1, 1)
}
if grid.in_grid(node.x, node.y + 1) {
search.check_adjacent_node(grid, &node, 0, 1)
}
if !grid.is_cardinal() & grid.in_grid(node.x - 1, node.y + 1) {
search.check_adjacent_node(grid, &node, -1, 1)
}
if grid.in_grid(node.x - 1, node.y) {
search.check_adjacent_node(grid, &node, -1, 0)
}
if grid.is_intercardinal() & grid.in_grid(node.x - 1, node.y - 1) {
search.check_adjacent_node(grid, &node, -1, -1)
}
calculate(search, grid)
}
},
}
}