Spaces:
Runtime error
Runtime error
from typing import List, Tuple, Optional | |
from enum import Enum | |
class Actions(Enum): | |
UPRIGHT = "UR" | |
RIGHT = "R" | |
DOWNRIGHT = "DR" | |
DOWNLEFT = "DL" | |
LEFT = "L" | |
UPLEFT = "UL" | |
PICKUP = "Pickup" | |
# Add more actions here if needed | |
class Board: | |
def __init__(self, grid: List[str], player_pos: Tuple[int, int], | |
flag_pos: Tuple[int, int], wall_pos:List[Tuple[int, int]], | |
key_pos:Optional[Tuple[int, int]]): | |
self.grid = grid | |
self.player_pos = player_pos | |
self.flag_pos = flag_pos | |
self.wall_pos = wall_pos | |
self.key_pos = key_pos | |
def change(action): | |
if action == Actions.UPRIGHT: | |
dx, dy = -1, 1 | |
elif action == Actions.UPLEFT: | |
dx, dy = -1, -1 | |
elif action == Actions.DOWNLEFT: | |
dx, dy = 1, -1 | |
elif action == Actions.DOWNRIGHT: | |
dx, dy = 1, 1 | |
elif action == Actions.LEFT: | |
dx, dy = 0, -2 | |
elif action == Actions.RIGHT: | |
dx, dy = 0, 2 | |
elif action == Actions.PICKUP: | |
dx, dy = 0, 0 | |
return dx, dy | |
def move(self, action: Actions) -> 'Board': | |
dx, dy = 0, 0 | |
if action == Actions.UPRIGHT: | |
dx, dy = -1, 1 | |
elif action == Actions.UPLEFT: | |
dx, dy = -1, -1 | |
elif action == Actions.DOWNLEFT: | |
dx, dy = 1, -1 | |
elif action == Actions.DOWNRIGHT: | |
dx, dy = 1, 1 | |
elif action == Actions.LEFT: | |
dx, dy = 0, -2 | |
elif action == Actions.RIGHT: | |
dx, dy = 0, 2 | |
elif action == Actions.PICKUP: | |
dx, dy = 0, 0 | |
if self.player_pos[0] == self.key_pos[0] and self.player_pos[1] == self.key_pos[1]: | |
return Board(self.grid, self.player_pos, self.flag_pos, self.wall_pos, None), "pickup" | |
else: | |
return self, "nokey" | |
else: | |
# Handle other actions here if needed | |
print("fail") | |
new_player_pos = (self.player_pos[0] + dx, self.player_pos[1] + dy) | |
if self.grid[new_player_pos[0]][new_player_pos[1]] == 'W': | |
# Can't move through walls | |
return self, "WALL" | |
new_grid = [row[:] for row in self.grid] # Create a copy of the grid | |
new_grid[self.player_pos[0]][self.player_pos[1]] = '.' | |
new_grid[new_player_pos[0]][new_player_pos[1]] = '@' | |
return Board(new_grid, new_player_pos, self.flag_pos, self.wall_pos, self.key_pos), "Good" | |
def create_wall(self, pos: Tuple[int, int]) -> 'Board': | |
if self.grid[pos[0]][pos[1]] in ( '@', 'P'): | |
# Can't place a wall on top of another object | |
return self | |
new_grid = [row[:] for row in self.grid] # Create a copy of the grid | |
new_grid[pos[0]][pos[1]] = "W" | |
return Board(new_grid, self.player_pos, self.flag_pos, self.wall_pos + [pos], self.key_pos) | |
def __str__(self) -> str: | |
# return '\n'.join((' ' * i %2) + ' '.join(row) for i, row in enumerate(self.grid)) | |
return '\n'.join(''.join(row) for i, row in enumerate(self.grid)) | |
def illegal_moves(self): | |
for action in Actions: | |
dx, dy = self.change(action) | |
new_player_pos = (self.player_pos[0] + dx, self.player_pos[1] + dy) | |
if new_player_pos[0] < 0 or new_player_pos[0] > self.flag_pos[0]: | |
#yield action, f"assert not 0 <= {new_player_pos[0]} < {self.flag_pos[0] + 1}" | |
continue | |
if new_player_pos[1] < 0 or new_player_pos[1] > self.flag_pos[1]: | |
#yield action, f"assert not 0 <= {new_player_pos[1]} < {self.flag_pos[0] + 1}" | |
continue | |
if action == Actions.PICKUP and not(self.key_pos is not None and self.player_pos[0] == self.key_pos[0] and self.player_pos[1] == self.key_pos[1]): | |
yield action, f"assert {new_player_pos} != board.key" | |
continue | |
if self.grid[new_player_pos[0]][new_player_pos[1]] == 'W': | |
yield action, f"assert {new_player_pos} in board.walls" | |
continue | |
continue | |
def board_state(self) -> str: | |
walls = ",".join(map(str, self.wall_pos)) | |
return f"Flag: {self.flag_pos} | Walls (illegal): {walls} | Boundary: {add(self.flag_pos, (1, 1))} | Key: {self.key_pos}" | |
def board_state2(self) -> str: | |
walls = ",".join(map(str, self.wall_pos)) | |
return f"init={self.player_pos}, flag={self.flag_pos}, walls= {self.wall_pos}, boundary= {add(self.flag_pos, (1, 1))}, key= {self.key_pos}" | |
def player_state(self) -> str: | |
msg = " K" if self.key_pos is None else "" | |
return f"{self.player_pos}{msg}" | |
def create_empty_board(cls, size: Tuple[int, int], key_pos, flag_pos, init) -> 'Board': | |
grid = [['.' if i % 2 == j % 2 else " " for i in range(size[1])] for j in range(size[0])] | |
player_pos = init | |
flag_pos = flag_pos | |
grid[player_pos[0]][player_pos[1]] = '@' | |
grid[flag_pos[0]][flag_pos[1]] = 'P' | |
grid[key_pos[0]][key_pos[1]] = 'K' | |
return cls(grid, player_pos, flag_pos, [], key_pos) | |
def add(a, b): | |
return a[0] + b[0], a[1] + b[1] | |
class GameBoard: | |
def __init__(self, init, flag, walls, key, boundary): | |
self.board = Board.create_empty_board(boundary, key, flag, init) | |
for wall in walls: | |
self.board = self.board.create_wall(wall) | |
self.original = self.board | |
self.actions = [] | |
def move(self, action): | |
self.board, _ = self.board.move(action) | |
self.actions.append(action) | |
def walls(self): | |
return self.board.wall_pos | |