1
1
use std:: collections:: HashSet ;
2
2
3
+ use log:: info;
4
+
3
5
use crate :: astar_snake:: get_snake_path;
4
6
use crate :: grid:: { get_distance, Point , WalkableGrid , DIRECTIONS } ;
5
7
use crate :: snake:: Snake ;
@@ -104,6 +106,9 @@ pub fn get_snake_path_to_outside(grid: &WalkableGrid, snake: &[Point]) -> Option
104
106
None
105
107
}
106
108
109
+ // const MAX_ROUTE_LENGTH: usize = usize::MAX;
110
+ const MAX_ROUTE_LENGTH : usize = 160 ;
111
+
107
112
pub fn get_path_to_eat_all (
108
113
grid : & WalkableGrid ,
109
114
snake : & [ Point ] ,
@@ -130,7 +135,7 @@ pub fn get_path_to_eat_all(
130
135
131
136
for p in cells_to_eat. iter ( ) {
132
137
let max_weight = match best_route. as_ref ( ) {
133
- None => usize :: MAX ,
138
+ None => MAX_ROUTE_LENGTH ,
134
139
Some ( path) => path. len ( ) - snake_length,
135
140
} ;
136
141
@@ -158,6 +163,52 @@ pub fn get_path_to_eat_all(
158
163
}
159
164
}
160
165
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
+
161
212
if let Some ( mut sub_path) = best_route {
162
213
let eaten = sub_path[ 0 ] ;
163
214
@@ -166,35 +217,6 @@ pub fn get_path_to_eat_all(
166
217
sub_path. truncate ( sub_path. len ( ) - snake_length) ;
167
218
sub_path. append ( & mut path) ;
168
219
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
- //
198
220
} else {
199
221
panic ! ( "impossible to path to cell to eat" ) ;
200
222
}
0 commit comments