Я делаю генератор астероидов, который создает двумерный массив bool
с.Генератор принимает параметр int
, size
, который должен определять, сколько True
ячеек будет в двумерном массиве.
Как я могу гарантировать, что в выходном массиве нет дыр ичто правильное количество ячеек True
?
Я видел вопрос Случайное создание кластеров в двумерном массиве , но я не могу придумать, как применить его для моего использованияслучай, так как мне нужно знать количество плиток, которые должны быть сгенерированы.
В приведенном ниже коде я случайным образом размещаю плитки, а затем использую клеточные автоматы, чтобы сгладить и убедиться, что нет отверстий, но сохраняя правильное числопроблема состоит из True
ячеек, тем более что удаление случайных ячеек True
для обеспечения правильного размера может создать дыры.
def create_shape(size, seed):
# init rng with seed
rng = random.Random(seed)
# initial grid values empty and full mass left
# make the grid size by size so any shape could fit
grid = [[False for x in range(size)] for y in range(size)]
mass_remaining = size
# guarantee the center is something
center = size // 2
grid[center][center] = True
mass_remaining -= 1 # remember to reduce available mass
# generate random values
for x in range(size):
for y in range(size):
# skip the already filled in center
if x == y == center:
continue
# assign random value
value = bool(rng.randint(0, 1))
grid[y][x] = value
# remember to reduce mass
if value:
mass_remaining -= 1
# smoothen things out with cellular automata neighbor checking
for x in range(size):
for y in range(size):
# skip the center
if x == y == center:
continue
# get neighbors
# set neighbors is the count of neighbors set to True
set_neighbors = 0
for i in range(-1, 2):
for j in range(-1, 2):
# skip counting self
if i == j == 0:
continue
nx, ny = x + i, y + j
if 0 <= nx < size and 0 <= ny < size:
# only get in-range cells
if grid[ny][nx]:
set_neighbors += 1
# more than 3 -> become True, less than 3 -> become False
if set_neighbors > 3:
grid[y][x] = True
mass_remaining -= 1
elif set_neighbors < 3:
grid[y][x] = False
mass_remaining += 1
else:
# otherwise leave it the same
pass
# find out how well the mass is staying "in-budget"
print(mass_remaining)
return grid
Функция часто print
s выделяет целый ряд различныхоставшиеся массовые количества, например, имеющие -14
в «долге» или имеющие 42
дополнительно.Я бы ожидал, что на выходе будет 0
, если функция будет работать правильно.
Например, вывод, подобный этому ...
create_shape(8) ->
[ 0, 0, 0, 0, 0, 0,
0, 1, 1, 0, 0, 0,
0, 1, 1, 1, 0, 0,
0, 1, 1, 1, 1, 0,
0, 1, 1, 1, 1, 0 ]
... сплошной, но имеет слишком многоустановить плитки.