|
1 | 1 | use std::collections::HashSet; |
2 | 2 |
|
3 | 3 | 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 | +}; |
5 | 7 |
|
6 | 8 | pub fn get_route_to_eat_all( |
7 | 9 | grid: &Grid, |
8 | 10 | walkable: Cell, |
9 | 11 | initial_snake: &Snake, |
10 | 12 | 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(); |
13 | 15 |
|
14 | | - while let Some(p) = targets.iter().next().cloned() { |
15 | | - targets.remove(&p); |
| 16 | + let mut targets: Vec<&Point> = cells_to_eat.iter().collect(); |
16 | 17 |
|
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 | + } |
18 | 55 | } |
19 | | - for dir in DIRECTIONS {} |
20 | | - Vec::new() |
| 56 | + |
| 57 | + path |
21 | 58 | } |
0 commit comments