def test_wheel_timer(): task_data = Path(utils.project_root() / 'tasks' / 'part-0-mock' / 'wheels.desc').read_text() task = GridTask(Task.parse(task_data)) actionlist = ('QQDD' + 'F' + 'ZZZZZZZZZZZZZZZZZZZZ' + 'F' + 'ZZZZZZZZZZZZZZZZZZZZ' + 'ZZZZZZZZZ' + 'ZZZZZZZZZZZZZZZZZZZZ' + 'ZZZZZZZZZZZZZZZZZZZZ' + 'ZZZZZZZZZZ' + 'D') game = Game(task) for a in actionlist: game.apply_action(Action.simple(a)) solution = compose_actions(game.get_actions()) expected_score = game.finished() assert expected_score is None game = Game(task) for a in actionlist: game.apply_action(Action.simple(a)) game.apply_action(Action.WSAD('D')) solution = compose_actions(game.get_actions()) expected_score = game.finished() er = validate.run(task_data, solution) assert er.time is not None assert er.time == expected_score
def run_one_bot_game(actions: List[Action]): task_data = Path(utils.project_root() / 'tasks' / 'part-0-mock' / 'prob-2003.desc').read_text() task = GridTask(Task.parse(task_data)) game = Game(task) for a in actions: game.apply_action(a) solution = compose_actions(game.get_actions()) expected_score = game.finished() er = validate.run(task_data, solution) assert er.time is not None assert er.time == expected_score
def solve(task: Task, max_depth) -> Tuple[int, List[List[Action]], dict]: task = GridTask(task) game = Game(task) while not game.finished(): while game.inventory['B'] > 0: logger.info('attach extension') game.apply_action(Action.attach(1, len(game.bots[0].manipulator) - 2)) action = get_action(game, max_depth) game.apply_action(action) score = game.finished() logger.info(game.inventory) extra = dict(final_manipulators = len(game.bots[0].manipulator)) return score, game.get_actions(), extra
def run_cloned_game(actions: List[List[Action]]): task_data = Path(utils.project_root() / 'tasks' / 'part-0-mock' / 'prob-2003.desc').read_text() task = GridTask(Task.parse(task_data)) game = Game(task) indices = [0] * len(actions) current = 0 while not game.finished(): if current == 0: botcount = len(game.bots) i = indices[current] game.apply_action(actions[current][i], current) indices[current] += 1 current = (current + 1) % botcount solution = compose_actions(game.get_actions()) expected_score = game.finished() er = validate.run(task_data, solution) assert er.time is not None assert er.time == expected_score
def solve(task: Task, max_depth) -> Tuple[int, List[List[Action]], dict]: task = GridTask(task) game = Game(task) st_root = game.bots[0].pos spanning_tree = calculate_spanning_tree(game, st_root) target = None while not game.finished(): while game.inventory['B'] > 0: logger.info('attach extension') action = attach_lined(game) wrap_updates = game.apply_action(action) for p in wrap_updates: assert game.is_wrapped(p) spanning_tree[p].wrap() bot = game.bots[0] if target is None: target = spanning_tree[bot.pos].get_next_unwrapped().pos distfield = calculate_distance_field(game, target, bot.pos) #print_distfield(game, distfield) action = get_action(game, max_depth, distfield, target) assert action wrap_updates = game.apply_action(action) for p in wrap_updates: assert game.is_wrapped(p) spanning_tree[p].wrap() if game.is_wrapped(target): target = None score = game.finished() logger.info(game.inventory) extra = dict(final_manipulators=len(game.bots[0].manipulator)) return score, game.get_actions(), extra
def solve(self, task: str) -> SolverResult: task = Task.parse(task) task = GridTask(task) game = Game(task) if not game.clone_spawn: return SolverResult(data=Pass(), expected_score=None, extra=dict(reason='no clone spawns')) if not game.inventory['C'] and not game.map_contains_booster('C'): return SolverResult(data=Pass(), expected_score=None, extra=dict(reason='no clone boosters')) cnt = 0 while not game.finished(): cnt += 1 if cnt % 200 == 0: logging.info( f'{len(game.bots)} bots; {game.remaining_unwrapped} unwrapped' ) used_bots = [False for bot in game.bots] actions = [None for bot in game.bots] orig_bots = game.bots[:] if game.clone_spawn and game.inventory['C']: logging.info('need spawn') df = DistanceField(game.grid) df.build(game.clone_spawn) dist = df.dist best_rank = 1e10 best_bot = None best_action = None for bot_index, bot in enumerate(orig_bots): if dist[bot.pos] == 0: continue for d, a in Action.DIRS.items(): p = bot.pos + d if not game.grid.in_bounds(p): continue rank = dist[p] if rank < best_rank: best_rank = rank best_bot = bot_index best_action = a #assert best_bot is not None #game.apply_action(best_action, best_bot) if best_bot is not None: actions[best_bot] = best_action used_bots[best_bot] = True boosters = [b.pos for b in game.boosters if b.code == 'C'] if not game.finished() and game.clone_spawn and not game.inventory[ 'C'] and boosters and not all(used_bots): df = DistanceField(game.grid) df.build(boosters) dist = df.dist best_rank = 1e10 best_bot = None best_action = None for bot_index, bot in enumerate(orig_bots): if used_bots[bot_index]: continue for d, a in Action.DIRS.items(): p = bot.pos + d if not game.grid.in_bounds(p): continue rank = dist[p] if rank < best_rank: best_rank = rank best_bot = bot_index best_action = a assert best_bot is not None actions[best_bot] = best_action used_bots[best_bot] = True if game.finished(): break df = DistanceField(game.grid) starts = list_unwrapped(game._wrapped) df.build(starts) dist = df.dist for bot_index, bot in enumerate(orig_bots): if game.finished(): break if used_bots[bot_index]: game.apply_action(actions[bot_index], bot_index) continue if game.inventory['C'] and bot.pos in game.clone_spawn: game.apply_action(Action.clone(), bot_index) logging.info('clone!!!') continue if game.inventory['B'] > 0: logger.info('attach extension') game.apply_action( Action.attach(1, len(game.bots[0].manipulator) - 2)) continue best_rank = 1e10 best_action = None for d, a in Action.DIRS.items(): p = bot.pos + d if not game.grid.in_bounds(p): continue rank = dist[p] for j, bot2 in enumerate(orig_bots): if j < bot_index: d = bot.pos.manhattan_dist(bot2.pos) rank += 10 * max(0, 30 - d) if rank < best_rank: best_rank = rank best_action = a assert best_action is not None game.apply_action(best_action, bot_index) expected_score = score = game.finished() extra = dict(final_bots=len(game.bots)) return SolverResult(data=compose_actions(game.get_actions()), expected_score=expected_score, extra=extra)
def solve(game: Game, params: dict) -> Tuple[Optional[int], List[List[Action]], dict]: cnt = 0 params['booster_count'] = sum(1 for b in game.boosters if b.code == 'B') map_center = Pt(game.grid.width // 2, game.grid.height // 2) teleport_list = [] while not game.finished(): cnt += 1 if cnt % 1000 == 0: logging.info(f'{game.remaining_unwrapped} unwrapped') bot = game.bots[0] extensions = { b.pos for b in game.boosters if b.code in params['boostlist'] } prev = {bot.pos: None} frontier = [bot.pos] # searching target depth = 0 while frontier: best_rank = 0 dst = None for p in frontier: rank = 0 if p in extensions: rank += 5 for m in bot.manipulator: q = p + m if (game.in_bounds(q) and game.grid[q] == '.' and not game.is_wrapped(q) and visible(game.grid, q, p)): rank += 1 if rank > best_rank: best_rank = rank dst = p if dst is not None: break new_frontier = [] if depth == 0 and 'R' in params['boostlist']: new_frontier = teleport_list[:] for p in new_frontier: prev[p] = bot.pos for p in frontier: for d in Action.DIRS.keys(): p2 = p + d if (p2 not in prev and game.in_bounds(p2) and (game.grid[p2] == '.' or bot.drill_timer - depth > 0)): prev[p2] = p new_frontier.append(p2) frontier = new_frontier depth += 1 assert dst is not None assert dst != bot.pos # teleport if 'R' in params['boostlist'] and game.inventory['R'] > 0: if map_center.manhattan_dist( bot.pos) < map_center.manhattan_dist(dst): game.apply_action(Action.reset()) logger.info('reset teleport') teleport_list.append(bot.pos) # gathering path path = [] p = dst while p != bot.pos: d = p - prev[p] if d not in Action.DIRS.keys(): assert 'R' in params['boostlist'] and p in teleport_list path.append(Action.teleport(p.x, p.y)) logger.info('teleport away') else: path.append(Action.DIRS[d]) p = prev[p] assert p is not None path.reverse() assert depth == len(path), (depth, len(path)) for a in path: game.apply_action(a) if params['best score'] is not None and game.turn >= params[ 'best score']: return None, [], {} # boosters if game.inventory['B'] > 0: logger.info('attach extension') params['attach func'](game, params, 0) if 'L' in params['boostlist'] and game.inventory['L'] > 0: logger.info('use drill') game.apply_action(Action.drill()) score = game.finished() logger.info(game.inventory) extra = dict(final_manipulators=len(game.bots[0].manipulator)) return score, game.get_actions(), extra
def solve(task: Task, turns: str, bestscore=None) -> Tuple[Optional[int], List[List[Action]], dict]: task = GridTask(task) game = Game(task) cnt = 0 for t in turns: game.apply_action(Action.simple(t)) while not game.finished(): cnt += 1 if cnt % 1000 == 0: logging.info(f'{game.remaining_unwrapped} unwrapped') extensions = {b.pos for b in game.boosters if b.code == 'B'} prev = {game.bots[0].pos: None} frontier = [game.bots[0].pos] while frontier: best_rank = 0 dst = None for p in frontier: rank = 0 if p in extensions: rank += 5 rank += len( manipulators_will_wrap(game.grid, game._wrapped, p, game.bots[0].manipulator)) if rank > best_rank: best_rank = rank dst = p if dst is not None: break new_frontier = [] for p in frontier: for d in Action.DIRS.keys(): p2 = p + d if (p2 not in prev and game.in_bounds(p2) and game.grid[p2] == '.'): prev[p2] = p new_frontier.append(p2) frontier = new_frontier assert dst is not None assert dst != game.bots[0].pos path = [] p = dst while p != game.bots[0].pos: d = p - prev[p] path.append(Action.DIRS[d]) p = prev[p] assert p is not None path.reverse() for a in path: game.apply_action(a) if bestscore is not None and game.turn >= bestscore: return None, [], {} if game.inventory['B'] > 0: logger.info('attach extension') attach_to = Pt(1, len(game.bots[0].manipulator) - 2) for t in turns: attach_to = turn_pt(attach_to, t) game.apply_action(Action.attach(attach_to.x, attach_to.y)) score = game.finished() logger.info(game.inventory) extra = dict(final_manipulators=len(game.bots[0].manipulator)) return score, game.get_actions(), extra
def interactive(task_number): task_data = utils.get_problem_raw(task_number) use_db = task_number <= 999 if use_db: conn = db.get_conn() cur = conn.cursor() cur.execute( ''' SELECT id, data FROM tasks WHERE name = %s ''', [f'prob-{task_number:03d}']) [task_id, task_data_db] = cur.fetchone() task_data_db = zlib.decompress(task_data_db).decode() assert task_data_db == task_data task = GridTask(Task.parse(task_data)) game = Game(task) score = None with contextlib.closing(Display(game)) as display: code, c = '', '' display.draw_initial(game) while not score: display.draw(game, f'lastchar = {code} {c!r}') code = display.stdscr.getch() action = None c = chr(code).upper() if c in '\x1B': break if c in Action.SIMPLE: action = Action.simple(c) # to perform complex action type it without spaces: B(1,-1) elif c in Action.PARAM: while c[-1] != ')': code = display.stdscr.getch() c = c + chr(code).upper() action = Action.parameterized(c) if display.current == 0: botcount = len(game.bots) if action: try: game.apply_action(action, display.current) except InvalidActionException as exc: display.draw_error(str(exc)) else: display.current = (display.current + 1) % botcount score = game.finished() if score is not None: print(f'Score: {score}') result = validate_replay(task_data, score, game.get_actions()) print(result) if use_db: submit_replay(conn, task_id, result) else: mock_solutions = utils.project_root( ) / 'outputs' / 'mock_solutions' mock_solutions.mkdir(parents=True, exist_ok=True) with mock_solutions / f'prob-{task_number}.sol' as fin: fin.write_text(result.solution)
def solve(task: Task) -> Tuple[int, List[List[Action]], dict]: task = GridTask(task) game = Game(task) cnt = 0 while not game.finished(): cnt += 1 if cnt % 1000 == 0: logging.info(f'{game.remaining_unwrapped} unwrapped') prev = {game.bots[0].pos: None} frontier = [game.bots[0].pos] while frontier: best_rank = 0 dst = None for p in frontier: rank = len( manipulators_will_wrap(game.grid, game._wrapped, p, game.bots[0].manipulator)) if rank > best_rank: best_rank = rank dst = p if dst is not None: break new_frontier = [] for p in frontier: for d in Action.DIRS.keys(): p2 = p + d if (p2 not in prev and game.in_bounds(p2) and game.grid[p2] == '.'): prev[p2] = p new_frontier.append(p2) frontier = new_frontier assert dst is not None assert dst != game.bots[0].pos path = [] p = dst while p != game.bots[0].pos: d = p - prev[p] path.append(Action.DIRS[d]) p = prev[p] assert p is not None path.reverse() for a in path: game.apply_action(a) if game.inventory['B'] > 0: logger.info('attach extension') game.apply_action( Action.attach(1, len(game.bots[0].manipulator) - 2)) score = game.finished() logger.info(game.inventory) extra = dict(final_manipulators=len(game.bots[0].manipulator)) return score, game.get_actions(), extra