我正在尝试使用C ++构建扑克游戏。甲板洗牌功能给了我一些问题。每次我运行初始化卡组的程序,将其洗牌,然后打印卡组我得到相同的输出:
Shuffling the cards and dealing...
Printing deck...
KD
6S
7D
QD
5C
JH
9S
6D
7H
JD
QH
3C
7S
3H
TC
5D
5S
3D
AD
7C
4H
6H
JC
TS
4D
JS
QC
AH
9C
2D
5H
8C
TD
4S
2S
KS
2C
8D
KC
2H
9H
6C
KH
3S
QS
8S
8H
4C
AS
AC
9D
TH
使用Deck和Card类我的相关功能定义如下:
Deck::Deck(){
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 13; j++) {
cards[i * 13 + j].suit = i;
cards[i * 13 + j].rank = j;
}
}
Card::suits[0] = "D";
Card::suits[1] = "S";
Card::suits[2] = "H";
Card::suits[3] = "C";
Card::ranks[0] = "2";
Card::ranks[1] = "3";
Card::ranks[2] = "4";
Card::ranks[3] = "5";
Card::ranks[4] = "6";
Card::ranks[5] = "7";
Card::ranks[6] = "8";
Card::ranks[7] = "9";
Card::ranks[8] = "T";
Card::ranks[9] = "J";
Card::ranks[10] = "Q";
Card::ranks[11] = "K";
Card::ranks[12] = "A";
}
void Deck::print(){
cout << "Printing deck..." << std::endl;
for (int i = 0; i < 52; i++) {
cout << Card::ranks[cards[i].rank] << Card::suits[cards[i].suit] << endl;
}
cout << endl;
}
void Deck::shuffle(){
top = 51;
int x;
Card tempCard;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 13; j++) {
cards[i * 13 + j].suit = i;
cards[i * 13 + j].rank = j;
}
}
cout << "Shuffling the cards and dealing..." << endl;
for (int i = 0; i < 52; i++) {
x = rand() % 52;
tempCard = cards[i];
cards[i] = cards[x];
cards[x] = tempCard;
}
}
我做错了吗?为什么我应该随机获得相同的结果?感谢。
答案 0 :(得分:5)
假设您可以使用C ++ 11功能,您可以使用它(取自https://stackoverflow.com/a/19728404/341065):
#include <random>
std::random_device rd; // only used once to initialise engine
std::mt19937 rng(rd); // random-number engine used
std::uniform_int_distribution<int> uni(min,max); // guaranteed unbiased
auto random_integer = uni(rng);
答案 1 :(得分:3)
您的代码在随机性方面存在一些问题:
您不会使用srand
对随机数发生器进行播种,因此随机数生成器始终从默认种子值开始。一种常见做法是使用srand(time(NULL))
将当前时间播种。请注意您的计划中的you should seed the randomizer only once。
您使用x = rand() % 52;
。这很糟糕,因为:
典型的rand()
实施是notorious for not being very random in their low-order bits。
来自rand()
(RAND_MAX+1
)的潜在结果数量不太可能被52整除。要理解为什么这是一个问题,想象一下rand()
的极端情况是完全一致的,只能返回{0,1,2}中的一个,并且你rand() % 2
。应该很清楚,这更有可能产生0而不是1.你可以通过使用循环as described in an SO answer by R..来解决这个问题。
对于每张卡,您总是随机地将其与52张卡中的一张交换。 This naive shuffling algorithm is close to being correct but is subtly wrong,这将导致偏见。您应该使用Fisher-Yates shuffling algorithm。由于您使用的是C ++,因此可以使用std::random_shuffle
/ std::shuffle
。
答案 2 :(得分:1)
您需要为随机数生成器播种。特别是在程序开始时调用srand()
一次。一种常见的方法是:
srand(time(NULL));
答案 3 :(得分:-1)
rand()方法,如果没有初始化,则返回相同的&#34;随机&#34;数。您必须使用函数srand()初始化数字生成的起始点。 此函数采用允许生成不同数字的参数。 把这一行
srand(time(0));
在rand函数之前你将拥有不同的数字。 (时间(0)是系统时间。你可以在这里输入一个像100这样的数字,但你总是会有相同的数字。时间(0)这个数字每次都会改变。)