diff --git a/src/blokus_gym.egg-info/SOURCES.txt b/src/blokus_gym.egg-info/SOURCES.txt index e665378..64c90b9 100644 --- a/src/blokus_gym.egg-info/SOURCES.txt +++ b/src/blokus_gym.egg-info/SOURCES.txt @@ -16,4 +16,9 @@ src/blokus_gym/envs/multiagent.py src/blokus_gym/utils/__init__.py src/blokus_gym/utils/render.py src/blokus_gym/wrappers/__init__.py -src/blokus_gym/wrappers/action_mask.py \ No newline at end of file +src/blokus_gym/wrappers/action_mask.py +tests/test_board.py +tests/test_envs.py +tests/test_game.py +tests/test_imports.py +tests/test_pieces.py \ No newline at end of file diff --git a/src/blokus_gym/__pycache__/__init__.cpython-311.pyc b/src/blokus_gym/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..e4b8c9b Binary files /dev/null and b/src/blokus_gym/__pycache__/__init__.cpython-311.pyc differ diff --git a/src/blokus_gym/core/__pycache__/__init__.cpython-311.pyc b/src/blokus_gym/core/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..926d38d Binary files /dev/null and b/src/blokus_gym/core/__pycache__/__init__.cpython-311.pyc differ diff --git a/src/blokus_gym/core/__pycache__/board.cpython-311.pyc b/src/blokus_gym/core/__pycache__/board.cpython-311.pyc new file mode 100644 index 0000000..e5fd806 Binary files /dev/null and b/src/blokus_gym/core/__pycache__/board.cpython-311.pyc differ diff --git a/src/blokus_gym/core/__pycache__/bots.cpython-311.pyc b/src/blokus_gym/core/__pycache__/bots.cpython-311.pyc new file mode 100644 index 0000000..373209f Binary files /dev/null and b/src/blokus_gym/core/__pycache__/bots.cpython-311.pyc differ diff --git a/src/blokus_gym/core/__pycache__/game.cpython-311.pyc b/src/blokus_gym/core/__pycache__/game.cpython-311.pyc new file mode 100644 index 0000000..f351585 Binary files /dev/null and b/src/blokus_gym/core/__pycache__/game.cpython-311.pyc differ diff --git a/src/blokus_gym/core/__pycache__/game.cpython-312.pyc b/src/blokus_gym/core/__pycache__/game.cpython-312.pyc index f633397..abeba61 100644 Binary files a/src/blokus_gym/core/__pycache__/game.cpython-312.pyc and b/src/blokus_gym/core/__pycache__/game.cpython-312.pyc differ diff --git a/src/blokus_gym/core/__pycache__/pieces.cpython-311.pyc b/src/blokus_gym/core/__pycache__/pieces.cpython-311.pyc new file mode 100644 index 0000000..de8f737 Binary files /dev/null and b/src/blokus_gym/core/__pycache__/pieces.cpython-311.pyc differ diff --git a/src/blokus_gym/core/game.py b/src/blokus_gym/core/game.py index 27cb8ed..cdfa523 100644 --- a/src/blokus_gym/core/game.py +++ b/src/blokus_gym/core/game.py @@ -55,6 +55,14 @@ class BlokusGame: self._move_to_action: dict[tuple[int, int, int, int], int] = {} self._generate_action_space() + # Pre-compute action indices per piece for faster filtering + self._actions_by_piece: list[list[int]] = [] + for piece_id in range(self.piece_set.num_pieces): + self._actions_by_piece.append([ + idx for idx, move in enumerate(self._action_moves) + if move.piece_id == piece_id + ]) + # Starting corners for each player (standard Blokus layout) # 4 players: all four corners # 2 players: opposite corners (0,0) and (max, max) @@ -197,7 +205,6 @@ class BlokusGame: # Rule 4: Corner rule (must touch same-color at a corner) if player.has_started: - # Must touch at least one same-color piece at a corner placed_corners = self._get_placed_corners(move) touches_corner = False for cx, cy in placed_corners: @@ -207,7 +214,6 @@ class BlokusGame: break if not touches_corner: return False - # If not started yet, first move doesn't need to touch (it's the first piece) return True @@ -219,12 +225,61 @@ class BlokusGame: if not player.can_move: return mask - for action_idx in range(self.num_actions): - move = self._action_moves[action_idx] - piece = self.piece_set.get_piece(move.piece_id) - if piece.name not in player.available_pieces: - continue - if self.valid_move(player_idx, move): + available_piece_ids = [ + self.piece_set.get_piece_id(name) + for name in player.available_pieces + ] + + if not player.has_started or not player.corners: + for piece_id in available_piece_ids: + for action_idx in self._actions_by_piece[piece_id]: + if self.valid_move(player_idx, self._action_moves[action_idx]): + mask[action_idx] = True + return mask + + player_board_idx = player_idx + self.PLAYER_OFFSET + + for piece_id in available_piece_ids: + for action_idx in self._actions_by_piece[piece_id]: + move = self._action_moves[action_idx] + placed_corners = self._get_placed_corners(move) + + touches_corner = False + for cx, cy in placed_corners: + if self.board.in_bounds(cx, cy): + if self.board.get_cell(cx, cy) == player_board_idx: + touches_corner = True + break + if not touches_corner: + continue + + placed_squares = self._get_placed_squares(move) + + valid = True + for x, y in placed_squares: + if not self.board.in_bounds(x, y): + valid = False + break + if not valid: + continue + + if self.board.has_overlap(placed_squares): + continue + + for x, y in placed_squares: + edge_invalid = False + for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]: + nx, ny = x + dx, y + dy + if self.board.in_bounds(nx, ny): + if self.board.get_cell(nx, ny) == player_board_idx: + edge_invalid = True + break + if edge_invalid: + valid = False + break + if not valid: + continue + mask[action_idx] = True return mask @@ -240,11 +295,14 @@ class BlokusGame: if not player.can_move: return False - for action_idx in range(self.num_actions): - move = self._action_moves[action_idx] - piece = self.piece_set.get_piece(move.piece_id) - if piece.name in player.available_pieces: - if self.valid_move(player_idx, move): + available_piece_ids = [ + self.piece_set.get_piece_id(name) + for name in player.available_pieces + ] + + for piece_id in available_piece_ids: + for action_idx in self._actions_by_piece[piece_id]: + if self.valid_move(player_idx, self._action_moves[action_idx]): return True return False diff --git a/src/blokus_gym/envs/__pycache__/__init__.cpython-311.pyc b/src/blokus_gym/envs/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..11d028c Binary files /dev/null and b/src/blokus_gym/envs/__pycache__/__init__.cpython-311.pyc differ diff --git a/src/blokus_gym/envs/__pycache__/blokus_env.cpython-311.pyc b/src/blokus_gym/envs/__pycache__/blokus_env.cpython-311.pyc new file mode 100644 index 0000000..b75769d Binary files /dev/null and b/src/blokus_gym/envs/__pycache__/blokus_env.cpython-311.pyc differ diff --git a/src/blokus_gym/envs/__pycache__/multiagent.cpython-311.pyc b/src/blokus_gym/envs/__pycache__/multiagent.cpython-311.pyc new file mode 100644 index 0000000..4c70fa1 Binary files /dev/null and b/src/blokus_gym/envs/__pycache__/multiagent.cpython-311.pyc differ diff --git a/src/blokus_gym/utils/__pycache__/__init__.cpython-311.pyc b/src/blokus_gym/utils/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..1253ce4 Binary files /dev/null and b/src/blokus_gym/utils/__pycache__/__init__.cpython-311.pyc differ diff --git a/src/blokus_gym/utils/__pycache__/render.cpython-311.pyc b/src/blokus_gym/utils/__pycache__/render.cpython-311.pyc new file mode 100644 index 0000000..8e34c1a Binary files /dev/null and b/src/blokus_gym/utils/__pycache__/render.cpython-311.pyc differ diff --git a/src/blokus_gym/wrappers/__pycache__/__init__.cpython-311.pyc b/src/blokus_gym/wrappers/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..c5657c6 Binary files /dev/null and b/src/blokus_gym/wrappers/__pycache__/__init__.cpython-311.pyc differ diff --git a/src/blokus_gym/wrappers/__pycache__/action_mask.cpython-311.pyc b/src/blokus_gym/wrappers/__pycache__/action_mask.cpython-311.pyc new file mode 100644 index 0000000..344f4e9 Binary files /dev/null and b/src/blokus_gym/wrappers/__pycache__/action_mask.cpython-311.pyc differ diff --git a/tests/__pycache__/test_board.cpython-311-pytest-9.1.1.pyc b/tests/__pycache__/test_board.cpython-311-pytest-9.1.1.pyc new file mode 100644 index 0000000..782fbca Binary files /dev/null and b/tests/__pycache__/test_board.cpython-311-pytest-9.1.1.pyc differ diff --git a/tests/__pycache__/test_envs.cpython-311-pytest-9.1.1.pyc b/tests/__pycache__/test_envs.cpython-311-pytest-9.1.1.pyc new file mode 100644 index 0000000..1b4b2b4 Binary files /dev/null and b/tests/__pycache__/test_envs.cpython-311-pytest-9.1.1.pyc differ diff --git a/tests/__pycache__/test_game.cpython-311-pytest-9.1.1.pyc b/tests/__pycache__/test_game.cpython-311-pytest-9.1.1.pyc new file mode 100644 index 0000000..be055c4 Binary files /dev/null and b/tests/__pycache__/test_game.cpython-311-pytest-9.1.1.pyc differ diff --git a/tests/__pycache__/test_imports.cpython-311-pytest-9.1.1.pyc b/tests/__pycache__/test_imports.cpython-311-pytest-9.1.1.pyc new file mode 100644 index 0000000..1d26a3b Binary files /dev/null and b/tests/__pycache__/test_imports.cpython-311-pytest-9.1.1.pyc differ diff --git a/tests/__pycache__/test_pieces.cpython-311-pytest-9.1.1.pyc b/tests/__pycache__/test_pieces.cpython-311-pytest-9.1.1.pyc new file mode 100644 index 0000000..d74419f Binary files /dev/null and b/tests/__pycache__/test_pieces.cpython-311-pytest-9.1.1.pyc differ