Example #1
0
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
Example #2
0
    def solve(self, task: str) -> SolverResult:
        task = Task.parse(task)
        min_score = None
        min_actions = []
        min_extra = {}

        turnlist = [[]]
        if self.turns:
            turnlist += [[Action.turnCCW()],
                         [Action.turnCCW(), Action.turnCCW()],
                         [Action.turnCW()]]

        # turnlist = [[Action.turnCW()]]

        for turns in turnlist:
            game = Game(GridTask(task))
            for t in turns:
                game.apply_action(t)

            expected_score, actions, extra = solve(game, min_score)
            if expected_score is None:
                # solution has exceeded the best score and stopped
                continue
            if min_score is None or expected_score < min_score:
                min_score, min_actions, min_extra = expected_score, actions, extra
        return SolverResult(data=compose_actions(min_actions),
                            expected_score=min_score,
                            extra=min_extra)
Example #3
0
def run_for_errors(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)
    try:
        for a in actions:
            game.apply_action(a)
    except InvalidActionException:
        return
    else:
        assert False
Example #4
0
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
Example #5
0
def main():
    s = Path(utils.project_root() / 'tasks' / 'part-1-initial' /
             'prob-145.desc').read_text()
    solver = BoostySolver([])
    t = time()
    sol = solver.solve(s)
    print(f'time elapsed: {time() - t:.4}')
    print(sol)
    task = Task.parse(s)
    score, sol, _ = solve(Game(GridTask(task)))
    print("score:", score)
    sol = compose_actions(sol)
    print(sol)
    print(len(sol), 'time units')
    sol_path = Path(utils.project_root() / 'outputs' / 'example-01-boosty.sol')
    sol_path.write_text(sol)
    print('result saved to', sol_path)
Example #6
0
    def solve(self, task: str) -> SolverResult:
        task = Task.parse(task)
        min_score = None
        # min_actions = []
        # min_extra = {}

        turnlist = {
            'Eastborne': [],
            'Nordish': [Action.turnCCW()],
            'Westerling': [Action.turnCCW(),
                           Action.turnCCW()],
            'Southerner': [Action.turnCW()]
        }

        params = {}
        params['boostlist'] = 'B'
        if self.drill:
            params['boostlist'] += 'L'
        if self.teleport:
            params['boostlist'] += 'R'

        params['attach func'] = manip_configs[self.manipconf]

        for direction in turnlist:
            logger.info(f'{direction} started working')
            params['best score'] = min_score

            game = Game(GridTask(task))
            for t in turnlist[direction]:
                game.apply_action(t)

            expected_score, actions, extra = solve(game, params)
            logger.info(f'{direction} finished with {expected_score} score')
            if expected_score is None:
                # solution has exceeded the best score and stopped
                continue

            if min_score is None or expected_score < min_score:
                min_score, min_actions, min_extra = expected_score, actions, extra

        return SolverResult(data=compose_actions(min_actions),
                            expected_score=min_score,
                            extra=min_extra)
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
Example #8
0
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
Example #10
0
    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)
Example #11
0
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
Example #12
0
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)
Example #13
0
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