X-Git-Url: https://git.ctpug.org.za/?a=blobdiff_plain;f=erdslangetjie%2Flevel.py;h=e4bc0e09a58072ea9c28dccdd2e4f8a790d9a6fb;hb=3bc9b0f02fe5766addeb4d45162866ff628fb2ab;hp=e1c534d71f064b75b6917e442b791504e3a3892b;hpb=7d7d155e3111824731f6e342be62e544b46df25d;p=erdslangetjie.git diff --git a/erdslangetjie/level.py b/erdslangetjie/level.py index e1c534d..e4bc0e0 100644 --- a/erdslangetjie/level.py +++ b/erdslangetjie/level.py @@ -38,40 +38,89 @@ class Level(object): for j, line in enumerate(self._data): tile_line = [] for i, c in enumerate(line): - if c == FLOOR: - tile_line.append(load_image('tiles/floor.png')) - elif c == WALL: - tile_line.append(self._get_wall_tile(i, j)) - elif c == ENTRY: - if self.enter_pos: - raise RuntimeError('Multiple entry points') - self.enter_pos = (i, j) - tile_line.append(load_image('tiles/entry.png')) - elif c == EXIT: - self.exit_pos.append((i, j)) - tile_line.append(load_image('tiles/door.png')) - elif c == GATE: - tile_line.append('tiles/gate_down.png') - self._gates[(i, j)] = -1 # down - elif c == BUTTON: - tile_line.append('tiles/button.png') - self._buttons[(i, j)] = 'active' + tile_image = self._get_tile_image((i, j), c) + tile_line.append(tile_image) self._tiles.append(tile_line) + def _get_tile_image(self, pos, c): + if pos in self._gates: + del self._gates[pos] + if pos in self._buttons: + del self._buttons[pos] + image = None + if c == FLOOR: + image = load_image('tiles/floor.png') + elif c == WALL: + image = self._get_wall_tile(pos) + elif c == ENTRY: + self.enter_pos = pos + image = load_image('tiles/entry.png') + elif c == EXIT: + self.exit_pos.append(pos) + image = load_image('tiles/door.png') + elif c == GATE: + image = load_image('tiles/gate_down.png') + self._gates[pos] = -1 # down + elif c == BUTTON: + image = load_image('tiles/button.png') + self._buttons[pos] = 'active' + if image is None: + raise RuntimeError('Unknown tile type %s at %s' % (c, pos)) + return image + + def validate(self): + entry_points = 0 + exit_points = 0 + for line in self._data: + if ENTRY in line: + entry_points += line.count(ENTRY) + if EXIT in line: + exit_points += line.count(EXIT) + if entry_points == 0: + raise RuntimeError('No entry point') + if entry_points > 1: + raise RuntimeError('Multiple entry points') + if exit_points == 0: + raise RuntimeError('No exit') + def get_tiles(self): return self._tiles def get_single_tile(self, pos): return self._tiles[pos[1]][pos[0]] + def get_tile_type(self, pos): + return self._data[pos[1]][pos[0]] + + def set_tile_type(self, pos, new_type): + self._data[pos[1]][pos[0]] = new_type + new_tile = self._get_tile_image(pos, new_type) + self._tiles[pos[1]][pos[0]] = new_tile + self._changed.append((pos, new_tile)) + # Also update neighbourhood for wall types, etc. + for new_pos in [(pos[0] - 1, pos[1]), (pos[0] + 1, pos[1]), + (pos[0] - 1, pos[1] - 1), (pos[0] + 1, pos[1] + 1), + (pos[0], pos[1] - 1), (pos[0], pos[1] + 1), + (pos[0] - 1, pos[1] + 1), (pos[0] + 1, pos[1] - 1)]: + if not self._in_limits(new_pos): + continue + tile = self._data[new_pos[1]][new_pos[0]] + new_tile = self._get_tile_image(new_pos, tile) + self._tiles[new_pos[1]][new_pos[0]] = new_tile + self._changed.append((new_pos, new_tile)) + def get_size(self): return len(self._tiles[0]), len(self._tiles) def at_exit(self, pos): return pos in self.exit_pos - def _get_wall_tile(self, x, y): + def get_level_data(self): + return '\n'.join(reversed([''.join(x) for x in self._data])) + + def _get_wall_tile(self, pos): # Is the neighbour in this direction also a wall? + x, y = pos left = right = top = bottom = False if x == 0: left = True @@ -121,6 +170,17 @@ class Level(object): return load_image('tiles/end_left.png') return load_image('tiles/pillar.png') + def _in_limits(self, pos): + if pos[0] < 0: + return False + if pos[1] < 0: + return False + try: + self._data[pos[1]][pos[0]] + except IndexError: + return False + return True + def blocked(self, pos): if pos[0] < 0: return True @@ -181,10 +241,16 @@ class LevelList(object): line = line.strip() if os.path.exists(filepath(line)): level_file = load(line) - self.levels.append(Level(level_file)) + level = Level(level_file) level_file.close() + try: + level.validate() + except RuntimeError as err: + raise RuntimeError( + 'Invalid level %s in level_list: %s' % (line, err)) + self.levels.append(level) else: - print 'Level list includes non-existant level %s' % line + raise RuntimeError('Level list includes non-existant level %s' % line) level_list.close() self._cur_level = 0