嗯,标题不太合适,请继续阅读(我无法获得更好的标题)。
注意:使用Python 2.7,但算法也会有所帮助。
我制作了一个侧卷轴游戏,我在飞行中产生障碍物。我遇到的麻烦是弄清楚如何产生障碍。 O_O
我有一种逻辑,但是我在弄清楚整个逻辑时遇到了麻烦。
从实施的角度来看,这是我的问题:
我有一个Surface
,其中我放了一些Element
s,它们都是矩形
把它想象成:
0 0 0 0 0 0 0
0 0 0 0 1 1 0
0 0 0 0 1 1 0
0 0 0 0 1 1 0
0 0 0 0 0 0 0
0 1 1 0 0 1 1
0 0 0 0 0 1 1
与上述结构一样,如何确定是否可以添加axb
矩形而不重叠另一个矩形(1s),以及所有矩形。此外,通过与所有其他对象保持x个元素(甚至是对角线)的距离,这意味着整个矩形是(x + 3,x + 4)。像x=1, a=3, b=4
这样的东西,只有一种可能的安排:
(2s代表新对象)
2 2 2 0 0 0 0
2 2 2 0 1 1 0
2 2 2 0 1 1 0
2 2 2 0 1 1 0
0 0 0 0 0 0 0
0 1 1 0 0 1 1
0 0 0 0 0 1 1
基本上,我需要找到所有的点,方括号a
和b
的矩形可以包含它,例如,左上角。如何实现这一目标?
注意:打开更好的想法,以便立即产生障碍!
PS:我在这里以及程序员问过这个问题,因为我认为它在两个网站上都有主题。
答案 0 :(得分:1)
以下应该可以很好地运作:
def find_valid_locations(grid, z, a, b):
check = [(0, 0, 0, 0)]
w = z + b
h = z + a
while check:
x, y, ox, oy = check.pop()
if x + w >= len(grid) or y + h >= len(grid[0]):
continue
for i, row in enumerate(grid[x+ox:x+w+1], x+ox):
for j, val in enumerate(row[y+oy:y+h+1], y+oy):
if val:
break
else:
continue
check.append((x, j+1, 0, 0))
if y == 0:
check.extend((ii, j+1, 0, 0) for ii in range(x+1, i+1))
check.append((i+1, y, 0, 0))
break
else:
yield (x, y)
check.append((x, y+1, 0, h-1))
if y == 0:
check.append((x+1, y, w-1, 0))
continue
此处的强力方法是检查每个潜在矩形位置中的所有位置,并仅返回矩形未遇到非零位置的位置。这基本上就是我们在这里所做的,具有以下优化:
请注意,我将参数x
重命名为z
,以便我可以在代码中使用x
作为行索引。
答案 1 :(得分:0)
您可以将曲面存储在矩阵M中,然后遍历矩阵以找到新矩形R的左上角的位置:
for all rows of matrix M
for all columns of matrix M
variable empty = 0
for all numbers from 1 to a
for all numbers from 1 to b
empty = empty + M(row + a, col + b)
if empty == 0
insert R(row,col) //insert R with top-left corner at M(row,col)
break;
答案 2 :(得分:0)
这是一个强力搜索,它考虑了一个矩形a,b的所有可能位置,其中边界c位于一个二维Python列表(列表列表)的网格中。
在调用find_placements
之前, isvalid
会将边框宽度和边框高度相加。这种方式isvalid
不需要考虑边界的任何内容。
我使用变量a, b, c
作为宽度,高度,边框,这样它们就不会混淆坐标,这些坐标通常是x, y, z
之类的东西。 gx
和gy
是网格x和网格y的缩写。
一个差异在于,使用以这种方式表示网格的二维列表,使用grid[y][x]
而不是grid[x][y]
来访问单元格。其他一切都非常直接。
def find_placements(grid, a, b, c):
"""
Return [(x, y), ...] for all valid placements in the grid
of rectangle a x b with border c.
"""
result = []
for gx in xrange(len(grid[0]) - (a + c)):
for gy in xrange(len(grid) - (b + c)):
if isvalid(grid, (a + c), (b + c), gx, gy):
result.append((gx, gy))
return result
def isvalid(grid, a, b, x, y):
"""
Return True if rect a, b fits at pos x, y
without overlapping.
"""
for gx in xrange(x + a):
for gy in xrange(y + b):
if grid[gy][gx]:
return False
return True
>>> grid =[
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 0],
[0, 0, 0, 0, 1, 1, 0],
[0, 0, 0, 0, 1, 1, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 0, 0, 1, 1],
[0, 0, 0, 0, 0, 1, 1]
]
>>> find_placements(grid, 3, 4, 1)
[(0, 0)]
>>>