洗牌

题目:

扑克游戏

部分:洗牌、发牌、手中的牌排序

全部:基于网络的扑克游戏


详解:

扑克游戏洗牌

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# include <stdio.h>
# include <stdlib.h>
# include <time.h>
# define CARDS 52
# define SHUFFLE_TIMES 100

void shuffle(int deck[]);
void print_deck(int deck[]);
int main() {
int deck[CARDS];
for (int i = 0; i < CARDS; i++) {
deck[i] = i;
}
shuffle(deck);
print_deck(deck);
return 0;
}
void shuffle(int deck[]) {
srand(time(NULL));
for (int i = 0; i < SHUFFLE_TIMES; i++) {
int idx1 = rand() % CARDS;
int idx2 = rand() % CARDS;
int temp = deck[idx1];
deck[idx1] = deck[idx2];
deck[idx2] = temp;
}
}
void print_deck(int deck[]) {
for (int i = 0; i < CARDS; i++) {
printf("%d ", deck[i]);
if ((i + 1) % 13 == 0) {
printf("\n");
}
}
}

这段程序可以实现基本的洗牌功能,但也有一些问题和不足之处:

综上所述,这段程序生成的牌并不是完全随机的,而是有一定的规律和偏差的。如果要提高洗牌的质量,可以考虑以下几点改进:

  • 改进一:使用一个更好的随机数生成器,例如梅森旋转算法56,它可以生成高质量的伪随机数序列,且周期非常长。C语言中可以使用mt19937函数来实现这个算法 。

  • 改进二:使用一个更好的洗牌算法,例如Fisher-Yates算法 ,它可以保证每张牌在每个位置出现的概率相等,且只需要进行N次交换,其中N是牌的数量。C语言中可以用如下代码实现这个算法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void shuffle(int deck[]) {
    srand(time(NULL));
    for (int i = CARDS - 1; i > 0; i--) {
    int j = rand() % (i + 1);
    // 生成0到i之间的随机数
    int temp = deck[i];
    deck[i] = deck[j];
    deck[j] = temp;
    }
    }
  • 改进三:将一些常量或参数封装成宏或变量,例如SHUFFLE_TIMES,13等,以便于修改和扩展。或者使用枚举类型来表示牌的花色和大小,以提高程序的可读性和可维护性。