【发布时间】:2020-05-11 14:25:31
【问题描述】:
我是 C 新手,我正在尝试随机化 16 张卡片。在较长的 cmets 中,我写了一些我不太清楚的东西......顺便说一句,这是代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define FACES 4
#define SUITS 4
void shuffle(char *wFace[], char *wSuit[], char *wMixed[][20]); // prototype
size_t checker(char *wwMixed[][20], size_t current); // prototype
int main(){
char *face[] = {"Jack", "Queen", "King", "Ace"};
char *suit[] = {"Hearts", "Spades", "Diamonds", "Clubs"};
char *mixed_cards[FACES*SUITS][20] = {0}; // initialize the final array
shuffle(face,suit,mixed_cards); // send to shuffle the pointer array
for (size_t k=0; k<FACES*SUITS;++k){ // at the end
printf("%s\n", *(mixed_cards+k)); // it prints the results
}
}
void shuffle(char *wFace[], char *wSuit[], char *wMixed[][20]){
srand(time(NULL));
for (size_t j = 0; j<(FACES*SUITS); ++j){ // for every card
do {
size_t face = rand() % FACES; // choose randomly
size_t suit = rand() % SUITS; // choose randomly
sprintf(*(wMixed+j), "%s of %s", *(wFace+face), *(wSuit+suit)); // copy to *(wMixed+j) so in mixed_card[j][0] matrix
} while (checker(wMixed, j)); // it does the cycle until checker function says that the string is unique
}
}
size_t checker(char *wwMixed[][20], size_t current){
for (size_t i=0; i<FACES*SUITS;++i){
if ( (*(wwMixed+current) == *(wwMixed+i)) && (current!=i) ) { // I don't get why I should use ONLY ONE *, since if I use only one it should be comparing ADDRESSES, NOT VALUES. if I put ** it doesn't work though, but I don't know why.
return 1; // the string is already in use, so it has to continue to randomize. it returns 1 and the while cycle continues so new rand string is created
}
}
return 0; // otherwise, if this for cycle doesn't find any duplicate, it returns 0 to shuffle function and while stops so j is increased (in the other for)
}
例如,在第 38 行,我不明白为什么我应该只使用一个 *,因为如果我只使用一个,它应该是比较地址,而不是值。如果我输入**,它就不会起作用(无限期地加载),所以我只留下了一个*,但我不知道为什么。
我认为问题出在检查器内部的某个地方(可能是** 的东西)。
其中一个随机输出,如您所见,有重复。c
Jack of Diamonds
Queen of Clubs
Ace of Hearts
Jack of Clubs
Ace of Diamonds
King of Diamonds
Ace of Spades
Jack of Spades
King of Spades
Jack of Clubs
Jack of Spades
King of Spades
King of Clubs
Queen of Hearts
King of Spades
King of Spades
【问题讨论】:
-
制作一个包含所有可能值的数组,打乱数组(可能是fischer-yates algorithm?)
-
@pmg 如何处理重复?
-
mixed_cards当前是char *的二维数组,但看起来它应该是char的二维数组:char mixed_cards[FACES*SUITS][20] = {0};。然后wMixed(和wwMixed)函数参数应声明为:char wMixed[][20]或char (*wMixed)[20](wwMixed相同)。可以使用sprintf(wMixed[j], "%s of %s", wFace[face], wSuit[suit]);等数组索引操作。 -
处理扑克牌的常用方法是将
0编码为12为黑桃A,将13编码为25为黑桃A红桃 A,26到38是梅花,39到51是方块(或附近),所以序列0, 1, 2, ..., 51包含所有 52 张牌且没有重复。
标签: c arrays pointers random shuffle