我正在创建一个利用程序创建的地牢图的python roguelike。我决定使用pythons的列表来实现这一点。我创建了一个2d列表(矩阵)用作地图,并使用0表示空白。为了在地牢中创建“房间”,我使用了随机生成的变量来确定房间右上角的随机行和列,并使用for循环并遍历随机数的行和行,将0替换为1(以表示房间)。列:
示例网格事先
00000000000000
00000000000000
00000000000000
00000000000000
00000000000000
00000000000000
创建并插入房间后的示例网格:
00000000000000 or 00000000000000 etc
01111000000000 00000111111000
01111000000000 00000111111000
01111000000000 00000000000000
00000000000000 00000000000000
00000000000000 00000000000000
具有创建网格,创建和插入房间以及打印网格的功能的代码:
import random
rand_row = random.randint(0,25)
rand_column = random.randint(0,25)
room_height = random.randint(7,15)
room_length = random.randint(7,15)
def create_grid():
global grid
grid = [[0 for column in range (50)] for row in range(50)]
create_room()
def create_room():
global grid
print (f"Room generated is of length {room_length} and height {room_height}")
print (f"Room placed randomly in row {rand_row} and column {rand_column}")
print (" ")
if room_height > 0:
for point in grid[rand_row]:
for each_number in range(room_length):
for increment in range(room_height):
grid[rand_row+increment][rand_column+each_number] = 1
def print_grid():
global grid
for row in grid:
print(" ".join(map(str,row)))
create_grid()
print_grid()
我不知道该怎么做,就是要生成多个房间,同时确保它们之间没有重叠。我试图使一个检查子例程返回一个布尔值,该布尔值取决于房间大小和位置的随机生成的值是否可以工作(如果与另一个房间重叠,则不能工作):
def check_if_space_taken():
global space_is_taken
global grid
for each_row in range(rand_row,room_height+rand_row):
if any(1 in each_row for each_row in grid):
space_is_taken = True
else:
space_is_taken = False
但是,我不知道如何利用它,我甚至不确定它是否有效。我还创建了一个更改所有房间值的函数:
def change_room_params():
cfg.first_row = random.randint(0,50)
cfg.first_column = random.randint(0,50)
cfg.temp_room_height = random.randint(5,20)
cfg.temp_room_length = random.randint(5,20)
但是我知道,如果随机数继续给出不起作用的值,则检查过程可能会花费很长时间。
总而言之,我如何为新房间创建新参数并检查房间之间是否有重叠:因此创建新值并在有重叠的情况下重复该过程,或者在没有重叠的情况下创建该房间,然后重复该过程。进行处理,直到绝对没有空间容纳更多房间为止。
非常感谢您的帮助。香港专业教育学院张贴这个问题之前,但删除并重新做了更多细节。一般而言,我对python或编程的经验不是很丰富,因此非常感谢提高我的任务效率的建议。
答案 0 :(得分:0)
一种改进是使用numpy arrays而不是python列表。尤其是当您有巨大的地图时。
然后,您可以使用skimage draw module绘制多边形或矩形。要检查房间是否拦截,您可以检查新房间的任何点处数组中是否已有1。此检查不应花费很长时间。尤其是只有一次时。为了避免无限循环。您可以设置较高的最大迭代次数。而且,如果您没有足够的房间,只需将阵列清零并重做该过程即可。
我创建了一个应该起作用的代码。如果您有任何问题,请随时在评论中提问。
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
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.]]