C 我的随机数生成器有问题
我正在自学基本的C语言,并试图创建一个扑克客户端。我有一个带牌的阵列(称为C 我的随机数生成器有问题,c,random,C,Random,我正在自学基本的C语言,并试图创建一个扑克客户端。我有一个带牌的阵列(称为kortaray)和一个玩家牌(称为kortHand)。我的实现不是洗牌牌,而是按顺序添加所有52张牌,然后从牌堆中随机选择5张牌。我添加了一个标志(称为draget),它告诉我们是否在之前提取了一张卡 现在,当我运行下面的算法时,它通常会生成五个随机数,使玩家或计算机的手。但有时它生成的数字少于五个,尽管我特别声明生成五个可接受的值 我有两个循环,一个循环运行五次,另一个嵌套并运行,直到它找到一张尚未拾取的卡。中间的 P
kortaray
)和一个玩家牌(称为kortHand
)。我的实现不是洗牌牌,而是按顺序添加所有52张牌,然后从牌堆中随机选择5张牌。我添加了一个标志(称为draget
),它告诉我们是否在之前提取了一张卡
现在,当我运行下面的算法时,它通常会生成五个随机数,使玩家或计算机的手。但有时它生成的数字少于五个,尽管我特别声明生成五个可接受的值
我有两个循环,一个循环运行五次,另一个嵌套并运行,直到它找到一张尚未拾取的卡。中间的<代码> Prtff <代码>告诉我,该算法并不总是生成五个接受的数字,并且当发生这种情况时,玩家的手包含有无意义值的卡。
srand((unsigned)(time(0)));
for(i = 0; i < 5; i++) {
int x = rand()%52 + 1;
while (kortArray[x].draget!=1) {
x = rand()%52 + 1;
if (kortArray[x].draget != 1) {
printf("%i\n", x);
kortArray[x].draget = 1;
kortHand[i] = kortArray[x];
}
}
}
srand((未签名)(时间(0));
对于(i=0;i<5;i++){
int x=rand()%52+1;
while(kortaray[x].draget!=1){
x=rand()%52+1;
if(kortaray[x].draget!=1){
printf(“%i\n”,x);
Kortaray[x].draget=1;
kortHand[i]=Kortaray[x];
}
}
}
问题仍然在于随机数的+1
此外,如果该卡已被拾取,则首先将第一个分配签入x,然后将其分配给另一张卡
为什么不使用类似于:
int nr_cards_picked = 0 /* Number of uniquely picked cards in hand */
/* Continue picking cards until 5 unique cards are picked. */
while (nr_cards_picked < 5) {
x = rand() % 52; /* Take a random card */
if (kortArray[x].draget == 0) {
/* Pick this card. */
kortArray[x].draget = 1; /* Card is picked */
kortHand[i] = kortArray[x]; /* Add picked card to hand */
nr_cards_picked++;
}
}
int nr_cards_picked=0/*手中唯一挑选的卡片数量*/
/*继续拾取卡片,直到拾取5张唯一的卡片*/
同时(所选卡片数量<5张){
x=rand()%52;/*随机取一张卡*/
if(kortaray[x].draget==0){
/*选这张卡*/
kortArray[x].draget=1;/*卡已拾取*/
kortHand[i]=Kortaray[x];/*将拾取的卡添加到手上*/
nr_卡片_拾取++;
}
}
原谅编译器错误;我这附近没有编译器
这种情况下你只有一次随机号码通话
理论上它可能永远不会结束,但这不太可能。问题仍然在于随机数的+1 此外,如果该卡已被拾取,则首先将第一个分配签入x,然后将其分配给另一张卡 为什么不使用类似于:
int nr_cards_picked = 0 /* Number of uniquely picked cards in hand */
/* Continue picking cards until 5 unique cards are picked. */
while (nr_cards_picked < 5) {
x = rand() % 52; /* Take a random card */
if (kortArray[x].draget == 0) {
/* Pick this card. */
kortArray[x].draget = 1; /* Card is picked */
kortHand[i] = kortArray[x]; /* Add picked card to hand */
nr_cards_picked++;
}
}
int nr_cards_picked=0/*手中唯一挑选的卡片数量*/
/*继续拾取卡片,直到拾取5张唯一的卡片*/
同时(所选卡片数量<5张){
x=rand()%52;/*随机取一张卡*/
if(kortaray[x].draget==0){
/*选这张卡*/
kortArray[x].draget=1;/*卡已拾取*/
kortHand[i]=Kortaray[x];/*将拾取的卡添加到手上*/
nr_卡片_拾取++;
}
}
原谅编译器错误;我这附近没有编译器
这种情况下你只有一次随机号码通话
理论上它可能永远不会结束,但这不太可能。您有:
int x = rand()%52+1;
while (kortArray[x].draget!=1){
x = rand()%52;
C中的数组从0开始索引。第一次调用rand()将生成一个从1开始的值。假设您声明Kortaray[]包含52个值,则有大约2%的可能性会使数组溢出
第一次调用rand()会生成范围为1..52的值。您的第二次呼叫生成0..51。其中一个是错误的。您有:
int x = rand()%52+1;
while (kortArray[x].draget!=1){
x = rand()%52;
C中的数组从0开始索引。第一次调用rand()将生成一个从1开始的值。假设您声明Kortaray[]包含52个值,则有大约2%的可能性会使数组溢出
第一次调用rand()会生成范围为1..52的值。您的第二次呼叫生成0..51。其中一个是错的。有几点值得注意
首先,如果对随机数生成器执行mod操作,则不能保证它们是随机的。更好的办法是将其分成52个部分,然后像这样选择
其次,最好将调用移动到while循环的末尾生成一个随机数,或者不在for循环的开头生成一个随机数
你的问题在于,你有时离开while循环而没有真正进入它,因为你在进入循环之前随机生成了一个数字
考虑到所有这些因素,我将按如下方式编写代码:
srand((unsigned)(time(0)));
for(i=0;i<5;i++){
x=-1;
while (kortArray[x].draget!=1){
x = floor(rand()*52);
}
printf("%i\n", x);
kortArray[x].draget=1;
kortHand[i]=kortArray[x];
}
srand((未签名)(时间(0));
对于(i=0;i一些值得注意的事情
首先,如果你对随机数生成器进行mod操作,就不能保证它是随机的。更好的方法是将它分成52段,然后像这样选择
其次,最好将调用移动到while循环的末尾生成一个随机数,或者不在for循环的开头生成一个随机数
问题的产生是,有时您离开while循环而不实际输入while循环,因为在进入循环之前,您正在随机生成一个数字
考虑到所有这些因素,我将按如下方式编写代码:
srand((unsigned)(time(0)));
for(i=0;i<5;i++){
x=-1;
while (kortArray[x].draget!=1){
x = floor(rand()*52);
}
printf("%i\n", x);
kortArray[x].draget=1;
kortHand[i]=kortArray[x];
}
srand((未签名)(时间(0));
对于(i=0;i嵌套循环仅在Kortaray[x]时输入。draget不是1。因此,每次为1时,都不会执行任何操作,也不会分配任何卡。首先确保您有唯一的x,然后在所有情况下更新kortHand[i]嵌套循环仅在kortArray[x]时输入.draget不是1。因此,每次为1时,都不会执行任何操作,也不会分配任何卡。首先确保您有唯一的x,然后在所有情况下更新kortHand[i]我建议使用不同的算法:
在0和牌组中的牌数之间创建一个随机数
将卡从该位置分配给th