我自己学习基本的C并尝试创建一个扑克客户端。我有一个带有牌的阵列(称为kortArray
)和一个牌手(称为kortHand
)。我的实现并没有改变牌组,而是按顺序添加所有52张牌,然后从牌组中随机选择5张牌。我添加了一个标记(称为draget
),用于说明是否已经拾取了卡片。
现在,当我运行下面的算法时,它通常会生成五个随机数,这些数字会影响玩家或计算机。但有时它会生成少于五个数字,即使我已经明确声明要生成五个可接受的值。
我有两个循环,一个循环运行五次,另一个循环运行,直到找到尚未被挑选的卡。中间的printf
告诉我,这个算法并不总是生成五个被接受的数字,当发生这种情况时,玩家的手中包含带有无意义值的卡片。
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];
}
}
}
答案 0 :(得分:4)
问题仍然在于随机数的+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++;
}
}
原谅编译错误;我附近没有编译器。
这种情况下你只有一次随机号码呼叫。
理论上它可能永远不会结束,但这不太可能。
答案 1 :(得分:2)
你有:
int x = rand()%52+1;
while (kortArray[x].draget!=1){
x = rand()%52;
C中的数组从0开始编制索引。第一次调用rand()将生成一个从1开始的值。假设您声明kortArray []保存52个值,那么大约有2%的可能会超出数组。
您对rand()的第一次调用会生成1..52范围内的值。你的第二个电话会产生0..51。其中一个错了。
答案 2 :(得分:2)
有几点需要注意。
首先,如果对它们进行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];
}
答案 3 :(得分:2)
仅当kortArray [x] .draget不为1时才输入嵌套循环。因此,每次为1时,不执行任何操作且未分配卡。首先确保你有一个独特的x然后在所有情况下更新kortHand [i]
答案 4 :(得分:2)
我建议使用不同的算法:
这样,你摆脱了旗帜,你可以保证线性表现。无需检查卡是否已经处理过。