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_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_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_end_turn_goes_to_next_player(fake_roll_dice): fake_roll_dice.return_value = (1, 2) # not a 7 players = [SimplePlayer(Color.RED), SimplePlayer(Color.BLUE)] game = Game(players) actions = [] while not any( a.action_type == ActionType.ROLL for a in game.state.playable_actions ): actions.append(game.play_tick()) p0_color = game.state.colors[0] p1_color = game.state.colors[1] assert ( game.state.current_prompt == ActionPrompt.PLAY_TURN and game.state.current_color() == p0_color ) assert game.state.playable_actions == [Action(p0_color, ActionType.ROLL, None)] game.execute(Action(p0_color, ActionType.ROLL, None)) assert game.state.current_prompt == ActionPrompt.PLAY_TURN assert game.state.current_color() == p0_color assert player_has_rolled(game.state, p0_color) assert Action(p0_color, ActionType.END_TURN, None) in game.state.playable_actions game.execute(Action(p0_color, ActionType.END_TURN, None)) assert game.state.current_prompt == ActionPrompt.PLAY_TURN assert game.state.current_color() == p1_color assert not player_has_rolled(game.state, p0_color) assert not player_has_rolled(game.state, p1_color) assert game.state.playable_actions == [Action(p1_color, ActionType.ROLL, None)]
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_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_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 test_play_monopoly_no_monopoly_card(): players = [SimplePlayer(Color.RED), SimplePlayer(Color.BLUE)] game = Game(players) action_to_execute = Action(players[0].color, ActionType.PLAY_MONOPOLY, ORE) with pytest.raises(ValueError): # no monopoly game.execute(action_to_execute)
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_play_year_of_plenty_no_year_of_plenty_card(): players = [SimplePlayer(Color.RED), SimplePlayer(Color.BLUE)] game = Game(players) action_to_execute = Action( players[0].color, ActionType.PLAY_YEAR_OF_PLENTY, [ORE, WHEAT] ) with pytest.raises(ValueError): # no year of plenty card game.execute(action_to_execute)
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_to_json_speed(benchmark): players = [ SimplePlayer(Color.RED), SimplePlayer(Color.BLUE), SimplePlayer(Color.ORANGE), SimplePlayer(Color.WHITE), ] game = Game(players) result = benchmark(json.dumps, game, cls=GameEncoder) assert isinstance(result, str)
def test_copy_speed(benchmark): players = [ SimplePlayer(Color.RED), SimplePlayer(Color.BLUE), SimplePlayer(Color.ORANGE), SimplePlayer(Color.WHITE), ] game = Game(players) result = benchmark(game.copy) assert result.seed == game.seed
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_create_sample_speed(benchmark): players = [ SimplePlayer(Color.RED), SimplePlayer(Color.BLUE), SimplePlayer(Color.WHITE), SimplePlayer(Color.ORANGE), ] game = Game(players) for _ in range(30): game.play_tick() sample = benchmark(create_sample, game, players[1].color) assert isinstance(sample, dict) assert len(sample) > 0
def get_feature_ordering(num_players=4): global FEATURE_ORDERING if FEATURE_ORDERING is None: players = [ SimplePlayer(Color.RED), SimplePlayer(Color.BLUE), SimplePlayer(Color.WHITE), SimplePlayer(Color.ORANGE), ] players = players[:num_players] game = Game(players) sample = create_sample(game, players[0].color) FEATURE_ORDERING = sorted(sample.keys()) return FEATURE_ORDERING
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_play_year_of_plenty_not_enough_resources(): players = [SimplePlayer(Color.RED), SimplePlayer(Color.BLUE)] player_to_act = players[0] game = Game(players) game.state.resource_freqdeck = [0, 0, 0, 0, 0] player_deck_replenish(game.state, player_to_act.color, YEAR_OF_PLENTY) action_to_execute = Action( player_to_act.color, ActionType.PLAY_YEAR_OF_PLENTY, [ORE, WHEAT], ) with pytest.raises(ValueError): # not enough cards in bank game.execute(action_to_execute)
def test_second_placement_takes_cards_from_bank(): players = [ SimplePlayer(Color.RED), SimplePlayer(Color.BLUE), SimplePlayer(Color.WHITE), SimplePlayer(Color.ORANGE), ] game = Game(players) assert sum(game.state.resource_freqdeck) == 19 * 5 while not any( a.action_type == ActionType.ROLL for a in game.state.playable_actions ): game.play_tick() assert sum(game.state.resource_freqdeck) < 19 * 5
def test_copy(): """Play 30 moves, copy game, ensure they look the same but not the same.""" players = [ SimplePlayer(Color.RED), SimplePlayer(Color.BLUE), SimplePlayer(Color.WHITE), SimplePlayer(Color.ORANGE), ] game = Game(players) for i in range(30): game.play_tick() game_copy = game.copy() assert json.dumps(game, cls=GameEncoder) == json.dumps(game_copy, cls=GameEncoder) assert game_copy != game
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_serialization(): game = Game(players=[ SimplePlayer(Color.RED), SimplePlayer(Color.BLUE), SimplePlayer(Color.WHITE), SimplePlayer(Color.ORANGE), ]) string = json.dumps(game, cls=GameEncoder) result = json.loads(string) # Loosely assert looks like expected assert isinstance(result["robber_coordinate"], list) assert isinstance(result["tiles"], list) assert isinstance(result["edges"], list) assert isinstance(result["nodes"], dict) assert isinstance(result["actions"], list)
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_discard_config(fake_roll_dice): fake_roll_dice.return_value = (1, 6) players = [SimplePlayer(Color.RED), SimplePlayer(Color.BLUE)] game = Game(players, discard_limit=10) while not any( a.action_type == ActionType.ROLL for a in game.state.playable_actions ): game.play_tick() until_nine = 9 - player_num_resource_cards(game.state, players[1].color) player_deck_replenish(game.state, players[1].color, WHEAT, until_nine) assert player_num_resource_cards(game.state, players[1].color) == 9 game.play_tick() # should be p0 rolling. assert game.state.playable_actions != [ Action(players[1].color, ActionType.DISCARD, None) ]
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_seven_cards_dont_trigger_discarding(fake_roll_dice): fake_roll_dice.return_value = (1, 6) players = [SimplePlayer(Color.RED), SimplePlayer(Color.BLUE)] # Play initial build phase game = Game(players) while not any( a.action_type == ActionType.ROLL for a in game.state.playable_actions ): game.play_tick() until_seven = 7 - player_num_resource_cards(game.state, players[1].color) player_deck_replenish(game.state, players[1].color, WHEAT, until_seven) assert player_num_resource_cards(game.state, players[1].color) == 7 game.play_tick() # should be player 0 rolling. assert not any( a.action_type == ActionType.DISCARD for a in game.state.playable_actions )
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_execute_action_on_copies_doesnt_conflict(): players = [ SimplePlayer(Color.RED), SimplePlayer(Color.BLUE), SimplePlayer(Color.WHITE), SimplePlayer(Color.ORANGE), ] game = Game(players) p0_color = game.state.colors[0] game.execute(Action(p0_color, ActionType.BUILD_SETTLEMENT, 0)) action = Action(p0_color, ActionType.BUILD_ROAD, (0, 1)) game_copy = game.copy() game_copy.execute(action) game_copy = game.copy() game_copy.execute(action) game.execute(action)
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