FreshRSS

Zobrazení pro čtení

Jsou dostupné nové články, klikněte pro obnovení stránky.

Connecting Isolated Paths in Randomly Generated Maps

I am new to game development, I previously created games using tiledmap editor and pygame, but manually creating map was real pain, so i begun to look how can i procedurally generate map, after banging head for few week and googling i finally created a map. However, I'm facing an issue where some paths on the map end up isolated from each other. I'm looking for suggestions or algorithms to connect these isolated parts of the map, ensuring that there is always a continuous path from any point to any other point on the map. The code works on looking at adjacent neighbour but in the end most of the time it cause isolation of part of map by closing path.

from random import random
from pprint import pprint, pformat

WALL = 1
EMPTY = 0
POSSIBLE_WALL_PERCENT = 0.4
ADJACENT_WALL_THRESHOLD = 5
range_X = 1
range_Y = 1

class Map:
    def __init__(self, width: int, height: int):
        self.width = width
        self.height = height
        self.grid = [[EMPTY for _ in range(width)] for _ in range(height)]

        self.random_wall_fill()
        self.place_walls()

    def random_wall_fill(self):
        for row in range(self.height):
            for col in range(self.width):
                if random() < POSSIBLE_WALL_PERCENT:
                    self.grid[row][col] = WALL

    def get_adjacent_wall(self, x: int, y: int, range_x: int, range_y: int):
        wall_count: int = 0
        start_x, end_x = x - range_x, x + range_x
        start_y, end_y = y - range_y, y + range_y  

        for i_y in range(start_y, end_y + 1):
            for i_x in range(start_x, end_x + 1):
                if (i_x != x or i_y != y) and self.is_wall(i_x, i_y):
                    wall_count += 1

        return wall_count

    def place_walls(self):
        for y in range(self.height):
            for x in range(self.width):
                if self.grid[y][x] == EMPTY:
                    if self.place_wall_logic(x, y):
                        self.grid[y][x] = WALL

    def place_wall_logic(self, x, y):
        num_walls = self.get_adjacent_wall(x, y, range_X, range_Y)
        if num_walls >= ADJACENT_WALL_THRESHOLD:
            return True
        else:
            return False

    def is_wall(self, x: int, y: int):
        if self.out_of_bound(x, y):
            return True
        elif self.grid[y][x] == WALL:
            return True
        return False

    def out_of_bound(self, x: int, y: int):
        if x < 0 or x >= len(self.grid[0]):
            return True
        elif y < 0 or y >= len(self.grid):
            return True
        return False

    def display_map(self):
        for row in self.grid:
            for cell in row:
                if cell == WALL:
                    print("0", end=" ")
                else:
                    print(".", end=" ")
            print() 

    def __repr__(self):
        return pformat(self.grid)

level_map = Map(30, 30)
level_map.display_map()

map screenshot

❌