11use std:: collections:: HashSet ;
22
3+ use log:: info;
4+
35use crate :: astar_snake:: get_snake_path;
46use crate :: grid:: { get_distance, Point , WalkableGrid , DIRECTIONS } ;
57use crate :: snake:: Snake ;
@@ -104,6 +106,9 @@ pub fn get_snake_path_to_outside(grid: &WalkableGrid, snake: &[Point]) -> Option
104106 None
105107}
106108
109+ // const MAX_ROUTE_LENGTH: usize = usize::MAX;
110+ const MAX_ROUTE_LENGTH : usize = 160 ;
111+
107112pub fn get_path_to_eat_all (
108113 grid : & WalkableGrid ,
109114 snake : & [ Point ] ,
@@ -130,7 +135,7 @@ pub fn get_path_to_eat_all(
130135
131136 for p in cells_to_eat. iter ( ) {
132137 let max_weight = match best_route. as_ref ( ) {
133- None => usize :: MAX ,
138+ None => MAX_ROUTE_LENGTH ,
134139 Some ( path) => path. len ( ) - snake_length,
135140 } ;
136141
@@ -158,6 +163,52 @@ pub fn get_path_to_eat_all(
158163 }
159164 }
160165
166+ if best_route. is_none ( ) {
167+ if let Some ( p) = best_target_unescapable {
168+ // let's got to the outside
169+ // and check again
170+
171+ let mut path_to_outside = get_snake_path_to_outside ( grid, snake) . unwrap ( ) ;
172+ let outside_direction = {
173+ if path_to_outside[ 0 ] . y < 0 {
174+ Point { x : 0 , y : -1 }
175+ } else if path_to_outside[ 0 ] . y >= grid. grid . height as i8 {
176+ Point { x : 0 , y : 1 }
177+ } else if path_to_outside[ 0 ] . x < 0 {
178+ Point { x : -1 , y : 0 }
179+ } else if path_to_outside[ 0 ] . x >= grid. grid . width as i8 {
180+ Point { x : 1 , y : 0 }
181+ } else {
182+ panic ! ( "not outside" ) ;
183+ }
184+ } ;
185+ for _ in 0 ..( ( snake_length + 1 ) / 2 ) {
186+ let p = Point {
187+ x : path_to_outside[ 0 ] . x + outside_direction. x ,
188+ y : path_to_outside[ 0 ] . y + outside_direction. y ,
189+ } ;
190+ path_to_outside. insert ( 0 , p) ;
191+ }
192+
193+ let snake_outside = & path_to_outside[ 0 ..snake_length] ;
194+ let res = get_snake_path (
195+ |c| grid. is_cell_walkable ( c) ,
196+ snake_outside,
197+ & p,
198+ MAX_ROUTE_LENGTH ,
199+ ) ;
200+
201+ if let Some ( mut sub_path) = res {
202+ let next_snake = & sub_path[ 0 ..snake_length] ;
203+ if can_snake_reach_outside ( grid, next_snake) {
204+ sub_path. truncate ( sub_path. len ( ) - snake_length) ;
205+ sub_path. append ( & mut path_to_outside) ;
206+ best_route = Some ( sub_path) ;
207+ }
208+ }
209+ }
210+ }
211+
161212 if let Some ( mut sub_path) = best_route {
162213 let eaten = sub_path[ 0 ] ;
163214
@@ -166,35 +217,6 @@ pub fn get_path_to_eat_all(
166217 sub_path. truncate ( sub_path. len ( ) - snake_length) ;
167218 sub_path. append ( & mut path) ;
168219 path = sub_path;
169- } else if let Some ( p) = best_target_unescapable {
170- // let's got to the outside
171- // and check again
172-
173- let mut path_to_outside = get_snake_path_to_outside ( grid, snake) . unwrap ( ) ;
174- let outside_direction = {
175- if path_to_outside[ 0 ] . y < 0 {
176- Point { x : 0 , y : -1 }
177- } else if path_to_outside[ 0 ] . y >= grid. grid . height as i8 {
178- Point { x : 0 , y : 1 }
179- } else if path_to_outside[ 0 ] . x < 0 {
180- Point { x : -1 , y : 0 }
181- } else if path_to_outside[ 0 ] . x >= grid. grid . width as i8 {
182- Point { x : 1 , y : 0 }
183- } else {
184- panic ! ( "not outside" ) ;
185- }
186- } ;
187- for _ in 0 ..snake_length {
188- let p = Point {
189- x : path_to_outside[ 0 ] . x + outside_direction. x ,
190- y : path_to_outside[ 0 ] . y + outside_direction. y ,
191- } ;
192- path_to_outside. insert ( 0 , p) ;
193- }
194-
195- log:: info!( "unescapable {:?} " , p) ;
196- panic ! ( "impossible to path to cell to eat" ) ;
197- //
198220 } else {
199221 panic ! ( "impossible to path to cell to eat" ) ;
200222 }
0 commit comments