Spaces:
Runtime error
Runtime error
File size: 5,786 Bytes
b33ab01 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
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
@staticmethod
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}"
@classmethod
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)
@property
def walls(self):
return self.board.wall_pos
|