示例#1
0
def do_player_action_transport_goods(game: Game, player_id: int,
                                     destination_id: int) -> None:
    """Transport 1 freight unit from the current location to the destination location. 

    Args:
        game (Game): [description]
        player_id (int): [description]
        destination_id (int): [description]

    Raises:
        InvalidActionException: If the action is not feasible with the given parameters.
    """
    player = game._get_player_by_id(player_id)
    node = game._get_node_by_id(player.location_id)
    target_node = game._get_node_by_id(destination_id)
    action_cost = 1
    if node.damage == 2:
        action_cost = 2
    if node.freight < 1:
        raise InvalidActionException(player)
    if node.damage >= 3:
        raise InvalidActionException(player)
    if action_cost > player.actions_left:
        raise InvalidActionException(player)
    player.actions_left -= (
        action_cost - 1
    )  # add one because every action automatically cost one action point
    node.freight -= 1
    target_node.freight += 1
    ACTIONS[RUN_ACTION_NAME](game, player_id, destination_id)
示例#2
0
 def test_choose_driver_action(self) -> None:
     g = Game(0)
     a = Agent(g)
     g.nodes[8].damage = 2
     action = a._choose_driver_actions(
         g._get_player_by_id(g.active_player_id))
     self.assertTrue(True)
示例#3
0
 def test_choose_industry_action(self):
     g = Game(0)
     a = Agent(g)
     g._get_node_by_id(g.start_node_id).freight = 3
     g.players[0].location_id = 10
     action = a._choose_industry_actions(
         g._get_player_by_id(g.active_player_id))
     self.assertTrue(True)
示例#4
0
 def test_find_shortest_path(self) -> None:
     g = Game(0)
     a = Agent()
     graph_dict = parse_nodes_to_graph_format(g.nodes)
     result = find_shortest_path(graph_dict, 21, 19)
     print(result)
     flat = flatten_list(result)
     self.assertTrue(True)
示例#5
0
def do_player_action_run(game: Game, player_id: int,
                         destination_id: int) -> None:
    """Move (run) to a neighboring node. 

    Args:
        game (Game): [description]
        player_id (int): Id of the moving player.
        destination_id (int): Id of the destination node. 

    Raises:
        InvalidActionException: If the action is not feasible with the given parameters. 
    """
    player = game._get_player_by_id(player_id)
    player_current_node_id = player.location_id
    if destination_id not in game._get_node_by_id(
            player_current_node_id).neighbors:
        raise InvalidActionException(player)
    player.location_id = destination_id
示例#6
0
def do_player_action_generate_goods(game: Game, player_id: int) -> None:
    """Generate 1 freight unit at the node the player is currently located at. 

    Args:
        game (Game): [description]
        player_id (int): [description]

    Raises:
        InvalidActionException: If the action is not feasible with the given parameters.
    """
    player = game._get_player_by_id(player_id)
    node = game._get_node_by_id(game.start_node_id)
    if player.funds < 2:
        raise InvalidActionException(player)
    if node.freight >= 3:
        raise InvalidActionException(player)
    player.funds -= 2
    node.freight += 1
示例#7
0
def do_player_action_repair(game: Game, player_id: int) -> None:
    """Remove 1 damage point from the node the player is currently located. 

    Args:
        game (Game): [description]
        player_id (int): [description]

    Raises:
        InvalidActionException: If the action is not feasible with the given parameters.
    """
    player = player = game._get_player_by_id(player_id)
    node = game._get_node_by_id(player.location_id)
    if player.funds < 1:
        raise InvalidActionException(player)
    if node.damage < 1:
        raise InvalidActionException(player)
    player.funds += 1
    node.damage -= 1
示例#8
0
def do_player_action_special_flight(game: Game, player_id: int,
                                    destination_id: int) -> None:
    """Special fly to a purple node.

    Args:
        game (Game): [description]
        player_id (int): [description]
        destination_id (int): [description]

    Raises:
        InvalidActionException: If the action is not feasible with the given parameters.
    """
    player = game._get_player_by_id(player_id)
    valid_destination_ids = [
        node.id for node in game.nodes if node.node_type in ['purple']
    ]
    if destination_id not in valid_destination_ids:
        raise InvalidActionException(player)
    game.location_id = destination_id
示例#9
0
def do_player_action_share_resources(game: Game, player_id: int,
                                     target_player_id: int) -> None:
    """Transfer 1 fund to a player that is at the same node. 

    Args:
        game (Game): [description]
        player_id (int): [description]
        target_player_id (int): [description]

    Raises:
        InvalidActionException: If the action is not feasible with the given parameters.
    """
    player = game._get_player_by_id(player_id)
    target_player = game._get_player_by_id(target_player_id)
    if player.funds < 1:
        raise InvalidActionException(player)
    if target_player.location_id != player.location_id:
        raise InvalidActionException(player)
    player.funds -= 1
    target_player.funds += 1
示例#10
0
def do_player_action_coordinate_drivers(game: Game, player_id: int,
                                        target_player_id: int,
                                        destination_id: int) -> None:
    """Use an action point to move one of the driver players when it is not their turn. 

    Args:
        game (Game): [description]
        player_id (int): [description]
        target_player_id (int): [description]
        destination_id (int): [description]

    Raises:
        InvalidActionException: If the action is not feasible with the given parameters.
    """
    player = game._get_player_by_id(player_id)
    target_player = game._get_player_by_id(target_player_id)
    try:
        game.do_player_action_run(target_player_id, destination_id)
    except InvalidActionException as e:
        raise InvalidActionException(player)
示例#11
0
def do_player_action_fly(game: Game, player_id: int,
                         destination_id: int) -> None:
    """Fly to a orange node.

    Args:
        game (Game): [description]
        player_id (int): [description]
        destination_id (int): [description]

    Raises:
        InvalidActionException: If the action is not feasible with the given parameters. 
    """
    player = game._get_player_by_id(player_id)
    player_current_node_id = player.location_id
    valid_destination_ids = [
        node.id for node in game.nodes if node.node_type in ['orange']
    ]
    if destination_id not in valid_destination_ids:
        raise InvalidActionException(player)
    if player.funds < 2:
        raise InvalidActionException(player)
    player.location_id = destination_id
    player.funds -= 2
示例#12
0
def get_valid_player_actions(game: Game, player_id: int) -> list[PlayerAction]:
    """Returns all valid player actions for a given player at the current state of the game. This implementation is brittle and should not be used except for demonstration purpose. 

    Args:
        game (Game): [description]
        player_id (int): [description]

    Returns:
        list[PlayerAction]: List of possible actions for the player. 
    """
    valid_actions = []
    player = game._get_player_by_id(player_id)
    player_node = game._get_node_by_id(player.location_id)
    # PASS
    # passing introduced as 'doing nothing'
    valid_actions.append(
        PlayerAction(game, player_id, ACTIONS[DO_NOTHING_ACTION_NAME]))
    # RUN
    # running to neighboring nodes is always valid
    neighbor_node_ids = player_node.neighbors
    for neighbor_node_id in neighbor_node_ids:
        valid_actions.append(
            PlayerAction(game,
                         player_id,
                         ACTIONS[RUN_ACTION_NAME],
                         parameters={"destination_id": neighbor_node_id}))
    # FLY
    # flying is valid to all orange nodes that are not the players current location
    orange_node_ids = [
        node.id for node in game.nodes if node.node_type in ['orange']
    ]
    if player.location_id in orange_node_ids:
        orange_node_ids.remove(player.location_id)
    # flying costs 2 funds
    if player.funds - 2 >= 0:
        for orange_node_id in orange_node_ids:
            valid_actions.append(
                PlayerAction(game,
                             player_id,
                             ACTIONS[FLY_ACTION_NAME],
                             parameters={"destination_id": orange_node_id}))
    # SPECIAL FLY
    # special flying is valid to all purple nodes that are not the players current location
    purple_node_ids = [
        node.id for node in game.nodes if node.node_type in ['purple']
    ]
    if player.location_id in purple_node_ids:
        purple_node_ids.remove(player.location_id)
    for purple_node_id in purple_node_ids:
        valid_actions.append(
            PlayerAction(game,
                         player_id,
                         ACTIONS[SPECIAL_FLY_ACTION_NAME],
                         parameters={"destination_id": purple_node_id}))
    # TYPE DEPENDENT ACTIONS: DRIVER ACTIONS
    if player.type is PLAYER_TYPE_DRIVER:
        # SHARE RESOuRCES
        # 1 fund can be shared with a player at the same location
        if player.funds - 1 >= 0:
            same_node_player_ids = [
                other_player.id for other_player in game.players
                if other_player.location_id == player.location_id
            ]
            same_node_player_ids.remove(player_id)
            for same_node_player_id in same_node_player_ids:
                valid_actions.append(
                    PlayerAction(
                        game,
                        player_id,
                        ACTIONS[SHARE_RESOURCES_ACTION_NAME],
                        parameters={"target_player_id": same_node_player_id}))
        # REPAIR
        # repair is valid if the current node has damage and 1 fund is available
        if player.funds - 1 >= 0 and player_node.damage > 0:
            valid_actions.append(
                PlayerAction(game, player_id, ACTIONS[REPAIR_ACTION_NAME]))
    # TYPE DEPENDEND ACTIONS: INDUSTRY ACTIONS
    if player.type is PLAYER_TYPE_INDUSTRY:
        # GENERATE GOODS
        # generate goods costs 2 funds and is valid if the current node has less than 2 freight
        if player.funds - 2 >= 0 and player_node.freight < 3:
            valid_actions.append(
                PlayerAction(game, player_id,
                             ACTIONS[GENERATE_GOODS_ACTION_NAME]))
        # TRANSPORT GOODS
        # transport goods is valid if starting node has less than 2 (3) damage and costs 1 (2) AP
        if player_node.freight > 0 and (player_node.damage < 2 or
                                        (player_node.damage == 2
                                         and player.actions_left - 2 >= 0)):
            for node_id in player_node.neighbors:
                valid_actions.append(
                    PlayerAction(game,
                                 player_id,
                                 ACTIONS[TRANSPORT_GOODS_ACTION_NAME],
                                 parameters={"destination_id": node_id}))
    # TYPE DEPENDEND ACTIONS: INVESTOR ACTIONS
    if player.type is PLAYER_TYPE_INVESTOR:
        # SHARE RESOURCES
        # 1 fund can be shared with a player at the same location
        if player.funds - 1 >= 0:
            same_node_player_ids = [
                other_player.id for other_player in game.players
                if other_player.location_id == player.location_id
            ]
            same_node_player_ids.remove(player_id)
            for same_node_player_id in same_node_player_ids:
                valid_actions.append(
                    PlayerAction(
                        game,
                        player_id,
                        ACTIONS[SHARE_RESOURCES_ACTION_NAME],
                        parameters={"target_player_id": same_node_player_id}))
        # COORDINATE DRIVERS
        # TODO: rewrite
        # coordinate drivers is only valid for player type driver and valid move actions
        #driver_player_ids = [player.id for player in game.players if player.type == PLAYER_TYPE_DRIVER]
        #for driver_player_id in driver_player_ids:
        #    valid_driver_move_actions = [player_action for player_action in get_valid_player_actions(game, driver_player_id) if player_action.action.__name__ in ALLOWED_ACTIONS]
        #    for valid_driver_action in valid_driver_move_actions:
        #        valid_actions.append(PlayerAction(game, player_id, valid_driver_action.action, valid_driver_action.parameters))

    return valid_actions
示例#13
0
 def test_parse_nodes_to_graph_format(self) -> None:
     g = Game()
     a = Agent()
     nodes = g.nodes
     graph_dict = a.parse_nodes_to_graph_format(nodes)
     self.assertTrue(True)
示例#14
0
 def test_Game(self) -> None:
     g = Game(random_seed=0, cascade_damage_threshold=5, target_amount=6)
     g.set_agent(Agent(g))
     result = g.play_game()
     self.assertTrue(True)