-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]):
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 __init__(self, source_map, yx):
self.source_map = source_map
self.size = self.source_map.size
+ self.fov_radius = (self.size[0] / 2) - 0.5
self.terrain = '?' * self.size_i
self[yx] = '.'
self.shadow_cones = []
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
# would lose shade growth through hexes at shade borders.)
# TODO: Start circling only in earliest obstacle distance.
+ # TODO: get rid of circle_in_map logic
circle_in_map = True
distance = 1
yx = yx[:]
#print('DEBUG CIRCLE_OUT', yx)
while circle_in_map:
+ if distance > self.fov_radius:
+ break
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