看360 看360看360

肉鸽(Roguelike)游戏的种子是怎么记录一整局游戏的?

以下是为大家精心整理的"肉鸽(Roguelike)游戏的种子是怎么记录一整局游戏的?"相关知识及问题的最佳答案:

肉鸽(Roguelike)游戏的种子是怎么记录一整局游戏的?

这个问题本质是计算机中如何实现随机数算法。

我们知道,计算机是一个非常一丝不苟的工具,它会忠实地执行我们交给它的指令,没有一点错误。在平时这是一件好事,但是如果我们想要获得随机数,那就有些麻烦了:随机数本来就是要随性的!

应该如何解决这个问题呢?也许你会想,既然计算机本身无法做到随性,那我们就从随性的大自然中进行采样吧。比如在计算机中安装一个温度计,用测得温度的某几位小数作为随机数。这是一种解决思路,但是并非现在的主流方法。

那么现在的人们一般怎么做呢?靠的是随机数算法。

这个名字听起来就很奇怪。所谓算法,要求之一就是给定输入的情况下,输出必须是固定的,不能含有随机性。这样一个固定的东西,又如何生成随机数呢?

其实很简单,随机数算法本身并不是随机的,但是它给出的结果可以当成随机数来用。我们要随机数是干什么的?当然不是盯着它好玩的,我们拿着随机数,可以进行科学计算中的随机采样,可以用于蒙特卡洛算法,可以用于随机生成一局roguelike游戏。我们的根本目的,并不是随机数本身,而是随机数的这些用途,既然如此,我们也没必要追求真正随机的序列,只要手中的这个序列能发挥和随机数几乎一样的效果就行。

这就是所谓的“伪随机”,它并不是说概率受到了人为的操控,什么“仓检”之类的。实际上,伪随机是指,生成这个序列的算法本身是固定的,但是这个序列看起来、用起来和真正的随机数基本一样。

随机数算法长什么样呢?一般来讲,它会要求你把序列中的当前数字输入进去,然后它会把一串乱七八糟的运算作用到这个数字上面,得到序列中的下一个数字。这一串乱七八糟的运算,就是保证生成的序列用起来和真正的随机数一样的关键所在了。这么看来,只要我们有序列中的当前数字,就可以不断去生成序列后面的数字。

但是,序列的第一个数字要怎么得到呢?这就只能靠人为指定,或者用之前的“温度计”方法获得了。这第一个数字,就是所谓的随机种子。

现在我们回到你一开始的问题上面来。

如果你没有指定种子,那么游戏会随便选择一个种子,一般是用当前的系统时间,这就和刚才的温度计是差不多的思路。当前系统时间本身是一个不断增大的数值,所以如果像刚才的温度计的例子一样,直接把系统时间拿过来作为随机数是肯定不行的。但是如果我们把系统时间作为随机种子,启动随机数算法,那就确实可以很好地模仿随机数了。

现在,你手动指定了种子。我们知道,随机数算法本身是固定的,所以只要你一直指定同一个种子,那么你得到的看上去、用起来和真正的随机数一样的序列,就一定是同一个。接着游戏就会用这个序列去生成房间,分配敌人,设置宝箱的奖励等等。

那么,有了固定的序列,我们就一定能得到相同的一局游戏吗?也不一定。这么说吧,假设这个游戏分成好几层,每层都是单独生成的。如果它会在一开始一口气把这么多层都生成好,那么固定的序列确实会产生相同的一局游戏。但是,如果它是先生成一层,把你放进去打,而且你的战斗过程也用到了这个序列,那么,后面几层可能就不一样了。为什么会这样呢?比如,你的每次攻击都有可能暴击,这样一来,你每攻击一次,就会从这个序列中消耗掉一个数字。如果你这一次一共攻击了90次,但是下一次重开的时候攻击了91次,那么从这个序列中消耗掉的数字就不一样多了,你最后一次攻击用到的数字,可能本来是用来生成下一层的第一个房间的,结果现在用来计算暴击了,而生成房间的过程就只能用下一个数字。这样一来,虽然序列还是那个序列,但是序列中每个数字的用途,从此开始就不一样了。

这就是我们的答案:要想生成相同的一局游戏,不仅序列要是同一个,而且序列中每个数的用途也要一样。游戏程序本身是一丝不苟的,所以只要它一口气把整局游戏都生成完,那么你确实会得到相同的一局游戏。但是如果它先生成一部分,然后让你去打,这就引入了人类活动的因素,而人类活动可是充满了随机性,这样就很可能改变后面的数的用途,也就得不到完全一样的一局游戏了。

当然,一般roguelike游戏还是希望忠实地还原种子记录下的那一局,所以会采用前面那种策略。

有了精妙的随机数算法,你就可以用一串简单的随机种子,记录下一整局复杂的游戏了!


肉鸽(Roguelike)游戏的种子是怎么记录一整局游戏的?

这个问题本质是计算机中如何实现随机数算法。

我们知道,计算机是一个非常一丝不苟的工具,它会忠实地执行我们交给它的指令,没有一点错误。在平时这是一件好事,但是如果我们想要获得随机数,那就有些麻烦了:随机数本来就是要随性的!

应该如何解决这个问题呢?也许你会想,既然计算机本身无法做到随性,那我们就从随性的大自然中进行采样吧。比如在计算机中安装一个温度计,用测得温度的某几位小数作为随机数。这是一种解决思路,但是并非现在的主流方法。

那么现在的人们一般怎么做呢?靠的是随机数算法。

这个名字听起来就很奇怪。所谓算法,要求之一就是给定输入的情况下,输出必须是固定的,不能含有随机性。这样一个固定的东西,又如何生成随机数呢?

其实很简单,随机数算法本身并不是随机的,但是它给出的结果可以当成随机数来用。我们要随机数是干什么的?当然不是盯着它好玩的,我们拿着随机数,可以进行科学计算中的随机采样,可以用于蒙特卡洛算法,可以用于随机生成一局roguelike游戏。我们的根本目的,并不是随机数本身,而是随机数的这些用途,既然如此,我们也没必要追求真正随机的序列,只要手中的这个序列能发挥和随机数几乎一样的效果就行。

这就是所谓的“伪随机”,它并不是说概率受到了人为的操控,什么“仓检”之类的。实际上,伪随机是指,生成这个序列的算法本身是固定的,但是这个序列看起来、用起来和真正的随机数基本一样。

随机数算法长什么样呢?一般来讲,它会要求你把序列中的当前数字输入进去,然后它会把一串乱七八糟的运算作用到这个数字上面,得到序列中的下一个数字。这一串乱七八糟的运算,就是保证生成的序列用起来和真正的随机数一样的关键所在了。这么看来,只要我们有序列中的当前数字,就可以不断去生成序列后面的数字。

但是,序列的第一个数字要怎么得到呢?这就只能靠人为指定,或者用之前的“温度计”方法获得了。这第一个数字,就是所谓的随机种子。

现在我们回到你一开始的问题上面来。

如果你没有指定种子,那么游戏会随便选择一个种子,一般是用当前的系统时间,这就和刚才的温度计是差不多的思路。当前系统时间本身是一个不断增大的数值,所以如果像刚才的温度计的例子一样,直接把系统时间拿过来作为随机数是肯定不行的。但是如果我们把系统时间作为随机种子,启动随机数算法,那就确实可以很好地模仿随机数了。

现在,你手动指定了种子。我们知道,随机数算法本身是固定的,所以只要你一直指定同一个种子,那么你得到的看上去、用起来和真正的随机数一样的序列,就一定是同一个。接着游戏就会用这个序列去生成房间,分配敌人,设置宝箱的奖励等等。

那么,有了固定的序列,我们就一定能得到相同的一局游戏吗?也不一定。这么说吧,假设这个游戏分成好几层,每层都是单独生成的。如果它会在一开始一口气把这么多层都生成好,那么固定的序列确实会产生相同的一局游戏。但是,如果它是先生成一层,把你放进去打,而且你的战斗过程也用到了这个序列,那么,后面几层可能就不一样了。为什么会这样呢?比如,你的每次攻击都有可能暴击,这样一来,你每攻击一次,就会从这个序列中消耗掉一个数字。如果你这一次一共攻击了90次,但是下一次重开的时候攻击了91次,那么从这个序列中消耗掉的数字就不一样多了,你最后一次攻击用到的数字,可能本来是用来生成下一层的第一个房间的,结果现在用来计算暴击了,而生成房间的过程就只能用下一个数字。这样一来,虽然序列还是那个序列,但是序列中每个数字的用途,从此开始就不一样了。

这就是我们的答案:要想生成相同的一局游戏,不仅序列要是同一个,而且序列中每个数的用途也要一样。游戏程序本身是一丝不苟的,所以只要它一口气把整局游戏都生成完,那么你确实会得到相同的一局游戏。但是如果它先生成一部分,然后让你去打,这就引入了人类活动的因素,而人类活动可是充满了随机性,这样就很可能改变后面的数的用途,也就得不到完全一样的一局游戏了。

当然,一般roguelike游戏还是希望忠实地还原种子记录下的那一局,所以会采用前面那种策略。

有了精妙的随机数算法,你就可以用一串简单的随机种子,记录下一整局复杂的游戏了!


肉鸽(Roguelike)游戏的种子是怎么记录一整局游戏的?

混沌理论只要起始条件有些微的偏差,差错会如雪崩一般越滚越大,宏观上看后续的发展就会截然不同

这就是混沌理论,在自然界中广泛存在这一现象,随着学界将这一理论应用于技术实践,我们便获得了制造随机的能力。

伪随机与噪声函数

由于种种限制,我们平日使用的计算机生成随机数并不是真正的随机,本质上不过是一个看起来混乱随机的序列,然而这个序列的顺序是完全固定的,只要知道制造序列的种子和算法,就能完美复现这个随机序列,甚至直接读取这个序列的任意位置。

通过取sin的小数部分制造看似极其不规律的波动,但是通过sin函数可以简单快速获取任意位置的值

使用Unity生成各类型噪声图的分享 - 加索尔加加加的文章 -

也可以看看catlike里的各种噪声函数的制作过程:Unity Pseudorandom Noise Tutorials

实现伪随机的算法有很多,各有各自的应用场景,从1维、2维到3维,从短平快到波澜起伏。

但是他们都有一个共同点,就是利用了函数的特性:

只要传入一个任意的坐标值,就能立即计算对应坐标的随机数。

这就意味着,你不需要一格一格从头算到尾,每一个位置的随机数都是可以独立计算获得的,同时这种算法用的函数基本都是分布在负无穷到正无穷的实数域,意味着随机的范围也是无穷大的。

游戏应用

有了可控的随机生成算法,就可以在游戏里制造无穷多的随机,同时根据种子精确复现,比如柏林噪声通过梯度计算,保证了结果的连续平滑,游戏中一个应用就是波澜起伏的山脉:

minecraft使用柏林噪声制作波澜起伏的地形

当然实际应用中往往是通过多个噪声叠加,并且调节大量参数才能达到这么复杂曲折的效果。

随机的范围自然也不限于地形,可以说只要用到数值计算的部分,都可以从噪声函数提取随机值来计算。从创建世界时地形、宝箱、怪物的分布,到装备、角色的数值,到战斗时造成的伤害,都可以用这样的方式来获得。

从这一点上来说,这就是一个宿命论的世界,当你选定种子后,整个世界的一切都是按照既定的规则去运转的。

不过冥冥之中还是有一个变数,那就是作为玩家的你,只有你做出的操作,无论是操作的时间还是操作的顺序,都是随机的种子所无法控制的,而这也让这个命中注定的世界有了不一样的可能。


肉鸽(Roguelike)游戏的种子是怎么记录一整局游戏的?

混沌理论只要起始条件有些微的偏差,差错会如雪崩一般越滚越大,宏观上看后续的发展就会截然不同

这就是混沌理论,在自然界中广泛存在这一现象,随着学界将这一理论应用于技术实践,我们便获得了制造随机的能力。

伪随机与噪声函数

由于种种限制,我们平日使用的计算机生成随机数并不是真正的随机,本质上不过是一个看起来混乱随机的序列,然而这个序列的顺序是完全固定的,只要知道制造序列的种子和算法,就能完美复现这个随机序列,甚至直接读取这个序列的任意位置。

通过取sin的小数部分制造看似极其不规律的波动,但是通过sin函数可以简单快速获取任意位置的值

使用Unity生成各类型噪声图的分享 - 加索尔加加加的文章 -

也可以看看catlike里的各种噪声函数的制作过程:Unity Pseudorandom Noise Tutorials

实现伪随机的算法有很多,各有各自的应用场景,从1维、2维到3维,从短平快到波澜起伏。

但是他们都有一个共同点,就是利用了函数的特性:

只要传入一个任意的坐标值,就能立即计算对应坐标的随机数。

这就意味着,你不需要一格一格从头算到尾,每一个位置的随机数都是可以独立计算获得的,同时这种算法用的函数基本都是分布在负无穷到正无穷的实数域,意味着随机的范围也是无穷大的。

游戏应用

有了可控的随机生成算法,就可以在游戏里制造无穷多的随机,同时根据种子精确复现,比如柏林噪声通过梯度计算,保证了结果的连续平滑,游戏中一个应用就是波澜起伏的山脉:

minecraft使用柏林噪声制作波澜起伏的地形

当然实际应用中往往是通过多个噪声叠加,并且调节大量参数才能达到这么复杂曲折的效果。

随机的范围自然也不限于地形,可以说只要用到数值计算的部分,都可以从噪声函数提取随机值来计算。从创建世界时地形、宝箱、怪物的分布,到装备、角色的数值,到战斗时造成的伤害,都可以用这样的方式来获得。

从这一点上来说,这就是一个宿命论的世界,当你选定种子后,整个世界的一切都是按照既定的规则去运转的。

不过冥冥之中还是有一个变数,那就是作为玩家的你,只有你做出的操作,无论是操作的时间还是操作的顺序,都是随机的种子所无法控制的,而这也让这个命中注定的世界有了不一样的可能。


肉鸽(Roguelike)游戏的种子是怎么记录一整局游戏的?

是利用伪随机数实现的,具体如下:

1.设定一个种子:1

2.根据这个种子 就会生成一个顺序固定且随机的序列,在代码上这些随机数是完全固定的,但是玩家并看不到这些调用的位置和顺序,所以感觉整个游戏是随机的

例如:这生成的这串随机数是749164960281654826185

随机一个地牢是就可以用上面的这个序列,每个数字假设代表房间类型。这样我就可以只储存随机种子,就能复显着一串完全一样的随机数,那我也就可以重现上次完全一样的关卡地图。

同理,我只要换个随机数种子,那就可以随机生成完全不一样的一个关卡。

最重要的是严格按照固定的顺序去使用这些随机数串。


肉鸽(Roguelike)游戏的种子是怎么记录一整局游戏的?

是利用伪随机数实现的,具体如下:

1.设定一个种子:1

2.根据这个种子 就会生成一个顺序固定且随机的序列,在代码上这些随机数是完全固定的,但是玩家并看不到这些调用的位置和顺序,所以感觉整个游戏是随机的

例如:这生成的这串随机数是749164960281654826185

随机一个地牢是就可以用上面的这个序列,每个数字假设代表房间类型。这样我就可以只储存随机种子,就能复显着一串完全一样的随机数,那我也就可以重现上次完全一样的关卡地图。

同理,我只要换个随机数种子,那就可以随机生成完全不一样的一个关卡。

最重要的是严格按照固定的顺序去使用这些随机数串。