def get_vert_and_horiz(cell, width=1): x, y = cell.x, cell.y return [ Cell(x, y + width), Cell(x - width, y), Cell(x, y - width), Cell(x + width, y), ]
def get_diagonals(cell, width=1): x, y = cell.x, cell.y return [ Cell(x + width, y + width), Cell(x - width, y + width), Cell(x + width, y - width), Cell(x - width, y - width) ]
def get_line_coordinates(start, end, width=1): # тут был round :D x1, y1 = start.x, start.y x2, y2 = end.x, end.y return [ Cell(x2 + width, y2 + width), Cell(x2 + width, y2 - width), Cell(x1 - width, y1 - width), Cell(x1 - width, y1 + width), ]
def __init__(self, flow_dirs, nx=None, ny=None, lons2d=None, lats2d=None, accumulation_area_km2=None): self.cells = [] self.lons2d = lons2d self.lats2d = lats2d self.flow_directions = flow_dirs self.accumulation_area_km2 = accumulation_area_km2 # calculate characteristic distance if not any([None is arr for arr in [self.lats2d, self.lons2d]]): v1 = lat_lon.lon_lat_to_cartesian(self.lons2d[0, 0], self.lats2d[0, 0]) v2 = lat_lon.lon_lat_to_cartesian(self.lons2d[1, 1], self.lats2d[1, 1]) dv = np.array(v2) - np.array(v1) self.characteristic_distance = np.sqrt(np.dot(dv, dv)) x, y, z = lat_lon.lon_lat_to_cartesian(self.lons2d.flatten(), self.lats2d.flatten()) self.kdtree = cKDTree(list(zip(x, y, z))) if None not in [nx, ny]: self.nx = nx self.ny = ny else: nx, ny = flow_dirs.shape self.nx, self.ny = flow_dirs.shape for i in range(nx): self.cells.append(list([Cell(i=i, j=j, flow_dir_value=flow_dirs[i, j]) for j in range(ny)])) self._without_next_mask = np.zeros((nx, ny), dtype=np.int) self._wo_next_wo_prev_mask = np.zeros((nx, ny), dtype=np.int) # mask of the potential outlets for i in range(nx): if i % 100 == 0: print("Created {}/{}".format(i, nx)) for j in range(ny): i_next, j_next = direction_and_value.to_indices(i, j, flow_dirs[i][j]) next_cell = None if 0 <= i_next < nx: if 0 <= j_next < ny: next_cell = self.cells[i_next][j_next] self._without_next_mask[i, j] = int(next_cell is None) self.cells[i][j].set_next(next_cell)
class Map: map = tuple((tuple(Cell(x, y) for y in range(Y_CELLS_COUNT))) for x in range(X_CELLS_COUNT)) me = None @staticmethod def get_player_territories(points, player): result = () for point in points: Map.map[point[0]][point[1]].type = Entities.MY_CAPTURE if player.its_me() else Entities.CAPTURE Map.map[point[0]][point[1]].entity = player result += (Map.map[point[0]][point[1]], ) return result @staticmethod def get_player_lines(points, player): result = () for point in points: Map.map[point[0]][point[1]].type = Entities.MY_LINE if player.its_me() else Entities.LINE Map.map[point[0]][point[1]].entity = player result += (Map.map[point[0]][point[1]], ) return result @staticmethod def get_player_cell(point, player): if player.its_me(): Map.me = player Map.map[point[0]][point[1]].type = Entities.MY_PLAYER if player.its_me() else Entities.PLAYER Map.map[point[0]][point[1]].entity = player return Map.map[point[0]][point[1]] @staticmethod def get_bonus_cell(point, bonus): Map.map[point[0]][point[1]].type = Entities.BONUS Map.map[point[0]][point[1]].entity = bonus return Map.map[point[0]][point[1]] @staticmethod def in_boundary(x, y): if 0 <= x < X_CELLS_COUNT and 0 <= y < Y_CELLS_COUNT: return True return False @staticmethod def get_path(start, stop): path = [LEFT] * max(0, start.x - stop.x) + [RIGHT] * max(0, stop.x - start.x) path += [DOWN] * max(0, start.y - stop.y) + [UP] * max(0, stop.y - start.y) return path command_shift = { LEFT: (-1, 0), RIGHT: (1, 0), UP: (0, 1), DOWN: (0, -1) } @staticmethod def get_points(cell, commands, single=False): if commands is None: return None if not isinstance(commands, list): commands = [commands] x, y = cell.x, cell.y result = [] for command in commands: xs, ys = Map.command_shift[command] x += xs y += ys result.append(Map.map[x][y]) return result[0] if single and result else result @staticmethod def get_siblings(cell): x, y = cell.x, cell.y dx = (-1, 1, 0, 0) dy = (0, 0, -1, 1) result = [] for i in range(4): nx, ny = x + dx[i], y + dy[i] if Map.in_boundary(nx, ny): result.append(Map.map[nx][ny]) return result @staticmethod def get_safe_siblings(cell): return [s for s in Map.get_siblings(cell) if s != Map.get_points(Map.me.cell, REVERSED_DIRECTIONS[Map.me.direction], single=True) and s.type not in [Entities.MY_LINE, Entities.MY_PLAYER]] # TODO Переписать @staticmethod def bfs_paths(start, goal, _filter=None): if not _filter: _filter = Map.get_safe_siblings visited, queue = set(), [[start, []]] while queue: vertex, path = queue.pop(0) for next in _filter(vertex): if next == goal: return path + [next] if next not in visited: visited.add(next) queue.append([next, path + [next]])