示例#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
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
示例#3
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
示例#5
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
示例#6
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)
示例#7
0
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
示例#8
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
示例#9
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)
示例#10
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