Skip to content

Commit be9fca7

Browse files
committed
.
1 parent c0a042d commit be9fca7

File tree

3 files changed

+70
-11
lines changed

3 files changed

+70
-11
lines changed

packages/solver-r/src/grid.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
22
pub struct Point {
3-
pub x: u8,
4-
pub y: u8,
3+
pub x: i8,
4+
pub y: i8,
55
}
66

7-
#[derive(Copy, Clone, Debug, PartialEq)]
7+
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
88
#[repr(u8)]
99
pub enum Cell {
1010
Empty = 0,
@@ -32,7 +32,7 @@ impl Grid {
3232
}
3333
}
3434

35-
pub fn get_index(&self, x: u8, y: u8) -> usize {
35+
pub fn get_index(&self, x: i8, y: i8) -> usize {
3636
return (x as usize) * (self.height as usize) + (y as usize);
3737
}
3838
pub fn get_cell(&self, p: &Point) -> Cell {
@@ -43,8 +43,18 @@ impl Grid {
4343
let i = self.get_index(p.x, p.y);
4444
self.cells[i] = value;
4545
}
46+
pub fn is_inside(&self, p: &Point) -> bool {
47+
p.x >= 0 && p.x < (self.width as i8) && p.y >= 0 && p.y < (self.height as i8)
48+
}
4649
}
4750

51+
#[test]
52+
fn it_should_sort_cell() {
53+
assert_eq!(Cell::Empty < Cell::Color1, true);
54+
assert_eq!(Cell::Color1 < Cell::Color2, true);
55+
assert_eq!(Cell::Color2 < Cell::Color3, true);
56+
assert_eq!(Cell::Color3 < Cell::Color4, true);
57+
}
4858
#[test]
4959
fn it_should_grid_create() {
5060
let grid = Grid::create_empty(30, 10);

packages/solver-r/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ pub fn iget_free_cell(grid: &IGrid) -> js_sys::Uint8Array {
7070

7171
let out = get_free_cell(&g, Cell::Color1);
7272

73-
let o: Vec<u8> = out.iter().flat_map(|p| [p.x, p.y]).collect();
73+
let o: Vec<u8> = out.iter().flat_map(|p| [p.x as u8, p.y as u8]).collect();
7474

7575
js_sys::Uint8Array::from(&o[..])
7676
}

packages/solver-r/src/solver.rs

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,62 @@ use crate::grid::{Cell, Grid, Point};
55
pub fn get_free_cell(grid: &Grid, walkable: Cell) -> HashSet<Point> {
66
let mut free: HashSet<Point> = HashSet::new();
77
let mut open_list: HashSet<Point> = HashSet::new();
8-
let mut changed = true;
98

10-
open_list.insert(Point { x: 0, y: 0 });
9+
for x in -1..((grid.width as i8) + 1) {
10+
open_list.insert(Point { x, y: 0 });
11+
open_list.insert(Point {
12+
x,
13+
y: (grid.height as i8) - 1,
14+
});
15+
}
16+
17+
let directions = [
18+
Point { x: 1, y: 0 },
19+
Point { x: -1, y: 0 },
20+
Point { x: 0, y: 1 },
21+
Point { x: 0, y: -1 },
22+
];
23+
24+
while let Some(p) = open_list.iter().next().cloned() {
25+
open_list.remove(&p);
26+
27+
let exit_count: u8 = directions.iter().fold(0, |sum, dir| {
28+
let neighbour = Point {
29+
x: p.x + dir.x,
30+
y: p.y + dir.y,
31+
};
32+
33+
if !grid.is_inside(&neighbour) {
34+
sum + 2
35+
} else if free.contains(&neighbour) {
36+
sum + 1
37+
} else {
38+
sum
39+
}
40+
});
41+
42+
if exit_count >= 2 {
43+
if grid.is_inside(&p) && grid.get_cell(&p) <= walkable {
44+
free.insert(p);
45+
}
46+
47+
for dir in directions {
48+
let neighbour = Point {
49+
x: p.x + dir.x,
50+
y: p.y + dir.y,
51+
};
1152

12-
while changed {
13-
changed = false
53+
if grid.is_inside(&neighbour)
54+
&& (grid.get_cell(&neighbour) <= walkable)
55+
&& !free.contains(&neighbour)
56+
{
57+
open_list.insert(neighbour);
58+
}
59+
}
60+
}
1461
}
1562

16-
open_list
63+
free
1764
}
1865

1966
#[test]
@@ -28,7 +75,9 @@ fn it_should_collect_free_cell() {
2875
free_cells,
2976
HashSet::from([
3077
//
31-
Point { x: 0, y: 0 }
78+
Point { x: 0, y: 0 },
79+
Point { x: 0, y: 1 },
80+
Point { x: 1, y: 0 },
3281
])
3382
);
3483
}

0 commit comments

Comments
 (0)