From 655b0c47e5be0b842eb999570d125a061422300e Mon Sep 17 00:00:00 2001 From: Anthony Erb Lugo Date: Sat, 29 Jun 2024 23:54:51 -0400 Subject: [PATCH] Remove mini map support (#20) --- catanatron_core/catanatron/models/board.py | 2 - catanatron_core/catanatron/models/map.py | 35 +-------------- tests/integration_tests/test_speed.py | 9 +++- tests/models/test_board.py | 17 +------- tests/models/test_map.py | 16 ------- tests/test_game.py | 48 ++++++++++----------- tests/test_gym.py | 8 ---- tests/test_machine_learning.py | 50 ---------------------- 8 files changed, 33 insertions(+), 152 deletions(-) diff --git a/catanatron_core/catanatron/models/board.py b/catanatron_core/catanatron/models/board.py index ff2d97d1..049745a1 100644 --- a/catanatron_core/catanatron/models/board.py +++ b/catanatron_core/catanatron/models/board.py @@ -9,7 +9,6 @@ from catanatron.models.player import Color from catanatron.models.map import ( BASE_MAP_TEMPLATE, - MINI_MAP_TEMPLATE, NUM_NODES, CatanMap, NodeId, @@ -19,7 +18,6 @@ # Used to find relationships between nodes and edges base_map = CatanMap.from_template(BASE_MAP_TEMPLATE) -mini_map = CatanMap.from_template(MINI_MAP_TEMPLATE) STATIC_GRAPH = nx.Graph() for tile in base_map.tiles.values(): STATIC_GRAPH.add_nodes_from(tile.nodes.values()) diff --git a/catanatron_core/catanatron/models/map.py b/catanatron_core/catanatron/models/map.py index 76b62cf0..cdfc2f3e 100644 --- a/catanatron_core/catanatron/models/map.py +++ b/catanatron_core/catanatron/models/map.py @@ -105,37 +105,6 @@ class MapTemplate: ] -# Small 7-tile map, no ports. -MINI_MAP_TEMPLATE = MapTemplate( - [3, 4, 5, 6, 8, 9, 10], - [], - [WOOD, None, BRICK, SHEEP, WHEAT, WHEAT, ORE], - { - # center - (0, 0, 0): LandTile, - # first layer - (1, -1, 0): LandTile, - (0, -1, 1): LandTile, - (-1, 0, 1): LandTile, - (-1, 1, 0): LandTile, - (0, 1, -1): LandTile, - (1, 0, -1): LandTile, - # second layer - (2, -2, 0): Water, - (1, -2, 1): Water, - (0, -2, 2): Water, - (-1, -1, 2): Water, - (-2, 0, 2): Water, - (-2, 1, 1): Water, - (-2, 2, 0): Water, - (-1, 2, -1): Water, - (0, 2, -2): Water, - (1, 1, -2): Water, - (2, 0, -2): Water, - (2, -1, -1): Water, - }, -) - """Standard 4-player map""" BASE_MAP_TEMPLATE = MapTemplate( [2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10, 11, 11, 12], @@ -553,10 +522,8 @@ def get_edge_nodes(edge_ref): TOURNAMENT_MAP = CatanMap.from_tiles(TOURNAMENT_MAP_TILES) -def build_map(map_type: Literal["BASE", "TOURNAMENT", "MINI"]): +def build_map(map_type: Literal["BASE", "TOURNAMENT"]): if map_type == "TOURNAMENT": return TOURNAMENT_MAP # this assumes map is read-only data struct - elif map_type == "MINI": - return CatanMap.from_template(MINI_MAP_TEMPLATE) else: return CatanMap.from_template(BASE_MAP_TEMPLATE) diff --git a/tests/integration_tests/test_speed.py b/tests/integration_tests/test_speed.py index 2659ac11..d875ab40 100644 --- a/tests/integration_tests/test_speed.py +++ b/tests/integration_tests/test_speed.py @@ -5,7 +5,10 @@ from catanatron.models.player import Color, SimplePlayer, RandomPlayer from catanatron.players.weighted_random import WeightedRandomPlayer from catanatron_gym.features import create_sample -from catanatron_experimental.machine_learning.players.minimax import AlphaBetaPlayer, SameTurnAlphaBetaPlayer +from catanatron_experimental.machine_learning.players.minimax import ( + AlphaBetaPlayer, + SameTurnAlphaBetaPlayer, +) RANDOM_SEED = 0 @@ -62,6 +65,7 @@ def test_simpleplayer_speed(benchmark): SimplePlayer(Color.ORANGE), ] game = Game(players, seed=RANDOM_SEED) + def _play_game(game): for _ in range(100): game.play_tick() @@ -78,6 +82,7 @@ def test_weightedrandom_speed(benchmark): WeightedRandomPlayer(Color.ORANGE), ] game = Game(players, seed=RANDOM_SEED) + def _play_game(game): for _ in range(100): game.play_tick() @@ -94,6 +99,7 @@ def test_alphabeta_speed(benchmark): AlphaBetaPlayer(Color.ORANGE), ] game = Game(players, seed=RANDOM_SEED) + def _play_game(game): for _ in range(100): game.play_tick() @@ -110,6 +116,7 @@ def test_same_turn_alphabeta_speed(benchmark): SameTurnAlphaBetaPlayer(Color.ORANGE), ] game = Game(players, seed=RANDOM_SEED) + def _play_game(game): for _ in range(100): game.play_tick() diff --git a/tests/models/test_board.py b/tests/models/test_board.py index c212df89..b9a8612a 100644 --- a/tests/models/test_board.py +++ b/tests/models/test_board.py @@ -1,6 +1,6 @@ import pytest -from catanatron.models.map import MINI_MAP_TEMPLATE, CatanMap +from catanatron.models.map import CatanMap from catanatron.models.enums import RESOURCES from catanatron.models.board import Board, get_node_distances from catanatron.models.player import Color @@ -97,14 +97,6 @@ def test_buildable_nodes(): assert len(nodes) == 54 -def test_buildable_nodes_in_mini_map(): - board = Board(catan_map=CatanMap.from_template(MINI_MAP_TEMPLATE)) - nodes = board.buildable_node_ids(Color.RED) - assert len(nodes) == 0 - nodes = board.buildable_node_ids(Color.RED, initial_build_phase=True) - assert len(nodes) == 24 - - def test_placing_settlement_removes_four_buildable_nodes(): board = Board() board.build_settlement(Color.RED, 3, initial_build_phase=True) @@ -155,13 +147,6 @@ def test_buildable_edges_simple(): assert len(buildable) == 3 -def test_buildable_edges_in_mini(): - board = Board(catan_map=CatanMap.from_template(MINI_MAP_TEMPLATE)) - board.build_settlement(Color.RED, 19, initial_build_phase=True) - buildable = board.buildable_edges(Color.RED) - assert len(buildable) == 2 - - def test_buildable_edges(): board = Board() board.build_settlement(Color.RED, 3, initial_build_phase=True) diff --git a/tests/models/test_map.py b/tests/models/test_map.py index b6892381..a39f8814 100644 --- a/tests/models/test_map.py +++ b/tests/models/test_map.py @@ -1,7 +1,6 @@ from catanatron import WOOD, BRICK from catanatron.models.map import ( BASE_MAP_TEMPLATE, - MINI_MAP_TEMPLATE, CatanMap, LandTile, get_nodes_and_edges, @@ -23,21 +22,6 @@ def test_node_production_of_same_resource_adjacent_tile(): assert result["WOOD"] == DICE_PROBAS[12] + DICE_PROBAS[6] + DICE_PROBAS[8] -def test_mini_map_can_be_created(): - mini = CatanMap.from_template(MINI_MAP_TEMPLATE) - assert len(mini.land_tiles) == 7 - assert len(mini.land_nodes) == 24 - assert len(mini.tiles_by_id) == 7 - assert len(mini.ports_by_id) == 0 - assert len(mini.port_nodes) == 0 - assert len(mini.adjacent_tiles) == 24 - assert len(mini.node_production) == 24 - - resources = [i.resource for i in mini.land_tiles.values()] - assert any(isinstance(i, str) for i in resources) - assert any(i is None for i in resources) # theres one desert - - def test_base_map_can_be_created(): catan_map = CatanMap.from_template(BASE_MAP_TEMPLATE) assert len(catan_map.land_tiles) == 19 diff --git a/tests/test_game.py b/tests/test_game.py index 3bfcfab8..c00d7561 100644 --- a/tests/test_game.py +++ b/tests/test_game.py @@ -13,9 +13,7 @@ player_num_resource_cards, ) from catanatron.state_functions import player_key -from catanatron.models.actions import ( - generate_playable_actions -) +from catanatron.models.actions import generate_playable_actions from catanatron.models.enums import ( BRICK, ORE, @@ -358,8 +356,8 @@ def test_longest_road_steal(): board.build_road(p0.color, (7, 8)) board.build_road(p0.color, (8, 9)) board.build_road(p0.color, (9, 10)) - game.state.player_state[f'{p0_key}_VICTORY_POINTS'] = 1 - game.state.player_state[f'{p0_key}_ACTUAL_VICTORY_POINTS'] = 1 + game.state.player_state[f"{p0_key}_VICTORY_POINTS"] = 1 + game.state.player_state[f"{p0_key}_ACTUAL_VICTORY_POINTS"] = 1 # p1 has longest road of lenght 5 board.build_settlement(p1.color, 28, True) @@ -368,14 +366,14 @@ def test_longest_road_steal(): board.build_road(p1.color, (29, 30)) board.build_road(p1.color, (30, 31)) board.build_road(p1.color, (31, 32)) - game.state.player_state[f'{p1_key}_VICTORY_POINTS'] = 3 - game.state.player_state[f'{p1_key}_ACTUAL_VICTORY_POINTS'] = 3 - game.state.player_state[f'{p1_key}_HAS_ROAD'] = True + game.state.player_state[f"{p1_key}_VICTORY_POINTS"] = 3 + game.state.player_state[f"{p1_key}_ACTUAL_VICTORY_POINTS"] = 3 + game.state.player_state[f"{p1_key}_HAS_ROAD"] = True # Required to be able to apply actions other than rolling or initial build phase. game.state.current_prompt = ActionPrompt.PLAY_TURN game.state.is_initial_build_phase = False - game.state.player_state[f'{p0_key}_HAS_ROLLED'] = True + game.state.player_state[f"{p0_key}_HAS_ROLLED"] = True game.state.playable_actions = generate_playable_actions(game.state) # Set up player0 to build two roads and steal longest road. @@ -386,25 +384,25 @@ def test_longest_road_steal(): # Matching length of longest road does not steal longest road. apply_action(game.state, Action(p0.color, ActionType.BUILD_ROAD, road1)) - assert game.state.player_state[f'{p0_key}_LONGEST_ROAD_LENGTH'] == 5 - assert game.state.player_state[f'{p0_key}_HAS_ROAD'] == False - assert game.state.player_state[f'{p0_key}_VICTORY_POINTS'] == 1 - assert game.state.player_state[f'{p0_key}_ACTUAL_VICTORY_POINTS'] == 1 - assert game.state.player_state[f'{p1_key}_LONGEST_ROAD_LENGTH'] == 5 - assert game.state.player_state[f'{p1_key}_HAS_ROAD'] == True - assert game.state.player_state[f'{p1_key}_VICTORY_POINTS'] == 3 - assert game.state.player_state[f'{p1_key}_ACTUAL_VICTORY_POINTS'] == 3 + assert game.state.player_state[f"{p0_key}_LONGEST_ROAD_LENGTH"] == 5 + assert game.state.player_state[f"{p0_key}_HAS_ROAD"] == False + assert game.state.player_state[f"{p0_key}_VICTORY_POINTS"] == 1 + assert game.state.player_state[f"{p0_key}_ACTUAL_VICTORY_POINTS"] == 1 + assert game.state.player_state[f"{p1_key}_LONGEST_ROAD_LENGTH"] == 5 + assert game.state.player_state[f"{p1_key}_HAS_ROAD"] == True + assert game.state.player_state[f"{p1_key}_VICTORY_POINTS"] == 3 + assert game.state.player_state[f"{p1_key}_ACTUAL_VICTORY_POINTS"] == 3 # Surpassing length of longest road steals longest road and VPs. apply_action(game.state, Action(p0.color, ActionType.BUILD_ROAD, road2)) - assert game.state.player_state[f'{p0_key}_LONGEST_ROAD_LENGTH'] == 6 - assert game.state.player_state[f'{p0_key}_HAS_ROAD'] == True - assert game.state.player_state[f'{p0_key}_VICTORY_POINTS'] == 3 - assert game.state.player_state[f'{p0_key}_ACTUAL_VICTORY_POINTS'] == 3 - assert game.state.player_state[f'{p1_key}_LONGEST_ROAD_LENGTH'] == 5 - assert game.state.player_state[f'{p1_key}_HAS_ROAD'] == False - assert game.state.player_state[f'{p1_key}_VICTORY_POINTS'] == 1 - assert game.state.player_state[f'{p1_key}_ACTUAL_VICTORY_POINTS'] == 1 + assert game.state.player_state[f"{p0_key}_LONGEST_ROAD_LENGTH"] == 6 + assert game.state.player_state[f"{p0_key}_HAS_ROAD"] == True + assert game.state.player_state[f"{p0_key}_VICTORY_POINTS"] == 3 + assert game.state.player_state[f"{p0_key}_ACTUAL_VICTORY_POINTS"] == 3 + assert game.state.player_state[f"{p1_key}_LONGEST_ROAD_LENGTH"] == 5 + assert game.state.player_state[f"{p1_key}_HAS_ROAD"] == False + assert game.state.player_state[f"{p1_key}_VICTORY_POINTS"] == 1 + assert game.state.player_state[f"{p1_key}_ACTUAL_VICTORY_POINTS"] == 1 def test_second_placement_takes_cards_from_bank(): diff --git a/tests/test_gym.py b/tests/test_gym.py index 472bce14..c69b2e91 100644 --- a/tests/test_gym.py +++ b/tests/test_gym.py @@ -95,14 +95,6 @@ def custom_reward(game, p0_color): assert reward == 123 -def test_custom_map(): - env = gym.make("catanatron_gym:catanatron-v1", config={"map_type": "MINI"}) - observation, info = env.reset() - assert len(env.get_valid_actions()) < 50 # type: ignore - assert len(observation) < 614 - # assert env.action_space.n == 260 - - def test_enemies(): env = gym.make( "catanatron_gym:catanatron-v1", diff --git a/tests/test_machine_learning.py b/tests/test_machine_learning.py index 9c1f9180..866014a2 100644 --- a/tests/test_machine_learning.py +++ b/tests/test_machine_learning.py @@ -9,7 +9,6 @@ from catanatron.models.board import Board, get_edges from catanatron.models.map import ( BASE_MAP_TEMPLATE, - MINI_MAP_TEMPLATE, NUM_EDGES, NUM_NODES, CatanMap, @@ -192,29 +191,6 @@ def test_tile_features(): assert features[f"TILE0_PROBA"] == proba -def test_tile_features_in_mini(): - players = [ - SimplePlayer(Color.RED), - SimplePlayer(Color.BLUE), - ] - game = Game(players, catan_map=CatanMap.from_template(MINI_MAP_TEMPLATE)) - - features = tile_features(game, players[0].color) - haystack = "".join(features.keys()) - assert "TILE7" not in haystack - - -def test_port_features_in_mini(): - players = [ - SimplePlayer(Color.RED), - SimplePlayer(Color.BLUE), - ] - game = Game(players, catan_map=CatanMap.from_template(MINI_MAP_TEMPLATE)) - - features = port_features(game, players[0].color) - assert len(features) == 0 - - def test_graph_features(): players = [ SimplePlayer(Color.RED), @@ -242,32 +218,6 @@ def test_graph_features(): assert ("NODE" + str(node)) in haystack -def test_graph_features_in_mini(): - players = [ - SimplePlayer(Color.RED), - SimplePlayer(Color.BLUE), - ] - game = Game(players, catan_map=CatanMap.from_template(MINI_MAP_TEMPLATE)) - p0_color = game.state.colors[0] - game.execute(Action(p0_color, ActionType.BUILD_SETTLEMENT, 3)) - game.execute(Action(p0_color, ActionType.BUILD_ROAD, (2, 3))) - - features = graph_features(game, p0_color) - assert features[f"NODE3_P0_SETTLEMENT"] - assert features[f"EDGE(2, 3)_P0_ROAD"] - assert not features[f"NODE3_P1_SETTLEMENT"] - assert not features[f"NODE0_P1_SETTLEMENT"] - # todo: CHANGE NUM_EDGES - assert len(features) == 24 * len(players) * 2 + 30 * len(players) - assert sum(features.values()) == 2 - - haystack = "".join(features.keys()) - for edge in get_edges(game.state.board.map.land_nodes): - assert str(edge) in haystack - for node in range(24): - assert ("NODE" + str(node)) in haystack - - def test_init_board_tensor_map(): node_map, edge_map = init_board_tensor_map() assert node_map[82] == (0, 0)