-class MapBase:
+class Map:
def __init__(self, size=(0, 0)):
self.size = size
self.terrain = '?'*self.size_i
+ def __getitem__(self, yx):
+ return self.terrain[self.get_position_index(yx)]
+
+ def __setitem__(self, yx, c):
+ pos_i = self.get_position_index(yx)
+ if type(c) == str:
+ self.terrain = self.terrain[:pos_i] + c + self.terrain[pos_i + 1:]
+ else:
+ self.terrain[pos_i] = c
+
+ def __iter__(self):
+ """Iterate over YX position coordinates."""
+ for y in range(self.size[0]):
+ for x in range(self.size[1]):
+ yield (y, x)
+
@property
def size_i(self):
return self.size[0] * self.size[1]
def get_position_index(self, yx):
return yx[0] * self.size[1] + yx[1]
-
-class Map(MapBase):
-
- def __getitem__(self, yx):
- return self.terrain[self.get_position_index(yx)]
-
- def __setitem__(self, yx, c):
- pos_i = self.get_position_index(yx)
- if type(c) == str:
- self.terrain = self.terrain[:pos_i] + c + self.terrain[pos_i + 1:]
- else:
- self.terrain[pos_i] = c
-
- def __iter__(self):
- """Iterate over YX position coordinates."""
- for y in range(self.size[0]):
- for x in range(self.size[1]):
- yield [y, x]
-
def lines(self):
width = self.size[1]
for y in range(self.size[0]):
def get_neighbors(self, pos):
neighbors = {}
+ pos = tuple(pos)
if not hasattr(self, 'neighbors_to'):
self.neighbors_to = {}
if pos in self.neighbors_to:
return self.neighbors_to[pos]
for direction in self.get_directions():
neighbors[direction] = None
- try:
- neighbors[direction] = self.move(pos, direction)
- except GameError:
- pass
+ neighbor_pos = self.move(pos, direction)
+ if neighbor_pos:
+ neighbors[direction] = neighbor_pos
self.neighbors_to[pos] = neighbors
return neighbors
new_pos = mover(start_pos)
if new_pos[0] < 0 or new_pos[1] < 0 or \
new_pos[0] >= self.size[0] or new_pos[1] >= self.size[1]:
- raise GameError('would move outside map bounds')
+ return None
return new_pos
class MapWithLeftRightMoves(Map):
def move_LEFT(self, start_pos):
- return [start_pos[0], start_pos[1] - 1]
+ return (start_pos[0], start_pos[1] - 1)
def move_RIGHT(self, start_pos):
- return [start_pos[0], start_pos[1] + 1]
+ return (start_pos[0], start_pos[1] + 1)
class MapSquare(MapWithLeftRightMoves):
def move_UP(self, start_pos):
- return [start_pos[0] - 1, start_pos[1]]
+ return (start_pos[0] - 1, start_pos[1])
def move_DOWN(self, start_pos):
- return [start_pos[0] + 1, start_pos[1]]
+ return (start_pos[0] + 1, start_pos[1])
def move_UPLEFT(self, start_pos):
if start_pos[0] % 2 == 1:
- return [start_pos[0] - 1, start_pos[1] - 1]
+ return (start_pos[0] - 1, start_pos[1] - 1)
else:
- return [start_pos[0] - 1, start_pos[1]]
+ return (start_pos[0] - 1, start_pos[1])
def move_UPRIGHT(self, start_pos):
if start_pos[0] % 2 == 1:
- return [start_pos[0] - 1, start_pos[1]]
+ return (start_pos[0] - 1, start_pos[1])
else:
- return [start_pos[0] - 1, start_pos[1] + 1]
+ return (start_pos[0] - 1, start_pos[1] + 1)
def move_DOWNLEFT(self, start_pos):
if start_pos[0] % 2 == 1:
- return [start_pos[0] + 1, start_pos[1] - 1]
+ return (start_pos[0] + 1, start_pos[1] - 1)
else:
- return [start_pos[0] + 1, start_pos[1]]
+ return (start_pos[0] + 1, start_pos[1])
def move_DOWNRIGHT(self, start_pos):
if start_pos[0] % 2 == 1:
- return [start_pos[0] + 1, start_pos[1]]
+ return (start_pos[0] + 1, start_pos[1])
else:
- return [start_pos[0] + 1, start_pos[1] + 1]
+ return (start_pos[0] + 1, start_pos[1] + 1)
def basic_circle_out_move(self, pos, direction):
"""Move position pos into direction. Return whether still in map."""
mover = getattr(self, 'move_' + direction)
- pos[:] = mover(pos)
+ pos = mover(pos)
if pos[0] < 0 or pos[1] < 0 or \
pos[0] >= self.size[0] or pos[1] >= self.size[1]:
- return False
- return True
+ return pos, False
+ return pos, True
def circle_out(self, yx, f):
# Optimization potential: Precalculate movement positions. (How to check
#print('DEBUG CIRCLE_OUT', yx)
while circle_in_map:
circle_in_map = False
- self.basic_circle_out_move(yx, 'RIGHT')
+ yx, _ = self.basic_circle_out_move(yx, 'RIGHT')
for dir_i in range(len(self.circle_out_directions)):
for dir_progress in range(distance):
direction = self.circle_out_directions[dir_i]
- if self.circle_out_move(yx, direction):
+ yx, test = self.circle_out_move(yx, direction)
+ if test:
f(yx, distance, dir_i, dir_progress)
circle_in_map = True
distance += 1