0

I have this program that has a full card deck. I want to display it shuffled randomly but each time I display it, it's displaying it unshuffled. My shuffling method seems not working. How can I fix it so my deck will be displayed shuffled each time.

#include <stdio.h>
#include <time.h>

char* suit[4] = {"Hearts", "Diamonds", "Clubs", "Spades"};
char* face[13] = {"Ace", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine",
    "Ten", "Jack", "Queen", "King"};
char* deck[4][13];

void display(){
    for (int i = 0; i < 4; ++i)
        for (int j = 0; j < 13; ++j)
            printf("%s of %s\n", face[j], suit[i]);
}

void shuffleDeck() {
    int shuffler[52];

    for (int i = 0; i < 52; ++i) {
        shuffler[i] = i;
    }

    //Randomiser
    for (int i = 0; i < 52; ++i) {
        int ind = i+(rand()%(52-i));

        int deckI = ind/13;
        int deckJ = ind%13;

        int temp = shuffler[i];
        shuffler[i] = shuffler[ind];
        shuffler[ind] = temp;

        int temp2 = deck[i/13][i%13];
        deck[i/13][i%13] = deck[deckI][deckJ];
        deck[deckI][deckJ] = temp2;
    }
}

int main() {
    srand(time(NULL));
    shuffleDeck();
    display();
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 2
    See also: • [Shuffle array in C](https://stackoverflow.com/q/06127503/15168) • Wikipedia on [Fisher-Yates Shuffle](http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle) • Jeff Atwood on [The Danger of Naivete](http://www.codinghorror.com/blog/2007/12/the-danger-of-naivete.html). • Ben Pfaff's [implementation](http://benpfaff.org/writings/clc/shuffle.html) • [Why does this simple shuffle algorithm produce biassed results?](https://stackoverflow.com/q/859253/15168) • [Is this C implementation of Fisher-Yates shuffle correct?](https://stackoverflow.com/q/3343797/15168) – Jonathan Leffler Apr 03 '22 at 03:13
  • 1
    Isn't your compiler shrieking about `int temp2 = deck[i/13][i%13];` where you have `char *deck[4][13];`? It should be! – Jonathan Leffler Apr 03 '22 at 03:16
  • 1
    Your `display()` function doesn't display the `deck` at all; it displays the `face` and `suit` arrays, which have not been shuffled. – Jonathan Leffler Apr 03 '22 at 03:17
  • @JonathanLeffler how can i merge the face and suit arrays into the deck 2d array. I think by doing this it might work. – user16218933 Apr 03 '22 at 03:21
  • 1
    Probably something along the lines of `for (int i = 0; i < 52; i++) printf("%s of %s\n", face[deck[i%13]], suit[deck[i/13]]);`? You probably need to redefine `int deck[4][13];` too — or you need two `char *` values per entry in `deck`, one for `suit` and one for `face`. You need to think about your data structures more carefully, IOW. I'm not sure that the `shuffler` array provides any help, either. – Jonathan Leffler Apr 03 '22 at 03:24
  • @JonathanLeffler it gives the error that says deck is undeclared – user16218933 Apr 03 '22 at 03:29
  • @JonathanLeffler bro can you please show me how to do it i've been learning c for 2 weeks and im really still a beginner so i dont get it directly. If you can show me how to do it ill be so thankful and it will be appreciated and ill for sure learn the way for next time i face something like this. thank you for your time anyways whether you show me how or not your previous comments are appreciated. – user16218933 Apr 03 '22 at 03:34
  • @JonathanLeffler Bro you are the best I cant thank you enough!! You made my day!!! Thank you – user16218933 Apr 03 '22 at 04:32

1 Answers1

1

As I noted in comments:

  • Isn't your compiler shrieking about int temp2 = deck[i/13][i%13]; where you have char *deck[4][13];? It should be!

  • Your display() function doesn't display the deck at all; it displays the face and suit arrays, which have not been shuffled.

  • Probably something along the lines of for (int i = 0; i < 52; i++) printf("%s of %s\n", face[deck[i%13]], suit[deck[i/13]]);? You probably need to redefine int deck[4][13]; too — or you need two char * values per entry in deck, one for suit and one for face. You need to think about your data structures more carefully, IOW. I'm not sure that the shuffler array provides any help, either.

The code written on the fly was wrong; it needs to use deck[i]%13 and deck[i]/13 (rather than deck[i%13] and deck[i/13]). The deck is also best represented as an array of 52 integers rather than as a 2D array. While you could work with a 2D array, you'd have to do some moderately major surgery on the code below.

This seems to work. It uses your shuffling code, which is close to a Fisher-Yates shuffle if it is not actually one. It has a biased random number generator. Given the limitations of rand(), it gets nowhere near producing all possible shuffles of a 52-card deck. Note that my comment has the %13 and /13 in the wrong places. Since there is only one source file, all functions except main() are static, and all variables are static too. The face and suit arrays are constant, too.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

static const char * const suit[4] = { "Hearts", "Diamonds", "Clubs", "Spades" };
static const char * const face[13] =
{
    "Ace", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine",
    "Ten", "Jack", "Queen", "King"
};

static int deck[52];

static void displayDeck(const char *tag)
{
    printf("%s:\n", tag);
    for (int i = 0; i < 52; i++)
        printf("%s of %s\n", face[deck[i] % 13], suit[deck[i] / 13]);
}

static void shuffleDeck(void)
{
    for (int i = 0; i < 52; ++i)
    {
        /* Biassed random number generation */
        int ind = i + (rand() % (52 - i));
        int temp = deck[i];
        deck[i] = deck[ind];
        deck[ind] = temp;
    }
}

static void initDeck(void)
{
    for (int i = 0; i < 52; i++)
        deck[i] = i;
}

int main(void)
{
    srand(time(NULL));
    initDeck();
    displayDeck("Before shuffle");
    shuffleDeck();
    displayDeck("After shuffle");
}

Sample output:

Before shuffle:
Ace of Hearts
Two of Hearts
Three of Hearts
Four of Hearts
Five of Hearts
Six of Hearts
Seven of Hearts
Eight of Hearts
Nine of Hearts
Ten of Hearts
Jack of Hearts
Queen of Hearts
King of Hearts
Ace of Diamonds
Two of Diamonds
Three of Diamonds
Four of Diamonds
Five of Diamonds
Six of Diamonds
Seven of Diamonds
Eight of Diamonds
Nine of Diamonds
Ten of Diamonds
Jack of Diamonds
Queen of Diamonds
King of Diamonds
Ace of Clubs
Two of Clubs
Three of Clubs
Four of Clubs
Five of Clubs
Six of Clubs
Seven of Clubs
Eight of Clubs
Nine of Clubs
Ten of Clubs
Jack of Clubs
Queen of Clubs
King of Clubs
Ace of Spades
Two of Spades
Three of Spades
Four of Spades
Five of Spades
Six of Spades
Seven of Spades
Eight of Spades
Nine of Spades
Ten of Spades
Jack of Spades
Queen of Spades
King of Spades
After shuffle:
Six of Spades
Six of Diamonds
Three of Diamonds
Queen of Hearts
Ace of Spades
Four of Spades
Two of Clubs
Six of Clubs
Jack of Diamonds
Five of Clubs
Two of Diamonds
Seven of Spades
Nine of Spades
Five of Hearts
Three of Clubs
Jack of Clubs
Five of Diamonds
Eight of Hearts
Two of Hearts
Five of Spades
King of Hearts
Queen of Clubs
Nine of Diamonds
Four of Diamonds
Seven of Clubs
King of Clubs
Two of Spades
Four of Hearts
Eight of Clubs
Seven of Diamonds
King of Diamonds
Ten of Spades
Six of Hearts
Seven of Hearts
Ten of Clubs
Ace of Clubs
Eight of Diamonds
Ace of Diamonds
Four of Clubs
Queen of Spades
Three of Hearts
King of Spades
Eight of Spades
Nine of Hearts
Nine of Clubs
Three of Spades
Jack of Hearts
Queen of Diamonds
Ten of Hearts
Ace of Hearts
Ten of Diamonds
Jack of Spades

I also used a diagnostic version of displayDeck():

static void displayDeck(const char *tag)
{
    printf("%s:\n", tag);
    for (int i = 0; i < 52; i++)
        printf("%2d [%2d] %s of %s\n", i, deck[i], face[deck[i] % 13], suit[deck[i] / 13]);
}

That helped me spot bugs in intermediate versions of the code. It illustrates how you can make sure your printing helps diagnose issues.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278