使用 GDScript 的本机伪随机数生成器 100% 可预测结果

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

我正在使用 GDScript(Godot 的 Python)尝试创建一种算法,在二维数组上生成整数 0 或 1 之间的随机噪声。为此,我使用预定义变量进行迭代,将每个值附加到数组上的相关位置。我知道伪随机数生成器可以揭示偏差,特别是如果在短时间内使用并以较低范围定义的话,但即使考虑到这些因素,我似乎也得到了 100% 一致(即不是随机)的结果。也就是说,数组上的每个子数组在exact相同的索引处包含exact相同的字符集。

我的代码非常简单:

var subMap: Array[int]
var geographyMap: Array[Array]
func generate_map():
    print("Generate map function called")
    var mapHeight: int = 10
    var mapWidth: int = 10
    geographyMap.clear()
    for yy in mapHeight:
        subMap.clear()
        for xx in mapWidth:
            var chance: int = randi_range(0, 1000)
            if (chance > 500):
                subMap.append(1)
            else:
                subMap.append(0)
        geographyMap.append(subMap)

    for i in geographyMap:
        print(i)

结果总是这样:

example 1:
[1, 0, 0, 1, 0, 0, 1, 0, 1, 0]
[1, 0, 0, 1, 0, 0, 1, 0, 1, 0]
[1, 0, 0, 1, 0, 0, 1, 0, 1, 0]
[1, 0, 0, 1, 0, 0, 1, 0, 1, 0]
[1, 0, 0, 1, 0, 0, 1, 0, 1, 0]
[1, 0, 0, 1, 0, 0, 1, 0, 1, 0]
[1, 0, 0, 1, 0, 0, 1, 0, 1, 0]
[1, 0, 0, 1, 0, 0, 1, 0, 1, 0]
[1, 0, 0, 1, 0, 0, 1, 0, 1, 0]
[1, 0, 0, 1, 0, 0, 1, 0, 1, 0]

example 2:
[0, 1, 0, 0, 1, 0, 0, 0, 0, 0]
[0, 1, 0, 0, 1, 0, 0, 0, 0, 0]
[0, 1, 0, 0, 1, 0, 0, 0, 0, 0]
[0, 1, 0, 0, 1, 0, 0, 0, 0, 0]
[0, 1, 0, 0, 1, 0, 0, 0, 0, 0]
[0, 1, 0, 0, 1, 0, 0, 0, 0, 0]
[0, 1, 0, 0, 1, 0, 0, 0, 0, 0]
[0, 1, 0, 0, 1, 0, 0, 0, 0, 0]
[0, 1, 0, 0, 1, 0, 0, 0, 0, 0]
[0, 1, 0, 0, 1, 0, 0, 0, 0, 0]

example 3:
[1, 1, 0, 1, 1, 1, 0, 1, 1, 1]
[1, 1, 0, 1, 1, 1, 0, 1, 1, 1]
[1, 1, 0, 1, 1, 1, 0, 1, 1, 1]
[1, 1, 0, 1, 1, 1, 0, 1, 1, 1]
[1, 1, 0, 1, 1, 1, 0, 1, 1, 1]
[1, 1, 0, 1, 1, 1, 0, 1, 1, 1]
[1, 1, 0, 1, 1, 1, 0, 1, 1, 1]
[1, 1, 0, 1, 1, 1, 0, 1, 1, 1]
[1, 1, 0, 1, 1, 1, 0, 1, 1, 1]
[1, 1, 0, 1, 1, 1, 0, 1, 1, 1]

单个子数组中 1 和 0 的位置会随着每次尝试而改变,但每次在数组中它们总是匹配的。当我强制函数减慢速度、强制它每次都获取新种子、更改数组的维度或更改 rng 的范围时,这不会改变。

我使用伪随机生成器是否错误?我似乎无法让这段代码在整个板上生成任何实际上随机的东西,仅在单个子数组中生成该模式在整个数组中重复的子数组。当然,我清除 subMap 数组是为了确保我不会在每个元素上粘贴相同的结果或不断扩展每个元素的长度,因此它不应该是 subMap 数组不变的结果。任何使这个 rng 真正成为 rng 的帮助将不胜感激。

编辑:包括我声明 subMap 数组的部分

edit2:修复代码格式

edit3:包含将结果打印到控制台的代码部分

edit4:附加上下文

注意: 根据 GDScript 文档,显然,现在项目默认运行时会调用 randomize() 函数(它生成一个种子供 randi 函数使用)。为了以防万一,我尝试了此代码的一个版本,其中包含 _ready() 处的 randomize() 函数,但这并不能解决问题。在随机数生成器的每次迭代中调用 randomize() (文档无论如何都不推荐)也没有解决问题。

random random-seed gdscript perlin-noise
1个回答
0
投票

找出问题所在。默认情况下,GDScript 中数组的append() 函数依赖于您在参数中输入的任何值的浅表副本。换句话说,尽管在 geographyMap 中的每个元素处清除并创建了新的 subMap 数组,但每次我这样做时,geographyMap 中的所有元素都会更新以匹配新的 subMap 数组。我通过在append()函数中调用duplicate(true)函数来强制进行深度复制来解决这个问题,如下所示:

geographyMap.append(subMap.duplicate(true))
© www.soinside.com 2019 - 2024. All rights reserved.