Can't randomize cards. Some of them are duplicates

限于喜欢 提交于 2021-01-07 06:36:41

问题


I'm new to C, I am trying to randomize 16 cards. In the longer comments I wrote something that I don't have much clear... Btw this is the code:

#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)
}

For example in line 38 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 tough (loads indefinitely) so I left only one *, but I don't know why. I think that the problem is somewhere inside checker (maybe this ** thing).

One of the randomized outputs, as you can see, there are duplicates.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

回答1:


You should first create the deck with every card without duplicates in the array:

void shuffle(const char *wFace[], const char *wSuit[], char wMixed[][20]){
    srand(time(NULL));
    for (size_t i=0; i<FACES; ++i){
        for (size_t j=0; j<SUITS; ++j){
            sprintf(wMixed[i*SUITS+j], "%s of %s\n", *(wFace+i), *(wSuit+j));  // save the card string
            printf("%s", wMixed[i*SUITS+j]);   // print card string
        }
    }

    /*Add Fisher-Yates shuffle here*/

}

Then use the Fisher-Yates shuffle algorithm to shuffle the array...




回答2:


Writing (*(wwMixed+current) == *(wwMixed+i)) is essentially the same as writing:

(wwMixed[current] == wwMixed[i])

That is why you only need 1 *.

Since wwMixed[i] contains a string, and you want to compare strings, I suggest you use strcmp():

if ( (strcmp(*(wwMixed+current),*(wwMixed+i)) == 0) && (current!=i) )
    return 1;



来源:https://stackoverflow.com/questions/61732065/cant-randomize-cards-some-of-them-are-duplicates

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!