@@ -96,6 +96,7 @@ pub struct State<'a> {
9696 valid : Matrix < bool > ,
9797 passed : Matrix < bool > ,
9898 booster_map : Matrix < Option < BoosterType > > ,
99+ remaining_hand : usize ,
99100 remaining_clone : usize ,
100101 remaining_pass : usize ,
101102 hand_count : usize ,
@@ -112,6 +113,7 @@ impl<'a> State<'a> {
112113 let height = task. height ;
113114
114115 let mut remaining_pass = 0 ;
116+ let mut remaining_hand = 0 ;
115117 let mut remaining_clone = 0 ;
116118 let mut booster_map = Matrix :: new ( width, height, None ) ;
117119 let mut passed = Matrix :: new ( width, height, true ) ;
@@ -125,8 +127,10 @@ impl<'a> State<'a> {
125127
126128 for b in & task. boosters {
127129 booster_map. set ( b. point , Some ( b. kind . clone ( ) ) ) ;
128- if let BoosterType :: Cloning = b. kind {
129- remaining_clone += 1 ;
130+ match b. kind {
131+ BoosterType :: Cloning => remaining_clone += 1 ,
132+ BoosterType :: NewHand => remaining_hand += 1 ,
133+ _ => { }
130134 }
131135 }
132136
@@ -156,6 +160,7 @@ impl<'a> State<'a> {
156160 valid,
157161 passed,
158162 booster_map,
163+ remaining_hand,
159164 remaining_clone,
160165 remaining_pass,
161166 hand_count,
@@ -167,37 +172,50 @@ impl<'a> State<'a> {
167172
168173 fn is_goal ( & self , robot_idx : usize , goal : Point ) -> bool {
169174 if self . remaining_clone > 0 {
170- match self . booster_map . get ( goal) {
175+ return match self . booster_map . get ( goal) {
171176 Some ( Some ( BoosterType :: Cloning ) ) => true ,
172177 _ => false ,
173- }
174- } else if self . clone_count > 0 {
175- match self . booster_map . get ( goal) {
176- Some ( Some ( BoosterType :: Spawn ) ) => true ,
177- _ => false ,
178- }
179- } else {
180- let not_passed = self . robots [ robot_idx]
181- . bodies_diff
182- . iter ( )
183- . map ( |diff| goal + * diff)
184- . any ( |p| match self . passed . get ( p) {
185- Some ( false ) => true ,
186- _ => false ,
187- } ) ;
188-
189- let is_booster = match self . booster_map . get ( goal) {
190- Some ( Some ( BoosterType :: NewHand ) ) => true ,
191- _ => false ,
192178 } ;
179+ }
193180
194- let is_valid = match self . valid . get ( goal) {
195- Some ( true ) => true ,
181+ if self . clone_count > 0 {
182+ return match self . booster_map . get ( goal) {
183+ Some ( Some ( BoosterType :: Spawn ) ) => true ,
196184 _ => false ,
197185 } ;
186+ }
198187
199- is_valid && ( not_passed || is_booster)
188+ if self . remaining_hand > 0 {
189+ if let Some ( ( first_robot_index, _) ) = self . robots . iter ( ) . enumerate ( ) . find ( |( _, r) | !r. new_bodies . is_empty ( ) ) {
190+ if robot_idx == first_robot_index {
191+ return match self . booster_map . get ( goal) {
192+ Some ( Some ( BoosterType :: NewHand ) ) => true ,
193+ _ => false ,
194+ } ;
195+ }
196+ }
200197 }
198+
199+ let not_passed = self . robots [ robot_idx]
200+ . bodies_diff
201+ . iter ( )
202+ . map ( |diff| goal + * diff)
203+ . any ( |p| match self . passed . get ( p) {
204+ Some ( false ) => true ,
205+ _ => false ,
206+ } ) ;
207+
208+ let is_booster = match self . booster_map . get ( goal) {
209+ Some ( Some ( BoosterType :: NewHand ) ) => true ,
210+ _ => false ,
211+ } ;
212+
213+ let is_valid = match self . valid . get ( goal) {
214+ Some ( true ) => true ,
215+ _ => false ,
216+ } ;
217+
218+ is_valid && ( not_passed || is_booster)
201219 }
202220
203221 fn find_shortest_path ( & self , robot_idx : usize , start : Point ) -> Option < Vec < Move > > {
@@ -255,6 +273,7 @@ impl<'a> State<'a> {
255273 if let Some ( Some ( kind) ) = self . booster_map . get ( current_point) {
256274 match kind {
257275 BoosterType :: NewHand => {
276+ self . remaining_hand -= 1 ;
258277 self . hand_count += 1 ;
259278 self . booster_map . set ( current_point, None ) ;
260279 }
0 commit comments