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
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
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