Skip to content

Commit 5a220f4

Browse files
committed
.
1 parent dbf8650 commit 5a220f4

File tree

6 files changed

+136
-18
lines changed

6 files changed

+136
-18
lines changed

β€Žcargo/snk-grid/src/color.rsβ€Ž

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ impl Color {
2323
match self {
2424
Color::Empty => 0,
2525
Color::Color1 => 1,
26-
Color::Color2 => 150,
27-
Color::Color3 => 150 * 150,
28-
Color::Color4 => 150 * 150 * 150,
26+
Color::Color2 => 128,
27+
Color::Color3 => 128 * 128,
28+
Color::Color4 => 128 * 128 * 128,
2929
}
3030
}
3131
}

β€Žcargo/snk-grid/src/direction.rsβ€Ž

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::collections::HashSet;
2+
13
use crate::point::{Point, add};
24

35
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
@@ -19,18 +21,38 @@ pub const DIRECTIONS: [Direction; 4] = [
1921
impl Direction {
2022
pub fn to_point(&self) -> Point {
2123
match self {
22-
Direction::UP => Point { x: 0, y: 1 },
23-
Direction::DOWN => Point { x: 0, y: -1 },
24+
Direction::UP => Point { x: 0, y: -1 },
25+
Direction::DOWN => Point { x: 0, y: 1 },
2426
Direction::LEFT => Point { x: -1, y: 0 },
2527
Direction::RIGHT => Point { x: 1, y: 0 },
2628
}
2729
}
2830

31+
pub fn get_opposite(&self) -> Direction {
32+
match self {
33+
Direction::UP => Direction::DOWN,
34+
Direction::DOWN => Direction::UP,
35+
Direction::LEFT => Direction::RIGHT,
36+
Direction::RIGHT => Direction::LEFT,
37+
}
38+
}
39+
2940
pub fn iter() -> impl Iterator<Item = Direction> {
3041
DIRECTIONS.iter().map(|dir| dir.clone())
3142
}
3243
}
3344

45+
impl ToString for Direction {
46+
fn to_string(&self) -> String {
47+
match self {
48+
Direction::UP => "↑".to_string(),
49+
Direction::DOWN => "↓".to_string(),
50+
Direction::LEFT => "←".to_string(),
51+
Direction::RIGHT => "β†’".to_string(),
52+
}
53+
}
54+
}
55+
3456
pub fn add_direction(a: Point, dir: Direction) -> Point {
3557
add(a, dir.to_point())
3658
}
@@ -45,30 +67,30 @@ pub fn iter_neighbour(p: Point) -> impl Iterator<Item = Point> {
4567

4668
#[test]
4769
fn it_should_iter_direction() {
48-
let directions: Vec<_> = iter_directions().collect();
70+
let directions: HashSet<_> = iter_directions().collect();
4971

5072
assert_eq!(
5173
directions,
52-
vec![
74+
HashSet::from([
5375
Direction::UP,
5476
Direction::DOWN,
5577
Direction::LEFT,
5678
Direction::RIGHT,
57-
]
79+
])
5880
);
5981
}
6082

6183
#[test]
6284
fn it_should_iter_direction_point() {
63-
let directions: Vec<_> = iter_directions().map(|d| d.to_point()).collect();
85+
let directions: HashSet<_> = iter_directions().map(|d| d.to_point()).collect();
6486

6587
assert_eq!(
6688
directions,
67-
vec![
89+
HashSet::from([
6890
Point { x: 0, y: 1 },
6991
Point { x: 0, y: -1 },
7092
Point { x: -1, y: 0 },
7193
Point { x: 1, y: 0 }
72-
]
94+
])
7395
);
7496
}

β€Žcargo/snk-grid/src/grid.rsβ€Ž

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ impl<T: Copy> Grid<T> {
2929
let i = self.get_index(p.x, p.y);
3030
return self.cells[i];
3131
}
32+
pub fn get_mut(&mut self, p: Point) -> &mut T {
33+
let i = self.get_index(p.x, p.y);
34+
return self.cells.get_mut(i).unwrap();
35+
}
3236
pub fn set(&mut self, p: Point, value: T) -> () {
3337
let i = self.get_index(p.x, p.y);
3438
self.cells[i] = value;

β€Žcargo/snk-solver/src/lib.rsβ€Ž

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
// pub mod reach_outside;
33
pub mod cost_to_outside;
44
mod fitness;
5+
mod path_to_outside_grid;
56
pub mod snake_path;
67
pub mod solver;
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
use snk_grid::{
2+
color::Color,
3+
direction::{Direction, add_direction, iter_directions},
4+
grid::{Grid, iter_rectangle_hull},
5+
point::Point,
6+
};
7+
use std::collections::HashSet;
8+
9+
#[derive(Copy, Clone)]
10+
pub struct ExitCell {
11+
cost: u32,
12+
exit_direction: Direction,
13+
}
14+
impl ToString for ExitCell {
15+
fn to_string(&self) -> String {
16+
if self.cost == 0 {
17+
"o".to_string()
18+
} else {
19+
self.exit_direction.to_string()
20+
}
21+
}
22+
}
23+
24+
//
25+
// cost_to_outside : for each cell return the minimal cost ( = sum of dot, with greater color costing more ) to get outside
26+
pub fn create_path_to_outside(grid: &Grid<Color>) -> Grid<ExitCell> {
27+
let mut path_to_outside = Grid::<ExitCell>::create_with_value(
28+
grid.width,
29+
grid.height,
30+
ExitCell {
31+
cost: u32::MAX,
32+
exit_direction: Direction::UP,
33+
},
34+
);
35+
36+
let mut changed: HashSet<Point> =
37+
iter_rectangle_hull(grid.width as i8 + 2, grid.height as i8 + 2)
38+
.map(|mut p| {
39+
p.x -= 1;
40+
p.y -= 1;
41+
p
42+
})
43+
.collect();
44+
45+
while let Some(p) = {
46+
let next = changed.iter().next();
47+
next.map(|p| *p)
48+
} {
49+
changed.remove(&p);
50+
51+
let cost = if path_to_outside.is_inside(p) {
52+
path_to_outside.get(p).cost
53+
} else {
54+
0
55+
};
56+
57+
for dir in iter_directions() {
58+
let p = add_direction(p, dir);
59+
if path_to_outside.is_inside(p) {
60+
let new_cost = cost + grid.get(p).cost();
61+
62+
let c = path_to_outside.get_mut(p);
63+
64+
if new_cost < c.cost {
65+
c.cost = new_cost;
66+
c.exit_direction = dir.get_opposite();
67+
changed.insert(p);
68+
}
69+
}
70+
}
71+
}
72+
73+
path_to_outside
74+
}
75+
76+
#[test]
77+
fn it_should_compute_the_cost_to_outside() {
78+
let grid = Grid::<_>::from(
79+
r#"
80+
_....
81+
_. ..
82+
_....
83+
_....
84+
"#,
85+
);
86+
let pto = create_path_to_outside(&grid);
87+
88+
assert_eq!(
89+
pto.to_string(),
90+
r#"
91+
o←↑↑↑
92+
o←←→→
93+
o←↓→→
94+
o←↓↓→
95+
"#
96+
.trim(),
97+
);
98+
}

β€Žcargo/snk-solver/src/reach_outside.rsβ€Ž

Lines changed: 0 additions & 7 deletions
This file was deleted.

0 commit comments

Comments
Β (0)