gpt4 book ai didi

c - 使用 setstate(3) 不会产生预期的随机数序列

转载 作者:太空宇宙 更新时间:2023-11-04 08:45:01 25 4
gpt4 key购买 nike

对于多人游戏,我需要在所有参与的设备上生成相同的随机数序列。显然,这是通过在所有设备上使用相同的种子来实现的。当在本应在所有设备上生成相同序列的例程之外调用 random() 时,就会出现问题。因此,在此例程中,我尝试使用 setstate 来保存状态数组。据我了解 man random(3),在此例程之外调用 random() 不应更改序列。

但是,以下代码不会为运行 1 和运行 2 产生相同的输出:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(int argc, const char * argv[])
{

char state[256];

printf("Run 1 : ");
initstate(123, state, 256);
for (int i=1; i < 10; i++) {
printf("%ld ", random());
}

printf("\nRun 2 : ");
initstate(123, state, 256);
for (int i=1; i < 10; i++) {
setstate(state); // load preserved state
printf("%ld ", random());
*state = *setstate(state); // preserve state
random(); // this simulates a call to random() from outside
}
printf("\n");
return 0;
}


Run 1 : 1597493280 1407130876 1753502901 1965067074 377602131 83146350 274392949 1718024305 1016176754
Run 2 : 1597493280 537479855 1611694138 941096776 83164437 1459338036 1256894804 1618690717 1091902527
Program ended with exit code: 0

有人知道为什么吗?或者,也许还有另一种方法可以达到预期的效果?

备案:使用 Xcode 5 在 OS X 和 iOS 上运行。

编辑在 Arkku 和 minitech 的帮助下,以下更改使运行 2 的输出与运行 1 相同:

    printf("\nRun 2 : ");
char otherstate[256];
initstate(123, state, 256);
for (int i=1; i < 10; i++) {
// preserve whatever state is currently active
// and set the current state to "my" state
memcpy(otherstate, setstate(state), 256);
printf("%ld ", random());
// switch back to the other state
memcpy(state, setstate(otherstate), 256);
// now this call does not affect the sequence that get's printf'd
random();
}
printf("\n");

最佳答案

在第二个循环中,您调用了 random() 而没有打印出值。此外,setstate 行没有用;每次都使用相同的数组 (state),因此状态会不断变化。这两个序列变得完全相同:

for (int i = 1; i <= 2; ++i) {
printf("\nRun %d: ", i);
initstate(123, state, sizeof(state));
for (int i=1; i < 10; i++) {
printf("%ld ", random());
}
}

如果您需要在生成一些随机数后保存状态,然后返回到相同状态,您必须在不同状态数组之间交替,例如:

char state[256], state2[256];
initstate(123, state, sizeof(state));
char *saved = initstate(123, state2, sizeof(state2));
for (int i=1; i < 10; i++) {
saved = setstate(saved);
printf("%ld ", random());
saved = setstate(saved);
(void) random();
(void) random();
}

每次调用 initstatesetstate 都会返回一个指向previous 状态数组的指针。要返回该状态,您需要调用 setstate 并将其作为参数并将返回的指针存储在某处(可能指向相同的指针,如此处所示)。您还需要有两个不同的状态数组,否则您将一遍又一遍地设置相同的数组——在上面的示例中,saved 的初始值来自 second调用initstate,即第一次调用时设置的状态数组。 (第一次调用可能会返回一些内部数组,但为了获得与所需数组大小一致的结果,我认为最好自己创建两个数组。)

关于c - 使用 setstate(3) 不会产生预期的随机数序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22029134/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com