def auto_command_finish(self): # If the traceback does not exist then it means the bot has not found a path. if not self.traceback: return False new_player, old_player = self.traceback[-1] if self.player_location == old_player: # Push the boulder. proximal = new_player self.traceback.pop() else: # Move next to the boulder. slow_neighbor_transition = SlowNeighborTransition(self, self) loc_to_dist = AscDP.measure_all_targets([old_player], [self.player_location], slow_neighbor_transition) assert self.player_location in loc_to_dist, error_message path = AscDP.get_path(self.player_location, slow_neighbor_transition, loc_to_dist) assert len(path) > 1, error_message proximal = path[1] row, col = self.player_location nrow, ncol = proximal drow = nrow - row dcol = ncol - col delta = (drow, dcol) move_result = self.move_player(delta) if not self.traceback: self.invalidate() return move_result
def do_curses_demo(stdscr): # do not wait for a keypress when using getch() stdscr.nodelay(1) # create the subscreen to leave room at the top for a message sokoban_screen = stdscr.subpad(1, 0) # solve each level for level_string, level_name in all_level_strings_and_names: # load the list of boulder pushes from the file push_list = load_push_sequence(level_name) # all of the soko files should exist when this function is called assert push_list # load the level level = SokoMap(level_string, level_name) # show the level name on the top row stdscr.addstr(0, 0, level_name) stdscr.refresh() # play the level automatically push_index = 0 while True: # quit if a key is pressed during the demo # note that getch() usually waits for a keypress, # but this has been disabled on stdscr by the nodelay(1) call. if stdscr.getch() != -1: return # show the initial move or the result of the last move level.draw_to_curses_screen(sokoban_screen) sokoban_screen.refresh() # pause between animation frames time.sleep(.1) # if we win then go to the next level if level.is_solved(): break # are we at the square that allows us to push yet? rowa, cola, rowb, colb = push_list[push_index] drow = rowb - rowa dcol = colb - cola target_player_location = (rowa, cola) player_location = level.player_location if player_location == target_player_location: # push the boulder delta = (drow, dcol) level.move_player(delta) push_index += 1 else: # move the player in the direction of the target player location slow_neighbor_transition = SlowNeighborTransition(level, level) loc_to_dist = AscDP.measure_all_targets([target_player_location], [level.player_location], slow_neighbor_transition) path = AscDP.get_path(level.player_location, slow_neighbor_transition, loc_to_dist) best_loc = path[1] row, col = player_location nrow, ncol = best_loc delta = (nrow - row, ncol - col) level.move_player(delta) # clear the screen to prepare to show the new level map and map name stdscr.clear() stdscr.refresh()