我正在用Python编写一个游戏,其中环境是随机生成的。目前,游戏的“保存”功能通过写出玩家探索过的环境的所有部分来工作。结果是保存文件比它们需要的大 - 为什么当你可以再次生成它时将随机数据写入磁盘?
我可以使用的是一个随机噪声函数:一个函数noise
,使noise(x)
返回一个随机数,并且每当用它调用时,它总是相同的数字值x
。现在,对于游戏环境中的每个点(x,y)
,我不是使用random()
生成随机数并将结果存储在env[(x,y)]
中,而是使用noise((x,y))
生成随机数扔掉它,然后生成相同的数字。
答案 0 :(得分:4)
我不太确定我是否说明了这一点,但使用Perlin噪声发生器的某些变体是一种常见的方法。 This post很好地说明了这一点(正如评论中提到的那样not exactly Perlin noise)
对于给定位置,Perlin函数将返回随机值(位置可以是2D,3D或任何维度)。
上有类似的帖子答案 1 :(得分:2)
首先,如果你需要它是真的,噪声(x)将始终为相同的x返回相同的值,无论如何,即使它从未被调用过,那么你根本不能真正使用随机性。一个好的哈希函数是唯一的可能性。
但是,如果您只需要能够恢复包含所有之前探索过的点的值的先前状态(保存和加载后从未探索过的点可能会有所不同)如果你还没有退出......但是如果没有访问多个宇宙,谁能告诉你?),而你不想存储所有这些点,那么重新生成它们是合理的。
但是让我们退一步吧。你想要一些像哈希函数一样的东西。你可以使用哈希函数吗?
我认为hashlib
中的算法太慢了(md5
可能是最快的,但是测试它们全部),但我不会在没有实际测试的情况下拒绝它们。
zlib.adler32
(或zlib.crc32
)的“随机时段”可能太短,但我不会拒绝它(除了hash
除外)而不考虑是否是hash
够好了。就此而言,即使md5
加上一个不错的固定侧混合器功能也可能足够好(至少在64位系统上)。
Python没有提供“seed
和”adler32“之间的任何内容。但是你可以找到数百种其他哈希算法的PyPI模块或源代码。就此而言,如果您熟悉任何听起来不错的特定哈希算法,其中大多数都是微不足道的 - 您可能可以编写代码,例如FNV hash使用xor-folding,花费的时间比您需要的时间少。看看其他选择。
另外,请记住,您可以在“新游戏”时生成一堆随机字节,将其存储在保存文件中,并将其用作哈希函数的盐。
如果你已经筋疲力尽,那么你真的做需要更多的随机性,而不是任意盐的快速哈希函数可以让你独自一人,那么:
听起来你已经需要存储用户探索过的点列表(因为你怎么知道还需要恢复哪些点?)。订单并不重要。因此,您可以按探索顺序存储它们。这意味着您可以确定性地重新生成值(只需迭代列表)。这意味着您可以根据自己的答案使用@delnan的建议。
但是,setstate
不是这样做的方法。无法保证每次在运行,Python版本,机器等之间将RNG置于相同的状态。为此,您需要random.getstate()
:
random.setstate(state)
,然后挑选并存储结果。random.Random
。有关详细信息,请参阅the docs。
如果你使用的是random.Random
个实例,那就完全相同了,当然除非你需要构建一个setstate
,然后再调用random.Random
。
这保证可以在程序运行之间,跨机器等运行。即使使用较新版本的Python也是如此。但是,不保证与较旧的版本的Python一起使用。 (也就是说,如果用户使用Python 2.6保存游戏,然后尝试用2.5加载它,状态将不兼容。我认为唯一的问题是2.6->更旧和2.3->更老,但是当然不能保证将来不会有其他的。)我建议存放Python版本,如果它们降级,则显示警告说“此保存文件需要Python 2.6或更高版本。你有Python 2.5负载可能会失败。无论如何都要继续?“
这仅保证random
和random.Random
模块本身(因为顶级模块功能只使用隐藏的random.SystemRandom
)。特别是,明确记录random.Random
不起作用。
实际上,你也可以直接挑选一个Random
,因为状态被腌制了。看起来应该有效,或者腌制getstate
对象的感觉是什么?它确实有效。但实际上并没有记录下来,所以为了安全起见,我会坚持使用{{1}}进行酸洗。
答案 2 :(得分:1)
noise
的一种可能实现是:
import random
def noise(point):
gen = random.Random()
gen.seed(point)
return gen.random()
我不知道Random.seed()
有多快。此外,Random
可能会从一个版本的Python变为另一个版本,导致我的游戏玩家在升级时发现环境发生变化。