class World: """Represents a world of tiles""" def __init__(self): self.tiles = list() self.coords = dict() self.cots = list() self.dirty = list() pnf = PerlinNoiseFactory(2, octaves=3) for y in range(HEIGHT): for x in range(WIDTH): self.tiles.append(Tile(self, (x, y))) self.coords[(x, y)] = self.tiles[-1] self.tiles[-1].height = int((pnf(x / RES_WIDTH, y / RES_HEIGHT) + 1) / 2 * NUM_HEIGHT) for y in range(HEIGHT): for x in range(WIDTH): tile = self.coords[(x, y)] if x > 0: tile.connect(self.coords[(x - 1, y)]) if y > 0: tile.connect(self.coords[(x - 1, y - 1)], True) if y + 1 < HEIGHT: tile.connect(self.coords[(x - 1, y + 1)], True) if x + 1 < WIDTH: tile.connect(self.coords[(x + 1, y)]) if y > 0: tile.connect(self.coords[(x + 1, y - 1)], True) if y + 1 < HEIGHT: tile.connect(self.coords[(x + 1, y + 1)], True) if y > 0: tile.connect(self.coords[(x, y - 1)]) if y + 1 < HEIGHT: tile.connect(self.coords[(x, y + 1)]) def set_cots(self): """ Initialize a list of COTs It uses K-means clustering to distribute COTs in the world, with each centroid being the COT """ self.cots = [CenterOfTrade(tile) for tile in random.choices(self.tiles, k=NUM_COT)] self.set_distance() for _ in range(NUM_COT_ITER): for cot in self.cots: cot.update() cot.to = list() self.set_distance() def set_distance(self): """ Set distance to all the tiles in the world. It uses a single full loop of multi-source dijkstra's algorithm to do it. """ for tile in self.tiles: tile.distance = None tile.parent = None tile.prev = None tile.dirty = False visited = list() for cot in self.cots: cot.frm.distance = 0 cot.frm.parent = cot cot.frm.prev = cot.frm cot.frm.dirty = False visited.append(cot.frm) while visited: select = heapq.heappop(visited) if not select.dirty: select.dirty = True for item in select.connections: if not item.to.dirty: distance = select.distance + item.weight if item.to.distance is None or item.to.distance > distance: item.to.distance = distance item.to.parent = select.parent item.to.prev = select heapq.heappush(visited, item.to) for cot in self.cots: cot.to = list() for tile in self.tiles: tile.parent.to.append(tile) def update(self): """Update all dirty tiles in the world""" while self.dirty: heapq.heappop(self.dirty).update()