Skip to content

Commit d7ef7da

Browse files
committed
.
1 parent db28309 commit d7ef7da

File tree

2 files changed

+79
-11
lines changed

2 files changed

+79
-11
lines changed

packages/solver-r/src/snake.rs

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,35 @@ pub fn move_snake(s: &mut Snake, dir: &Point) -> () {
1111
e.y = s[0].y + dir.y;
1212
s.insert(0, e);
1313
}
14-
pub fn will_self_collide(s: &Snake, dir: &Point) -> bool {
14+
pub fn snake_will_self_collide(s: &Snake, dir: &Point) -> bool {
1515
let next_head = Point {
1616
x: s[0].x + dir.x,
1717
y: s[0].y + dir.y,
1818
};
1919

2020
(&s[0..(s.len() - 1)]).contains(&next_head)
2121
}
22+
pub fn get_snake_head(s: &Snake) -> Point {
23+
s[0]
24+
}
25+
pub fn get_next_snake_head(s: &Snake, dir: &Point) -> Point {
26+
Point {
27+
x: s[0].x + dir.x,
28+
y: s[0].y + dir.y,
29+
}
30+
}
31+
32+
#[test]
33+
fn it_should_return_head() {
34+
let s = vec![
35+
//
36+
Point { x: 3, y: 0 },
37+
Point { x: 2, y: 0 },
38+
Point { x: 1, y: 0 },
39+
];
2240

41+
assert_eq!(get_snake_head(&s), Point { x: 3, y: 0 });
42+
}
2343
#[test]
2444
fn it_should_detect_self_collide() {
2545
let mut s = vec![
@@ -35,11 +55,22 @@ fn it_should_detect_self_collide() {
3555
move_snake(&mut s, &DIRECTION_UP);
3656
move_snake(&mut s, &DIRECTION_LEFT);
3757

38-
assert_eq!(will_self_collide(&s, &DIRECTION_DOWN), true);
58+
assert_eq!(snake_will_self_collide(&s, &DIRECTION_DOWN), true);
3959

4060
move_snake(&mut s, &DIRECTION_LEFT);
4161

42-
assert_eq!(will_self_collide(&s, &DIRECTION_DOWN), false);
62+
assert_eq!(snake_will_self_collide(&s, &DIRECTION_DOWN), false);
63+
}
64+
#[test]
65+
fn it_should_detect_self_collide_2() {
66+
let s = vec![
67+
//
68+
Point { x: 3, y: 0 },
69+
Point { x: 2, y: 0 },
70+
Point { x: 1, y: 0 },
71+
];
72+
73+
assert_eq!(snake_will_self_collide(&s, &DIRECTION_LEFT), true);
4374
}
4475
#[test]
4576
fn it_should_move_snake() {

packages/solver-r/src/snake_walk.rs

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,58 @@
11
use std::collections::HashSet;
22

33
use crate::grid::{Cell, Grid, Point, DIRECTIONS};
4-
use crate::snake::Snake;
4+
use crate::snake::{
5+
get_next_snake_head, get_snake_head, move_snake, snake_will_self_collide, Snake,
6+
};
57

68
pub fn get_route_to_eat_all(
79
grid: &Grid,
810
walkable: Cell,
911
initial_snake: &Snake,
1012
cells_to_eat: HashSet<Point>,
11-
) -> Vec<Snake> {
12-
let mut targets = cells_to_eat.clone();
13+
) -> Vec<Point> {
14+
// let mut targets: Vec<Point> = cells_to_eat.iter().map(|p| p.clone()).collect();
1315

14-
while let Some(p) = targets.iter().next().cloned() {
15-
targets.remove(&p);
16+
let mut targets: Vec<&Point> = cells_to_eat.iter().collect();
1617

17-
let mut open_list: HashSet<Snake> = HashSet::new();
18+
let mut path: Vec<Point> = Vec::new();
19+
20+
let mut initial_snake = initial_snake.clone();
21+
22+
while let Some(target) = targets.pop() {
23+
// prepare
24+
let mut open_list: HashSet<(Snake, Vec<Point>)> = HashSet::new();
25+
open_list.insert((initial_snake.clone(), Vec::new()));
26+
27+
while let Some(x) = open_list.iter().next().cloned() {
28+
open_list.remove(&x);
29+
30+
let snake = x.0;
31+
let mut sub_path = x.1;
32+
33+
if get_snake_head(&snake) == *target {
34+
path.append(&mut sub_path);
35+
initial_snake = snake;
36+
break;
37+
}
38+
39+
for dir in DIRECTIONS {
40+
if {
41+
let h = get_next_snake_head(&snake, &dir);
42+
grid.get_cell(&h) <= walkable
43+
} && !snake_will_self_collide(&snake, &dir)
44+
{
45+
let mut next_snake = snake.clone();
46+
move_snake(&mut next_snake, &dir);
47+
48+
let mut next_sub_path = sub_path.clone();
49+
next_sub_path.push(dir.clone());
50+
51+
open_list.insert((next_snake, next_sub_path));
52+
}
53+
}
54+
}
1855
}
19-
for dir in DIRECTIONS {}
20-
Vec::new()
56+
57+
path
2158
}

0 commit comments

Comments
 (0)