一种改进是使用numpy 数组而不是python列表。 尤其是当您有巨大的地图时。

然后,您可以使用skimage绘制模块绘制多边形或矩形。 要检查房间是否拦截,您可以检查新房间的任何点处数组中是否已有1。 此检查不应花费很长时间。 尤其是只有一次时。 为了避免无限循环。 您可以设置较高的最大迭代次数。 如果您没有足够的房间,则将阵列归零并重做该过程。

我创建了一个应该起作用的代码。 如果您有任何问题,请随时在评论中提问。

numpy和skimage的方法

def insert_room(data, row, col) -> bool:
if row + ROOM_HEIGHT > MAP_HEIGHT or col + ROOM_LENGTH > MAP_WIDTH or row < 0 or col < 0:
return False
# This method assumes that all rooms are equal in size
if (data[row][col] == 1 or
data[row + ROOM_HEIGHT - 1][col] == 1 or
data[row][col + ROOM_LENGTH - 1] == 1 or
data[row + ROOM_HEIGHT - 1][col + ROOM_LENGTH - 1] == 1):
return False
for r in range(row, row + ROOM_HEIGHT):
for c in range(col, col + ROOM_LENGTH):
data[r][c] = 1
return True
允许所有房间大小
def insert_room(data, row, col) -> bool:
if row + ROOM_HEIGHT > MAP_HEIGHT or col + ROOM_LENGTH > MAP_WIDTH or row < 0 or col < 0:
return False
# Can room be added
for r in range(row, ROOM_HEIGHT):
if any(data[r][col:col+ROOM_LENGTH]):
return False
# Add room
for r in range(row, row + ROOM_HEIGHT):
for c in range(col, col + ROOM_LENGTH):
data[r][c] = 1
return True
numpy和skimage的方法
import numpy as np
import random
import skimage.draw
MAP_WIDTH = 10
MAP_HEIGHT = 10
ROOM_LENGTH = 3
ROOM_HEIGHT = 3
NUM_ROOMS = 5
def create_map():
# These values define how long you gonna to try to create a map
outer_max_iteration = 10
max_iteration = 1000
outer_iteration = 0
iteration = 0
created_rooms = 0
data = np.zeros((MAP_WIDTH, MAP_HEIGHT))
while created_rooms < NUM_ROOMS and outer_iteration < outer_max_iteration:
data = np.zeros((MAP_WIDTH, MAP_HEIGHT))
while created_rooms < NUM_ROOMS and iteration < max_iteration:
col = random.randint(0, MAP_WIDTH - ROOM_LENGTH)
row = random.randint(0, MAP_HEIGHT - ROOM_HEIGHT)
inserted = insert_room(data, col, row)
created_rooms += inserted
iteration += 1
outer_iteration += 1
if created_rooms < NUM_ROOMS:
print("ERROR: Map cannot contain so many rooms!")
print(data)
return data
def insert_room(data, row, col) -> bool:
# check bounds
if row + ROOM_HEIGHT > MAP_HEIGHT or col + ROOM_LENGTH > MAP_WIDTH or row < 0 or col < 0:
return False
#: The rows of the polygon
r = np.array([row, row, row + ROOM_HEIGHT, row + ROOM_HEIGHT])
#: The columns of the polygon
c = np.array([col, col + ROOM_LENGTH, col + ROOM_LENGTH, col])
# create data where room should be created
rr, cc = skimage.draw.polygon(r, c)
#: check if room overlap with existing
if not any(data[rr, cc]):
data[rr, cc] = 1
return True
return False
示例输出:
[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[1. 1. 1. 0. 0. 0. 1. 1. 1. 0.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 0.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 0.]
[0. 0. 0. 1. 1. 1. 1. 1. 1. 0.]
[0. 0. 0. 0. 0. 0. 1. 1. 1. 0.]
[0. 1. 1. 1. 0. 0. 1. 1. 1. 0.]
[0. 1. 1. 1. 0. 0. 0. 0. 0. 0.]
[0. 1. 1. 1. 0. 0. 0. 0. 0. 0.]]