我正在实现波函数崩溃算法,我定义波如下:
wave = {divmod(n, HEIGHT): types.copy() for n in range(HEIGHT * WIDTH)}
然后,当我更新仓位的可能状态时,它不会改变。我用这个来更新它:
wave[(nx, ny)] = new # update possibilities
wave[pos] = {chosen_type} # collapse to one state
我想知道问题是否是使用 divmod 或 tuple 作为键,或者是否是关于在 dict 中存储集合。
这是完整的代码:
import random
WIDTH, HEIGHT = 20, 20
class TileType:
def __init__(self, name):
self.allowed = set()
self.name = name
def __repr__(self):
return self.name
def add_allowed(self, *types):
for type_ in types:
self.allowed.add(type_)
type_.allowed.add(self)
def generate(types):
def propagate(xy, *allowed):
x, y = xy
for dx, dy in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
nx, ny = x + dx, y + dy
if 0 <= nx < WIDTH and 0 <= ny < HEIGHT:
new = wave[(nx, ny)].union(*allowed)
if new.difference(wave[(nx, ny)]):
wave[(nx, ny)] = new
propagate((nx, ny), *(tile.allowed for tile in new))
# Initialize wave state
assert len(types) > 0
wave = {divmod(n, HEIGHT): types.copy() for n in range(HEIGHT * WIDTH)}
while True:
pos, entropy = min(wave.items(), key=lambda i: (len(i[1]) if len(i[1]) != 1 else 9e+9))
entropy = len(entropy)
assert entropy != 0
if entropy == 9e+9:
break
chosen_type = tuple(wave[pos])[random.randint(0, entropy - 1)]
print(pos, entropy, chosen_type)
wave[pos] = {chosen_type}
propagate(pos, chosen_type.allowed)
def main():
t0 = TileType("0")
t1 = TileType("1")
t2 = TileType("2")
t3 = TileType("3")
t4 = TileType("4")
t0.add_allowed(t4, t2)
t1.add_allowed(t3, t4)
t2.add_allowed(t3)
generate({t0, t1, t2, t3, t4})
if __name__ == '__main__':
main()
我认为字典值正在更新
主要内容有一点变化:
def generate(types):
def propagate(xy, *allowed):
x, y = xy
for dx, dy in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
nx, ny = x + dx, y + dy
if 0 <= nx < WIDTH and 0 <= ny < HEIGHT:
new = wave[(nx, ny)].union(*allowed)
if new.difference(wave[(nx, ny)]):
wave[(nx, ny)] = new
propagate((nx, ny), *(tile.allowed for tile in new))
# Initialize wave state
assert len(types) > 0
wave = {divmod(n, HEIGHT): types.copy() for n in range(HEIGHT * WIDTH)}
print(wave)
while True:
pos, entropy = min(wave.items(), key=lambda i: (len(i[1]) if len(i[1]) != 1 else 9e+9))
print("pos", pos)
entropy = len(entropy)
assert entropy != 0
if entropy == 9e+9:
break
chosen_type = tuple(wave[pos])[random.randint(0, entropy - 1)]
print(pos, entropy, chosen_type)
wave[pos] = {chosen_type}
propagate(pos, chosen_type.allowed)
break
print(wave)
我得到了输出...
(0, 0): {1, 3, 2, 0, 4}, ...
pos (0, 0)
(0, 0) 5 4
{(0, 0): {4}, ...
所以字典波更新了我不太确定你正在实现的算法,也许 while 停止条件有点不可能达到。
if entropy == 9e+9:
break
因为 min 返回较小的值,而不是 key 返回的值。我认为熵 entropy == 9e+9 是不太可能的,这使得程序永远不会结束......