在articy:draft中制作你自己的伪随机数生成器

0 点赞
articy:draft
转载

articy:draft没有内置的随机数生成器,但如果你在项目中确实需要,可以自行构建一个。 本指南为英文版本,但根据开发者的建议,我已检查了所有语言标签,以便无论用户的母语是什么,都能看到本指南。 简介 伪随机数生成器通常被称为RNG。许多电子游戏都会使用它们。部分articy:draft用户可能希望了解其游戏机制与RNG的集成效果。尽管articy:draft没有内置伪随机生成器,但我们完全可以通过脚本编写一个。本指南将展示具体方法。 我们将要实现的算法是线性同余生成器,这是一种简单高效且能满足需求的方法。它能快速生成伪随机数,但远非科学可靠。虽然存在许多更好的算法,但它们都需要整数数组,而articy:draft并未实现这一功能。鉴于该软件的局限性,线性同余生成器是我们在articy:draft中编写随机数生成器脚本的最佳选择。 算法与articy的局限性 在开始实际操作指南之前,让我们先了解一下线性同余算法以及在articy中实现该算法所面临的挑战。我们不会深入探讨该算法的数学原理,如果你想了解更多相关内容,可以自行查阅资料。如果我们要在C语言中实现该算法,大致如下: const unsigned long long m = 2147483648; // 模数 const unsigned long long a = 214013; // 乘数 const unsigned long long c = 2531011; // 增量 // 种子数可以是0到(m-1)之间的任意数。 // 每次运行程序时应手动更改此值,以生成不同的伪随机数序列。 unsigned long long seed = 5323; unsigned int genRandom() { seed = (a * seed + c) % m; // 仅使用种子的第30到16位作为随机数。 unsigned long long randomNum = (seed >> 15) & 32767; return (unsigned int) randomNum; } int main() { // 生成1到100之间的伪随机数。unsigned int d100 = genRandom() % 100 + 1; } 上述代码假设unsigned long long是64位无符号整数。它的大小足以处理所涉及的数学运算而不会发生溢出。然而,在articy:draft中,整数只有32位长,并且可以是负数也可以是正数。如果我们按原样实现该算法,很可能会因整数溢出而得到负数。此外,articy:draft中没有位运算符。这有点不方便,因为有了位运算符,我们就可以更轻松地选择种子变量中哪些位用于生成伪随机数。 话虽如此,这些限制不过是些不便之处。我们仍然可以解决这些问题。在articy中编写随机数生成器脚本 第一步是创建一些随机数生成器将要使用的全局变量。在本指南中,我们将把变量集命名为“RNGVars”。

该集合中的所有变量均为整数,具体如下: 【种子值】这是用于算法初始化的起始数字。种子值可以是0到2147483647之间的任意数字。每次开始新进程时,应手动更改该值以生成不同的序列。 【随机数】这是由我们的算法生成的伪随机数。 【掷骰结果】此变量并非算法本身的核心部分。它仅用于将随机数转换为所需范围(例如1到100)。你可以选择忽略它或将其转移到其他变量集中。 接下来,进入流程视图并创建一个名为【生成随机数】的新流程片段。你可以根据需要为其添加描述。

如上图所示,此流程片段将作为实现随机数生成器(RNG)部分的容器。深入此流程片段即可开始构建其内部内容。完成后,处于深入层级的流程应如下所示:

这个水下关卡的第一个区块是一个说明,其外观应与下图所示一致。

创建指令并将父节点的入站引脚连接到此指令的入站引脚。在其中编写以下代码: // 线性同余生成器 RNGVars.Seed = 214013 * RNGVars.Seed + 2531011 接下来,创建一个新条件并将指令的出站引脚连接到该条件的入站引脚。在其中编写以下代码: // Seed = Seed % 2147483648 // Seed 的范围将是 [0, 2147483647] RNGVars.Seed < 0 如以下图片所示,此条件的绿色输出引脚嵌入了脚本。

双击绿色输出引脚,在弹出的窗口中输入以下代码: RNGVars.Seed += 1; RNGVars.Seed += 2147483647;

完成后点击确定。 整个条件实际上是我们实现“Seed = Seed % 2147483648”的变通方法。由于整数溢出,Seed有可能包含负值。因为Seed是32位整数,我们知道其取值范围在-2147483648到2147483647之间。如果Seed的值大于或等于零,那么“Seed % 2147483648”运算将返回Seed的原始值。如果Seed的值小于零,那么给它加上2147483648,其结果将与使用无符号64位整数进行取模运算得到的值相同。但要注意,有符号32位整数的最大值是2147483647。因此,要给Seed加上2147483648,我们首先给它加上2147483647,然后再加1。这些是我们在articy中实现随机数生成器(RNG)时必须完成的一些步骤。 如果最后一段内容让你感到困惑,不用担心。只要你严格按照这些说明操作,就不会有问题。 接下来,我们创建另一个指令,并将前一个条件的两个出站引脚连接到新指令的入站引脚。在这个指令中编写以下脚本: // 使用第30位到第16位生成0到32767之间的随机数。 RNGVars.Random = RNGVars.Seed / 32768

创建第二个条件,并将上一个指令的输出引脚连接到这个新条件的输入引脚。在其中输入以下代码:RNGVars.Random > 32767

上图展示了最后一个条件的外观。注意其绿色输出引脚已点亮,表明其中嵌入了代码。双击绿色输出引脚,在弹出的窗口中输入以下脚本:RNGVars.Random -= 32768

完成后点击确定。 最后,将此条件的两个出站引脚连接到父节点的出站引脚。 你可能会想,这到底是怎么回事?最后的指令和条件是为了在articy中实现以下代码,前提是articy支持位运算: RNGVars.Random = (RNGVars.Seed >> 15) & 32767 可惜的是,articy中没有位运算,所以我们不得不多费些周折来解决这个限制。 到这里,给自己鼓鼓掌吧。你现在在articy中拥有了自己的随机数生成器。太棒了。 伪骰子掷出 我们刚刚创建的随机数生成器将生成一个0到32767之间的伪随机数。你正在设计的游戏可能需要不同范围的随机数,例如d100需要1到100,或者d6需要1到6。你可以通过以下运算将伪随机数转换到不同的数字范围:RNGVars.DiceRoll = RNGVars.Random % RANGE + LOWER_LIMIT。RANGE 应是一个代表你所需随机数范围的数字,LOWER_LIMIT 是该范围的最低值。下图展示了如何实现一个 d100 骰子投掷。

这就是我关于在articy中创建伪随机数生成器的指南。祝你在使用随机数生成器时玩得开心。