This commit is contained in:
platane
2025-03-24 22:01:03 +01:00
parent db283098a9
commit d7ef7da9fb
2 changed files with 79 additions and 11 deletions

View File

@@ -11,7 +11,7 @@ pub fn move_snake(s: &mut Snake, dir: &Point) -> () {
e.y = s[0].y + dir.y;
s.insert(0, e);
}
pub fn will_self_collide(s: &Snake, dir: &Point) -> bool {
pub fn snake_will_self_collide(s: &Snake, dir: &Point) -> bool {
let next_head = Point {
x: s[0].x + dir.x,
y: s[0].y + dir.y,
@@ -19,7 +19,27 @@ pub fn will_self_collide(s: &Snake, dir: &Point) -> bool {
(&s[0..(s.len() - 1)]).contains(&next_head)
}
pub fn get_snake_head(s: &Snake) -> Point {
s[0]
}
pub fn get_next_snake_head(s: &Snake, dir: &Point) -> Point {
Point {
x: s[0].x + dir.x,
y: s[0].y + dir.y,
}
}
#[test]
fn it_should_return_head() {
let s = vec![
//
Point { x: 3, y: 0 },
Point { x: 2, y: 0 },
Point { x: 1, y: 0 },
];
assert_eq!(get_snake_head(&s), Point { x: 3, y: 0 });
}
#[test]
fn it_should_detect_self_collide() {
let mut s = vec![
@@ -35,11 +55,22 @@ fn it_should_detect_self_collide() {
move_snake(&mut s, &DIRECTION_UP);
move_snake(&mut s, &DIRECTION_LEFT);
assert_eq!(will_self_collide(&s, &DIRECTION_DOWN), true);
assert_eq!(snake_will_self_collide(&s, &DIRECTION_DOWN), true);
move_snake(&mut s, &DIRECTION_LEFT);
assert_eq!(will_self_collide(&s, &DIRECTION_DOWN), false);
assert_eq!(snake_will_self_collide(&s, &DIRECTION_DOWN), false);
}
#[test]
fn it_should_detect_self_collide_2() {
let s = vec![
//
Point { x: 3, y: 0 },
Point { x: 2, y: 0 },
Point { x: 1, y: 0 },
];
assert_eq!(snake_will_self_collide(&s, &DIRECTION_LEFT), true);
}
#[test]
fn it_should_move_snake() {

View File

@@ -1,21 +1,58 @@
use std::collections::HashSet;
use crate::grid::{Cell, Grid, Point, DIRECTIONS};
use crate::snake::Snake;
use crate::snake::{
get_next_snake_head, get_snake_head, move_snake, snake_will_self_collide, Snake,
};
pub fn get_route_to_eat_all(
grid: &Grid,
walkable: Cell,
initial_snake: &Snake,
cells_to_eat: HashSet<Point>,
) -> Vec<Snake> {
let mut targets = cells_to_eat.clone();
) -> Vec<Point> {
// let mut targets: Vec<Point> = cells_to_eat.iter().map(|p| p.clone()).collect();
while let Some(p) = targets.iter().next().cloned() {
targets.remove(&p);
let mut targets: Vec<&Point> = cells_to_eat.iter().collect();
let mut open_list: HashSet<Snake> = HashSet::new();
let mut path: Vec<Point> = Vec::new();
let mut initial_snake = initial_snake.clone();
while let Some(target) = targets.pop() {
// prepare
let mut open_list: HashSet<(Snake, Vec<Point>)> = HashSet::new();
open_list.insert((initial_snake.clone(), Vec::new()));
while let Some(x) = open_list.iter().next().cloned() {
open_list.remove(&x);
let snake = x.0;
let mut sub_path = x.1;
if get_snake_head(&snake) == *target {
path.append(&mut sub_path);
initial_snake = snake;
break;
}
for dir in DIRECTIONS {
if {
let h = get_next_snake_head(&snake, &dir);
grid.get_cell(&h) <= walkable
} && !snake_will_self_collide(&snake, &dir)
{
let mut next_snake = snake.clone();
move_snake(&mut next_snake, &dir);
let mut next_sub_path = sub_path.clone();
next_sub_path.push(dir.clone());
open_list.insert((next_snake, next_sub_path));
}
}
}
}
for dir in DIRECTIONS {}
Vec::new()
path
}