ios Swift:寻找具有相同输出的Java的Random()PRNG的交叉兼容方法

时间:2015-06-15 15:39:48

标签: java ios swift compatibility prng

这是我的delimna: 我正在编写一个应用程序,需要从Java编写的游戏中精确地再现PRNG输出,该游戏使用Java random()和给定的种子来创建它的所有初始游戏“世界”数据。

我面临的问题是Java的random()和ios Swift本地PRNG在给出完全相同的种子时不会生成相同的值。

以下是我的测试用例: 在所有情况下,使用相同的“种子”,公式用于0到9之间的随机整数。

在Java中:

import java.util.Random;
long seed = 987234904;
Random rnd = new Random(seed);
int result = rnd.nextInt(10);

Java random()'result'= 0

在ios Swift中 - 使用srand48()/ drand48():

import UIKit
var seed: Int = 987234904
srand48(seed)
var result = Int(drand48()*10)

ios Swift drand48()'result'= 7

在ios Swift中 - 使用rand_r():

import UIKit
var seed: UInt32 = 987234904
var result = Int(Float(rand_r(&seed))/Float(INT32_MAX)*10)

ios Swift rand_r()result = 4

考虑到这一点 - 是否有一个ios Swift | Objective-C | C ++代码snippit |库在功能和输出方面与Java的random()版本完全相同?

3 个答案:

答案 0 :(得分:0)

不,这是不可能的(最有可能),因为随机的实现甚至不需要通过不同的版本和系统保持不变,您必须实现自己的随机算法以确保。或者你可以生成一个序列,保存它并以某种方式将它传输到另一个设备,但这更加复杂。

查看this链接中的EXAMPLE部分,该部分给出了一个算法,并指出这可能对两台不同的机器有用:

static unsigned long next = 1;

/* RAND_MAX assumed to be 32767 */
int myrand(void) {
    next = next * 1103515245 + 12345;
    return((unsigned)(next/65536) % 32768);
}

void mysrand(unsigned seed) {
    next = seed;
}

您只需将其翻译为首选语言

即可

答案 1 :(得分:0)

在iOS 9和OS X 10.11中,GameplayKit提供了一套确定性PRNG - 其中一个主要原理是,您可以跨多个设备或服务器和客户端之间复制随机序列以进行多人游戏。 (有关更多理由和其他有趣内容,请参阅the WWDC session。)

特别是,GKLinearCongruentialRandomSource使用Knuth标准,因此应与java.util.Random兼容(当使用相同的48位种子进行初始化时)。

答案 2 :(得分:0)

好的 - 这是解决方案:

我在Apple论坛上问了同样的问题,并且'ahltorp'手柄上的一个好人共享了他们一直用于同一件事的c函数。它是快速兼容的,我已经针对我的模拟进行了测试,这是一个完美的数据匹配!

C函数的Github位置:https://github.com/ahltorp/swiftjavarandom

使用它的Swift示例

var inseed: UInt64 = 987234904   
java_random_setseed(&inseed, inseed)  
var result = java_random_nextint_n(&inseed, 10)  
print(result) 

结果= 0: - )

链接到苹果论坛讨论: https://forums.developer.apple.com/thread/5791?q=Swift%20prng