def path_to_move_actions(game: botbowl.Game,
                         player: botbowl.Player,
                         path: Path,
                         do_assertions=True) -> List[Action]:
    """
    This function converts a path into a list of actions corresponding to that path.
    If you provide a handoff, foul or blitz path, then you have to manally set action type.
    :param game:
    :param player: player to move
    :param path: a path as returned by the pathfinding algorithms
    :param do_assertions: if False, it turns off the validation, can be helpful when the GameState will change before
                          this path is executed.
    :returns: List of actions corresponding to 'path'.
    """

    if path.block_dice is not None:
        action_type = ActionType.BLOCK
    elif path.handoff_roll is not None:
        action_type = ActionType.HANDOFF
    elif path.foul_roll is not None:
        action_type = ActionType.FOUL
    else:
        action_type = ActionType.MOVE

    active_team = game.state.available_actions[0].team
    player_at_target = game.get_player_at(path.get_last_step())

    if do_assertions:
        if action_type is ActionType.MOVE:
            assert player_at_target is None or player_at_target is game.get_active_player(
            )
        elif action_type is ActionType.BLOCK:
            assert game.get_opp_team(active_team) is player_at_target.team
            assert player_at_target.state.up
        elif action_type is ActionType.FOUL:
            assert game.get_opp_team(active_team) is player_at_target.team
            assert not player_at_target.state.up
        elif action_type is ActionType.HANDOFF:
            assert active_team is player_at_target.team
            assert player_at_target.state.up
        else:
            raise Exception(f"Unregonized action type {action_type}")

    final_action = Action(action_type, position=path.get_last_step())

    if game._is_action_allowed(final_action):
        return [final_action]
    else:
        actions = []
        if not player.state.up and path.steps[0] == player.position:
            actions.append(Action(ActionType.STAND_UP, player=player))
            actions.extend(
                Action(ActionType.MOVE, position=sq)
                for sq in path.steps[1:-1])
        else:
            actions.extend(
                Action(ActionType.MOVE, position=sq) for sq in path.steps[:-1])
        actions.append(final_action)
        return actions
Exemple #2
0
    def move_actions(self, game: botbowl.Game,
                     action_choice) -> ActionProbList:
        if game.get_player_action_type(
        ) in self.player_actiontypes_without_move_actions:
            return []

        action_probs = []

        player = game.get_active_player()
        ball_carrier = game.get_ball_carrier()
        is_ball_carrier = player is game.get_ball_carrier()

        if player.state.moves > 0 and not is_ball_carrier:
            return []
        elif is_ball_carrier and player.state.moves > 0:
            action_probs.append((Action(ActionType.END_PLAYER_TURN), 1))

        ball = game.get_ball()

        ball_on_floor_pos = game.get_ball(
        ).position if not ball.is_carried else None
        opp_ball_carrier = ball_carrier if ball_carrier is not None and ball_carrier.team is not game.active_team else None

        is_home = player.team is game.state.home_team

        for pos in action_choice.positions:
            prob = 1
            if ball_on_floor_pos is not None:
                if pos == ball_on_floor_pos:
                    prob = 3
                elif pos.distance(ball_on_floor_pos) == 1:
                    prob = 2
            elif opp_ball_carrier is not None and pos.distance(
                    opp_ball_carrier.position):
                prob = 2

            elif is_ball_carrier and game.arena.is_in_opp_endzone(
                    pos, is_home):
                prob = 2

            action = Action(ActionType.MOVE, position=pos)
            action_probs.append((action, prob))

        return action_probs
Exemple #3
0
def expand_bounce(game: botbowl.Game, parent: Node) -> Node:
    # noinspection PyTypeChecker
    active_proc: procedures.Bounce = game.get_procedure()
    assert type(active_proc) is procedures.Bounce

    new_parent = ChanceNode(game, parent)

    ball_pos = active_proc.piece.position

    active_player = game.get_active_player()
    adj_squares = game.get_adjacent_squares(ball_pos, occupied=False)
    sq_to_num_tz = {
        sq: game.num_tackle_zones_at(active_player, sq)
        for sq in adj_squares
    }
    num_tz_to_sq = {}

    for sq, num_tz in sq_to_num_tz.items():
        num_tz_to_sq.setdefault(num_tz, []).append(sq)

    for num_tz, count in Counter(sq_to_num_tz.values()).items():
        possible_squares = num_tz_to_sq[num_tz]
        square = np.random.choice(possible_squares, 1)[0]
        assert type(square) == botbowl.Square

        delta_x = square.x - ball_pos.x
        delta_y = square.y - ball_pos.y

        roll = botbowl.D8.d8_from_xy[(delta_x, delta_y)]
        with only_fixed_rolls(game, d8=[roll]):
            game.step()
        new_node = expand_none_action(game, new_parent)
        new_parent.connect_child(new_node, prob=count / 8)
        assert game.get_step() == new_parent.step_nbr

    sum_prob = sum(new_parent.child_probability)
    new_parent.child_probability = [
        prob / sum_prob for prob in new_parent.child_probability
    ]

    assert sum(new_parent.child_probability) == approx(1.0, abs=1e-9)
    assert game.get_step() == new_parent.step_nbr
    return new_parent