字典值未更新

问题描述 投票:0回答:1

我正在实现波函数崩溃算法,我定义波如下:

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()
python dictionary abstract-data-type
1个回答
0
投票

我认为字典值正在更新

主要内容有一点变化:

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 是不太可能的,这使得程序永远不会结束......

© www.soinside.com 2019 - 2024. All rights reserved.