This commit is contained in:
platane
2025-03-24 21:23:51 +01:00
parent 621d78be60
commit db283098a9
5 changed files with 75 additions and 64 deletions

View File

@@ -48,11 +48,15 @@ impl Grid {
}
}
pub const DIRECTION_RIGHT: Point = Point { x: 1, y: 0 };
pub const DIRECTION_LEFT: Point = Point { x: -1, y: 0 };
pub const DIRECTION_UP: Point = Point { x: 0, y: 1 };
pub const DIRECTION_DOWN: Point = Point { x: 0, y: -1 };
pub const DIRECTIONS: [Point; 4] = [
Point { x: 1, y: 0 },
Point { x: -1, y: 0 },
Point { x: 0, y: 1 },
Point { x: 0, y: -1 },
DIRECTION_RIGHT,
DIRECTION_LEFT,
DIRECTION_UP,
DIRECTION_DOWN,
];
#[test]

View File

@@ -1,5 +1,6 @@
mod grid;
mod snake;
mod snake_compact;
mod snake_walk;
mod solver;

View File

@@ -1,59 +0,0 @@
use crate::grid::Point;
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
pub enum Direction {
Left = 0,
Right = 1,
Up = 2,
Down = 3,
}
fn get_direction_vector(dir: &Direction) -> Point {
match dir {
Direction::Down => Point { x: 0, y: -1 },
Direction::Up => Point { x: 0, y: 1 },
Direction::Left => Point { x: -1, y: 0 },
Direction::Right => Point { x: 1, y: 0 },
}
}
#[derive(Clone)]
pub struct SnakeC {
pub head: Point,
pub body: Vec<Direction>,
}
impl SnakeC {
pub fn get_cells(&self) -> Vec<Point> {
let mut e = self.head.clone();
let mut out = Vec::new();
out.push(e.clone());
for dir in self.body.iter() {
let v = get_direction_vector(dir);
e.x -= v.x;
e.y -= v.y;
out.push(e.clone());
}
out
}
}
#[test]
fn it_should_get_the_snake_cell() {
let s = SnakeC {
head: Point { x: 10, y: 5 },
body: vec![Direction::Up, Direction::Up, Direction::Left],
};
assert_eq!(
s.get_cells(),
vec![
//
Point { x: 10, y: 5 },
Point { x: 10, y: 4 },
Point { x: 10, y: 3 },
Point { x: 11, y: 3 },
]
);
}

View File

@@ -1,6 +1,64 @@
use crate::grid::Point;
use crate::grid::{Point, DIRECTIONS, DIRECTION_DOWN, DIRECTION_LEFT, DIRECTION_UP};
/**
* head is at 0
*/
pub type Snake = Vec<Point>;
pub fn move_snake(s: &mut Snake, dir: &Point) -> () {
let mut e = s.pop().unwrap();
e.x = s[0].x + dir.x;
e.y = s[0].y + dir.y;
s.insert(0, e);
}
pub fn will_self_collide(s: &Snake, dir: &Point) -> bool {
let next_head = Point {
x: s[0].x + dir.x,
y: s[0].y + dir.y,
};
(&s[0..(s.len() - 1)]).contains(&next_head)
}
#[test]
fn it_should_detect_self_collide() {
let mut s = vec![
//
Point { x: 6, y: 0 },
Point { x: 5, y: 0 },
Point { x: 4, y: 0 },
Point { x: 3, y: 0 },
Point { x: 2, y: 0 },
Point { x: 1, y: 0 },
];
move_snake(&mut s, &DIRECTION_UP);
move_snake(&mut s, &DIRECTION_LEFT);
assert_eq!(will_self_collide(&s, &DIRECTION_DOWN), true);
move_snake(&mut s, &DIRECTION_LEFT);
assert_eq!(will_self_collide(&s, &DIRECTION_DOWN), false);
}
#[test]
fn it_should_move_snake() {
let mut s = vec![
//
Point { x: 3, y: 0 },
Point { x: 2, y: 0 },
Point { x: 1, y: 0 },
];
move_snake(&mut s, &DIRECTION_UP);
assert_eq!(
s,
vec![
//
Point { x: 3, y: 1 },
Point { x: 3, y: 0 },
Point { x: 2, y: 0 },
]
);
}

View File

@@ -9,6 +9,13 @@ pub fn get_route_to_eat_all(
initial_snake: &Snake,
cells_to_eat: HashSet<Point>,
) -> Vec<Snake> {
let mut targets = cells_to_eat.clone();
while let Some(p) = targets.iter().next().cloned() {
targets.remove(&p);
let mut open_list: HashSet<Snake> = HashSet::new();
}
for dir in DIRECTIONS {}
Vec::new()
}