def test_robber_possibilities(): red = SimplePlayer(Color.RED) blue = SimplePlayer(Color.BLUE) orange = SimplePlayer(Color.ORANGE) players = [red, blue, orange] state = State(players) # one for each resource tile (excluding desert) assert len(robber_possibilities(state, Color.RED)) == 18 # assert same number of possibilities, b.c. players have no cards. state.board.build_settlement(Color.BLUE, 3, initial_build_phase=True) state.board.build_settlement(Color.ORANGE, 0, initial_build_phase=True) assert len(robber_possibilities(state, Color.RED)) == 18 # assert same number of possibilities, b.c. only one player to rob in this tile player_deck_replenish(state, orange.color, WHEAT) assert len(robber_possibilities(state, Color.RED)) == 18 # now possibilites increase by 1 b.c. we have to decide to steal from blue or orange # Unless desert is (0,0,0)... in which case still at 18... player_deck_replenish(state, blue.color, WHEAT) possibilities = len(robber_possibilities(state, Color.RED)) assert possibilities == 19 or ( possibilities == 18 and state.board.map.land_tiles[(0, 0, 0)].resource is None)
def test_building_settlement_gives_vp(): players = [SimplePlayer(Color.RED), SimplePlayer(Color.BLUE)] state = State(players) build_settlement(state, state.colors[0], 0, True) assert state.player_state["P0_VICTORY_POINTS"] == 1 assert state.player_state["P0_ACTUAL_VICTORY_POINTS"] == 1
def test_play_monopoly_player_steals_cards(): player_to_act = SimplePlayer(Color.RED) player_to_steal_from_1 = SimplePlayer(Color.BLUE) player_to_steal_from_2 = SimplePlayer(Color.ORANGE) players = [player_to_act, player_to_steal_from_1, player_to_steal_from_2] state = State(players) player_deck_replenish(state, player_to_act.color, MONOPOLY) player_deck_replenish(state, player_to_steal_from_1.color, ORE, 3) player_deck_replenish(state, player_to_steal_from_1.color, WHEAT, 1) player_deck_replenish(state, player_to_steal_from_2.color, ORE, 2) player_deck_replenish(state, player_to_steal_from_2.color, WHEAT, 1) action_to_execute = Action(player_to_act.color, ActionType.PLAY_MONOPOLY, ORE) apply_action(state, action_to_execute) assert player_num_resource_cards(state, player_to_act.color, ORE) == 5 assert player_num_resource_cards(state, player_to_steal_from_1.color, ORE) == 0 assert player_num_resource_cards(state, player_to_steal_from_1.color, WHEAT) == 1 assert player_num_resource_cards(state, player_to_steal_from_2.color, ORE) == 0 assert player_num_resource_cards(state, player_to_steal_from_2.color, WHEAT) == 1
def test_cant_buy_more_than_max_card(): players = [SimplePlayer(Color.RED), SimplePlayer(Color.BLUE)] state = State(players) with pytest.raises(ValueError): # not enough money apply_action( state, Action(players[0].color, ActionType.BUY_DEVELOPMENT_CARD, None)) player_deck_replenish(state, players[0].color, SHEEP, 26) player_deck_replenish(state, players[0].color, WHEAT, 26) player_deck_replenish(state, players[0].color, ORE, 26) for i in range(25): apply_action( state, Action(players[0].color, ActionType.BUY_DEVELOPMENT_CARD, None)) # assert must have all victory points assert player_num_dev_cards(state, players[0].color) == 25 assert get_dev_cards_in_hand(state, players[0].color, VICTORY_POINT) == 5 with pytest.raises(ValueError): # not enough cards in bank apply_action( state, Action(players[0].color, ActionType.BUY_DEVELOPMENT_CARD, None)) assert player_num_resource_cards(state, players[0].color) == 3
def test_defeating_your_own_largest_army_doesnt_give_more_vps(): # Arrange: Buy all dev cards players = [SimplePlayer(Color.RED), SimplePlayer(Color.BLUE)] state = State(players) player_deck_replenish(state, players[0].color, SHEEP, 26) player_deck_replenish(state, players[0].color, WHEAT, 26) player_deck_replenish(state, players[0].color, ORE, 26) for i in range(25): apply_action( state, Action(players[0].color, ActionType.BUY_DEVELOPMENT_CARD, None)) assert get_largest_army(state) == (None, None) assert get_actual_victory_points(state, Color.RED) == 5 # Act - Assert play_dev_card(state, Color.RED, KNIGHT) play_dev_card(state, Color.RED, KNIGHT) play_dev_card(state, Color.RED, KNIGHT) assert get_largest_army(state) == (Color.RED, 3) assert get_actual_victory_points(state, Color.RED) == 7 # Act - Assert play_dev_card(state, Color.RED, KNIGHT) assert get_largest_army(state) == (Color.RED, 4) assert get_actual_victory_points(state, Color.RED) == 7
def test_playable_actions(): players = [SimplePlayer(Color.RED), SimplePlayer(Color.BLUE)] state = State(players) actions = generate_playable_actions(state) assert len(actions) == 54 assert actions[0].action_type == ActionType.BUILD_SETTLEMENT
def __init__( self, players: Iterable[Player], seed: int = None, discard_limit: int = 7, vps_to_win: int = 10, catan_map: CatanMap = None, initialize: bool = True, ): """Creates a game (doesn't run it). Args: players (Iterable[Player]): list of players, should be at most 4. seed (int, optional): Random seed to use (for reproducing games). Defaults to None. discard_limit (int, optional): Discard limit to use. Defaults to 7. vps_to_win (int, optional): Victory Points needed to win. Defaults to 10. catan_map (CatanMap, optional): Map to use. Defaults to None. initialize (bool, optional): Whether to initialize. Defaults to True. """ if initialize: self.seed = seed or random.randrange(sys.maxsize) random.seed(self.seed) self.id = str(uuid.uuid4()) self.vps_to_win = vps_to_win self.state = State(players, catan_map, discard_limit=discard_limit)
def test_playable_cards(): player = SimplePlayer(Color.RED) state = State([player]) player_deck_replenish(state, Color.RED, "KNIGHT") player_clean_turn(state, Color.RED) assert player_can_play_dev(state, Color.RED, "KNIGHT")
def test_robber_possibilities_simple(): red = SimplePlayer(Color.RED) blue = SimplePlayer(Color.BLUE) orange = SimplePlayer(Color.ORANGE) players = [red, blue, orange] state = State(players) # one for each resource tile (excluding desert) assert len(robber_possibilities(state, Color.RED)) == 18
def test_building_city_gives_vp(): players = [SimplePlayer(Color.RED), SimplePlayer(Color.BLUE)] state = State(players) build_settlement(state, state.colors[0], 0, True) player_deck_replenish(state, state.colors[0], WHEAT, 2) player_deck_replenish(state, state.colors[0], ORE, 2) build_city(state, state.colors[0], 0) assert state.player_state["P0_VICTORY_POINTS"] == 2 assert state.player_state["P0_ACTUAL_VICTORY_POINTS"] == 2
def test_cant_steal_devcards(): # Arrange: Have RED buy 1 dev card (and have no resource cards) players = [SimplePlayer(Color.RED), SimplePlayer(Color.BLUE)] state = State(players) player_deck_replenish(state, Color.RED, WHEAT) player_deck_replenish(state, Color.RED, ORE) player_deck_replenish(state, Color.RED, SHEEP) buy_dev_card(state, Color.RED, KNIGHT) # Act: Attempt to steal a resource with pytest.raises(IndexError): # no resource cards in hand player_deck_random_draw(state, Color.RED)
def test_can_trade_with_port(): players = [SimplePlayer(Color.RED)] state = State(players) state.board.build_settlement(Color.RED, 26, initial_build_phase=True) port_tile = state.board.map.tiles[(3, -3, 0)] # port with node_id=25,26 resource_out = port_tile.resource or WHEAT # type: ignore num_out = 3 if port_tile.resource is None else 2 # type: ignore player_deck_replenish(state, Color.RED, resource_out, num_out) possibilities = maritime_trade_possibilities(state, Color.RED) assert len(possibilities) == 4
def test_can_only_play_one_dev_card_per_turn(): players = [ SimplePlayer(Color.RED), SimplePlayer(Color.BLUE), SimplePlayer(Color.WHITE), SimplePlayer(Color.ORANGE), ] state = State(players) player_deck_replenish(state, players[0].color, YEAR_OF_PLENTY, 2) action = Action(players[0].color, ActionType.PLAY_YEAR_OF_PLENTY, 2 * [BRICK]) apply_action(state, action) with pytest.raises(ValueError): # shouldnt be able to play two dev cards apply_action(state, action)
def test_4to1_maritime_trade_possibilities(): player = SimplePlayer(Color.RED) state = State([player]) possibilities = maritime_trade_possibilities(state, player.color) assert len(possibilities) == 0 player_deck_replenish(state, player.color, WHEAT, 4) possibilities = maritime_trade_possibilities(state, player.color) print(possibilities) assert len(possibilities) == 4 player_deck_replenish(state, player.color, BRICK, 4) possibilities = maritime_trade_possibilities(state, player.color) assert len(possibilities) == 8
def test_road_possible_actions(): player = SimplePlayer(Color.RED) state = State([player]) assert len(road_building_possibilities( state, Color.RED)) == 0 # no money or place state.board.build_settlement(Color.RED, 3, initial_build_phase=True) assert len(road_building_possibilities(state, Color.RED)) == 0 # no money player_deck_replenish(state, player.color, WOOD) player_deck_replenish(state, player.color, BRICK) assert len(road_building_possibilities(state, Color.RED)) == 3 state.board.build_settlement(Color.RED, 1, initial_build_phase=True) assert len(road_building_possibilities(state, Color.RED)) == 6
def test_trade_execution(): players = [ SimplePlayer(Color.RED), SimplePlayer(Color.BLUE), SimplePlayer(Color.WHITE), SimplePlayer(Color.ORANGE), ] state = State(players) player_deck_replenish(state, players[0].color, BRICK, 4) trade_offer = tuple([BRICK] * 4 + [ORE]) action = Action(players[0].color, ActionType.MARITIME_TRADE, trade_offer) apply_action(state, action) assert player_num_resource_cards(state, players[0].color) == 1 assert sum(state.resource_freqdeck) == 19 * 5 + 4 - 1
def test_buying_road_is_payed_for(): players = [SimplePlayer(Color.RED), SimplePlayer(Color.BLUE)] state = State(players) state.is_initial_build_phase = False state.board.build_settlement(players[0].color, 3, True) action = Action(players[0].color, ActionType.BUILD_ROAD, (3, 4)) player_freqdeck_add( state, players[0].color, freqdeck_from_listdeck([WOOD, BRICK]), ) apply_action(state, action) assert player_num_resource_cards(state, players[0].color, WOOD) == 0 assert player_num_resource_cards(state, players[0].color, BRICK) == 0
def test_sequence(): players = [ SimplePlayer(Color.RED), SimplePlayer(Color.BLUE), SimplePlayer(Color.WHITE), SimplePlayer(Color.ORANGE), ] state = State(players) p0_color = state.colors[0] assert state.current_prompt == ActionPrompt.BUILD_INITIAL_SETTLEMENT assert Action(p0_color, ActionType.BUILD_SETTLEMENT, 0) in state.playable_actions assert Action(p0_color, ActionType.BUILD_SETTLEMENT, 50) in state.playable_actions apply_action(state, state.playable_actions[0])
def test_city_playable_actions(): player = SimplePlayer(Color.RED) state = State([player]) assert len(city_possibilities(state, Color.RED)) == 0 # no money or place state.board.build_settlement(Color.RED, 3, initial_build_phase=True) build_settlement(state, player.color, 3, True) assert len(city_possibilities(state, Color.RED)) == 0 # no money player_deck_replenish(state, Color.RED, WHEAT, 2) player_deck_replenish(state, Color.RED, ORE, 3) assert len(city_possibilities(state, Color.RED)) == 1 state.board.build_settlement(Color.RED, 0, initial_build_phase=True) build_settlement(state, player.color, 0, True) assert len(city_possibilities(state, Color.RED)) == 2
def test_settlement_possible_actions(): player = SimplePlayer(Color.RED) state = State([player]) assert len(settlement_possibilities(state, Color.RED)) == 0 # no money or place state.board.build_settlement(Color.RED, 3, initial_build_phase=True) state.board.build_road(Color.RED, (3, 4)) state.board.build_road(Color.RED, (4, 5)) assert len(settlement_possibilities(state, Color.RED)) == 0 # no money player_freqdeck_add(state, player.color, SETTLEMENT_COST_FREQDECK) assert len(settlement_possibilities(state, Color.RED)) == 1 state.board.build_road(Color.RED, (5, 0)) assert len(settlement_possibilities(state, Color.RED)) == 2
def test_largest_army_calculation_when_no_one_has_three(): red = SimplePlayer(Color.RED) blue = SimplePlayer(Color.BLUE) white = SimplePlayer(Color.WHITE) state = State([red, blue, white]) player_deck_replenish(state, Color.RED, WHEAT, 2) player_deck_replenish(state, Color.RED, SHEEP, 2) player_deck_replenish(state, Color.RED, ORE, 2) player_deck_replenish(state, Color.BLUE, WHEAT, 1) player_deck_replenish(state, Color.BLUE, SHEEP, 1) player_deck_replenish(state, Color.BLUE, ORE, 1) buy_dev_card(state, Color.RED, KNIGHT) buy_dev_card(state, Color.RED, KNIGHT) buy_dev_card(state, Color.BLUE, KNIGHT) play_dev_card(state, Color.RED, KNIGHT) color, count = get_largest_army(state) assert color is None and count is None
def test_moving_robber_steals_correctly(): players = [SimplePlayer(Color.RED), SimplePlayer(Color.BLUE)] state = State(players) player_deck_replenish(state, players[1].color, WHEAT, 1) state.board.build_settlement(Color.BLUE, 3, initial_build_phase=True) action = Action(players[0].color, ActionType.MOVE_ROBBER, ((2, 0, -2), None, None)) apply_action(state, action) assert player_num_resource_cards(state, players[0].color) == 0 assert player_num_resource_cards(state, players[1].color) == 1 action = Action( players[0].color, ActionType.MOVE_ROBBER, ((0, 0, 0), players[1].color, WHEAT), ) apply_action(state, action) assert player_num_resource_cards(state, players[0].color) == 1 assert player_num_resource_cards(state, players[1].color) == 0
def test_largest_army_calculation_on_tie(): red = SimplePlayer(Color.RED) blue = SimplePlayer(Color.BLUE) white = SimplePlayer(Color.WHITE) state = State([red, blue, white]) player_deck_replenish(state, red.color, KNIGHT, 3) player_deck_replenish(state, blue.color, KNIGHT, 4) play_dev_card(state, Color.RED, KNIGHT) play_dev_card(state, Color.RED, KNIGHT) play_dev_card(state, Color.RED, KNIGHT) play_dev_card(state, Color.BLUE, KNIGHT) play_dev_card(state, Color.BLUE, KNIGHT) play_dev_card(state, Color.BLUE, KNIGHT) color, count = get_largest_army(state) assert color is Color.RED and count == 3 play_dev_card(state, Color.BLUE, KNIGHT) color, count = get_largest_army(state) assert color is Color.BLUE and count == 4
def test_play_year_of_plenty_gives_player_resources(): players = [SimplePlayer(Color.RED), SimplePlayer(Color.BLUE)] state = State(players) player_to_act = players[0] player_deck_replenish(state, player_to_act.color, YEAR_OF_PLENTY, 1) action_to_execute = Action(player_to_act.color, ActionType.PLAY_YEAR_OF_PLENTY, [ORE, WHEAT]) apply_action(state, action_to_execute) for card_type in RESOURCES: if card_type == ORE or card_type == WHEAT: assert player_num_resource_cards(state, player_to_act.color, card_type) == 1 assert freqdeck_count(state.resource_freqdeck, card_type) == 18 else: assert player_num_resource_cards(state, player_to_act.color, card_type) == 0 assert freqdeck_count(state.resource_freqdeck, card_type) == 19 assert get_dev_cards_in_hand(state, player_to_act.color, YEAR_OF_PLENTY) == 0
def test_initial_placement_possibilities(): red = SimplePlayer(Color.RED) state = State([red]) assert len(settlement_possibilities(state, Color.RED, True)) == 54
def test_maritime_possibities_respect_bank_not_having_cards(): player = SimplePlayer(Color.RED) state = State([player]) player_deck_replenish(state, player.color, WHEAT) assert len(maritime_trade_possibilities(state, player.color)) == 0