我正在构建一个多人桌面Air游戏,我需要在两个客户端生成一个相同的随机数。
我一直在阅读其他游戏如何做到这一点,显然如果我在两个客户端都有相同的种子,随机输出将是相同的。
但是我从未尝试过这样做,不知道从哪里开始。
它是如何工作的?这个字符串(让相同的播放器名称)如何保证两个客户端的随机输出是一样的?
答案 0 :(得分:4)
这是概念上容易的事情之一,但在实践中可能会非常困难。
从概念上讲,伪随机数生成器(PRNG)是一种算法,它使用其当前状态信息生成新状态,然后返回该状态的某些函数。例如,线性同余生成器(LCG)几十年来一直是一种流行的选择,因为它们相对快速且易于实现。 LCG是以下形式的递归关系:
R(i+1) = (a * R(i) + b) % m
其中R(i)
是序列中的i th 整数值“随机”数字,a
,b
和m
是精心选择的整数常量。设置种子意味着给PRNG一个初始状态,即为R(0)
分配一个值以启动该过程。现代PRNG通常使用多个递归函数来维持其状态空间中的多个整数,并根据整个状态的某些函数返回单个整数值,但基本原则仍然适用 - 从相同的状态开始将产生完全相同的序列返回PRNG的一系列调用的值。
现在是实际的一面。这意味着如果他们的游戏是同步的,两个玩家将获得相同的结果序列 - 他们从相同的种子开始并经历相同的事件序列,因此他们的PRNG在他们沿着游戏路径做出的每个决定中总是处于相同的状态。但是,做出不同的选择将导致PRNG结果用于不同目的,并且很可能使用不同数量的PRNG结果。玩家的一个选择可能会导致程序绘制2个PRN,其中一个替代选择将会得出3.游戏现在将不同步,并为随后的基于PRNG的结果产生不同的结果,这通常会导致游戏路径进一步远离同步。
维持PRNG使用的同步在实践中很难实现。一种可能的解决方案是维护PRNG状态的多个实例,每个不同的用例一个。例如,特定的战斗将始终在相同的PRNG状态下开始,但这需要预测和维护一大堆独立的PRNG序列。另一种解决方案是预先生成所有实体及其所有属性,实质上是用他们可能参与的每个随机选择或选项对其进行纹身处理,并在他们获得结果时将结果排除在外进入那些情况。这两种方法都很快成为后勤问题。
答案 1 :(得分:4)
我已经制作了多人游戏。通常处理的方式是服务器处理这样的细节,并将数据发送给所有玩家。
如果您在没有涉及服务器的情况下进行点对点,那么一个玩家充当“服务器”或“主机”,生成您需要的任何游戏细节(障碍布局等),然后将该信息传递给对等方(S)。充当“服务器”的玩家没有优势。它的“客户端”代码不具备任何特殊处理(数据传输速度除外)。 “服务器”还在滞后的情况下保持游戏状态。它确定游戏何时“结束”等。
根据您在网络上处理广告的方式,这将决定谁是“主持人”。如果您想讨论它,请发布更多相关细节。在一个简单的设置中,一个玩家决定“主持”一个游戏,它在网络上做广告并且有人加入,并与“主机”建立p2p连接。随着更大的游戏,它变得更加复杂,因为你想要处理“主机”玩家退出的状况。处理方式是所有玩家保持游戏状态,以便其他人可以在“主机”掉线时加强。
在对等体之间存在很多的消息来维持游戏状态。使用回合制游戏这很容易,但动态游戏变得非常复杂。
您对两个客户端生成相同数据集的想法虽然可能是合乎逻辑的但是不可行。