Thread: Card Shuffle Print Error

  1. #1
    Registered User
    Join Date
    Mar 2017
    Posts
    13

    Card Shuffle Print Error

    Hello! Once again, I have another program from Pearson. (copyright ended 2013, but just in case).

    I rewrote the code, but in the end, it still won't print out. It doesn't give me any errors or warnings during compilation, either, and I am just learning this content for the first time.

    Can anyone help me debug this?

    Code:
    #include <stdio.h>#include <stdlib.h>
    #include <time.h>
    
    
    #define SUITS 4
    #define FACES 13
    #define CARDS 52
    
    
    
    
    void shuffle(unsigned int wDeck[][FACES]);
    void deal(unsigned int wDeck[][FACES], const char *wFace[],
              const char *wSuit[]);
    
    
    int main(void)
    {
    
    
        const char *suit[SUITS] =
        { "Hearts", "Diamonds", "Clubs", "Spades" };
    
    
        const char *face[FACES] =
        { "Ace", "Deuce", "Three", "Four", "Five", "Six", "Seven",
            "Eight", "Nine", "Ten", "Jack", "Queen", "King" };
    
    
        unsigned int deck[SUITS][FACES] = { 0 };
    
    
        srand(time(NULL));
    
    
        shuffle(deck);
        deal(deck, face, suit);
    }
    
    
    void shuffle(unsigned int wDeck[][FACES])
    {
        size_t row;
        size_t column;
        size_t card;
    
    
        for (card = 1; card <= CARDS; card++)
        {
            do
            {
                row = rand() % SUITS;
                column = rand() % FACES;
            } while (wDeck[row][column] != 0);
        }
    
    
        wDeck[row][column] = card;
    }
    
    
    void deal(unsigned int wDeck[][FACES], const char *wFace[],
              const char *wSuit[])
    {
        size_t card;
        size_t row;
        size_t column;
    
    
        for (card = 1; card <= CARDS; card++)
        {
            for (row = 0; row < SUITS; row++)
            {
                for (column = 0; column < FACES; column++)
                {
                    if (wDeck[row][column] == card)
                    {
                        printf("%5s of %-8s%s", wFace[column], wSuit[row],
                               card % 2 == 0 ? '\n' : '\t');
                    }
                }
            }
        }
    }

  2. #2
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,111
    Code:
    for (card = 1; card <= CARDS; card++)
    All arrays are 0 based, NOT 1! IOW, the first element of card is 0!

    Your code should be:
    Code:
    for (card = 0; card < CARDS; card++)
    Please make sure that warnings are actually turn on, and turned up to the highest level for the compiler you are using.

    In your "deal()" function, you are attempting to pint the newline or tab as a string, not a char:
    Code:
    printf("%5s of %-8s%s", wFace[column], wSuit[row],
                     card % 2 == 0 ? '\n' : '\t');
    Should be:
    Code:
    printf("%5s of %-8s%c", wFace[column], wSuit[row],
                     card % 2 == 0 ? '\n' : '\t');
    EDIT: This corrects the basic errors, but not the logic.
    Last edited by rstanley; 04-15-2017 at 11:14 AM.

  3. #3
    Registered User
    Join Date
    Mar 2017
    Posts
    13
    I changed the code, but for some reason, the 2-column format is off.
    Everything prints correctly, but I can't get 2 columns (26 cards/inputs each)
    Here is the revised code:

    Code:
    #include <stdio.h>#include <stdlib.h>
    #include <time.h>
    
    
    #define SUITS 4
    #define FACES 13
    #define CARDS 52
    
    
    
    
    void shuffle(unsigned int wDeck[][FACES]);
    void deal(unsigned int wDeck[][FACES], const char *wFace[],
              const char *wSuit[]);
    
    
    int main(void)
    {
    
    
        const char *suit[SUITS] =
        { "Hearts", "Diamonds", "Clubs", "Spades" };
    
    
        const char *face[FACES] =
        { "Ace", "Deuce", "Three", "Four", "Five", "Six", "Seven",
            "Eight", "Nine", "Ten", "Jack", "Queen", "King" };
    
    
        unsigned int deck[SUITS][FACES] = { 0 };
    
    
        srand(time(NULL));
    
    
        shuffle(deck);
        deal(deck, face, suit);
    }
    
    
    void shuffle(unsigned int wDeck[][FACES])
    {
        size_t row;
        size_t column;
        size_t card;
    
    
        for (card = 0; card < CARDS; card++)
        {
            do
            {
                row = rand() % SUITS;
                column = rand() % FACES;
            } while (wDeck[row][column] != 0);
        }
    
    
        wDeck[row][column] = card;
    }
    
    
    void deal(unsigned int wDeck[][FACES], const char *wFace[],
              const char *wSuit[])
    {
        size_t card;
        size_t row;
        size_t column;
    
    
        for (card = 0; card < CARDS; card++)
        {
            for (row = 0; row < SUITS; row++)
            {
                for (column = 0; column < FACES; column++)
                {
                    if (wDeck[row][column] == card)
                    {
                        printf("%5s of %-8s%c", wFace[column], wSuit[row],
                            card % 2 == 0 ? '\n' : '\t');
                    }
                }
            }
        }
    }

  4. #4
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,111
    a "Deck" really should be an array of structs, where each struct contains a pointer to a Suit, and a Face, for the 52 cards.

    Then shuffle should swap two different randomly selected "cards" in the deck, for at least 52 times.

    The "Deal" should just print out all 52 "cards" in the deck, in order from subscript 0 to 51.

    Try this and repost you code. Good luck!

  5. #5
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    The line wDeck[row][column] = card; does need to be inside the for loop body.

    But you don't need to represent cards in this complex way nor shuffle them so inefficiently. Cards can be represented by integers from 0 to 51. The suit is that integer divided by 13 (giving a number from 0 to 3) and the value (not face!) is that integer modulus 13 plus one (giving a number from 1 to 13, or leave out the plus one to index an array from 0 to 12).
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    #define NUM_SUITS    4
    #define NUM_VALUES  13
    #define NUM_CARDS  (NUM_SUITS * NUM_VALUES)
    
    // comment this out to not use unicode characters for suit symbols
    #define USE_UTF8_SUITS
    
    void print_value(int c) {
        printf("%c", "A23456789TJQK"[c % NUM_VALUES]);
    }
    
    void print_suit(int c) {
    #ifdef USE_UTF8_SUITS
        char *suits[] = {"\xe2\x99\xa3", "\xe2\x99\xa6",
                         "\xe2\x99\xa5", "\xe2\x99\xa0"};
    #else
        char *suits[] = {"C", "D", "H", "S"};
    #endif
        printf("%s", suits[c / NUM_VALUES]);
    }
    
    void shuffle_deck(int *deck) {
        for (int i = NUM_CARDS; i > 1; ) {
            int r = rand() % i--;
            int t = deck[i]; deck[i] = deck[r]; deck[r] = t;
        }
    }
    
    void print_deck(int *deck) {
        for (int i = 0; i < NUM_CARDS; i++) {
            print_value(deck[i]);
            print_suit(deck[i]);
            printf("  ");
            if ((i + 1) % NUM_VALUES == 0) printf("\n");
        }
        printf("\n");
    }
    
    int main(void) {
        srand((unsigned)time(NULL));
        int deck[NUM_CARDS];
        for (int i = 0; i < NUM_CARDS; i++) deck[i] = i;
        print_deck(deck);
        shuffle_deck(deck);
        print_deck(deck);
        return 0;
    }

  6. #6
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,111
    TIMTOWTDI, "There is more than one way to do it!"

    @algorism provides an alternative method.

  7. #7
    Registered User
    Join Date
    Mar 2017
    Posts
    13
    Thank you algorism!! I like this approach better, truthfully, I will definitely look at this when I need to incorporate/make my own code, since it's more readable for me. In the end, I figured out the print error, but didn't resolve it entirely, I think I just messed around with the last print line (line 78-79).

    The intended use was for me to share the code I made that aligned with the PowerPoint so that others could benefit from it, so I can't use your code for that, but I can benefit personally. Thank you so much!!

    I don't know how to do a spoiler cut, but I ended up with the following...

    Code:
    #include <stdio.h>#include <stdlib.h>
    #include <time.h>
    
    
    #define SUITS 4
    #define FACES 13
    #define CARDS 52
    
    
    
    
    void shuffle(unsigned int wDeck[][FACES]);
    void deal(unsigned int wDeck[][FACES], const char *wFace[],
              const char *wSuit[]);
    
    
    int main(void)
    {
    
    
        const char *suit[SUITS] =
        { "Hearts", "Diamonds", "Clubs", "Spades" };
    
    
        const char *face[FACES] =
        { "Ace", "Deuce", "Three", "Four", "Five", "Six", "Seven",
            "Eight", "Nine", "Ten", "Jack", "Queen", "King" };
    
    
        unsigned int deck[SUITS][FACES] = { 0 };
    
    
        srand(time(NULL));
    
    
        shuffle(deck);
        deal(deck, face, suit);
    }
    
    
    void shuffle(unsigned int wDeck[][FACES])
    {
        size_t row;
        size_t column;
        size_t card;
    
    
        for (card = 0; card < CARDS; card++)
        {
            do
            {
                row = rand() % SUITS;
                column = rand() % FACES;
            } while (wDeck[row][column] != 0);
        wDeck[row][column] = card;
        }
    
    
    }
    
    
    void deal(unsigned int wDeck[][FACES], const char *wFace[],
              const char *wSuit[])
    {
        size_t card;
        size_t row;
        size_t column;
    
    
        for (card = 0; card < CARDS; card++)
        {
            for (row = 0; row < SUITS; row++)
            {
                for (column = 0; column < FACES; column++)
                {
                    if (wDeck[row][column] == card)
                    {
                        printf("%5s of %-8s%c", wFace[column], wSuit[row],
                            card % 2 == 0 ? '\n' : '\t');
                    }
                }
            }
        }
    }
    It doesn't really print 2 columns of 26 equally, but it's still pretty good, I got tired after debugging it for two hours haha

  8. #8
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    I felt you might have thought the code I posted was too complicated or something and therefore didn't like that approach. But it really is the simplest approach when you get used to it. I threw in the unicode stuff for fun, just in case it works for you (depends on your system).

    To fix your code it seems you just need to say cards % 2 == 1 instead of 0 (or switch the '\n' and '\t').

    If you don't care about the "of"'s lining up you could do this
    Code:
        char str[100];
        sprintf(str, "%s of %s", wFace[column], wSuit[row]);
        printf("%-24s%s", str, card % 2 ? "\n" : "");

  9. #9
    Registered User
    Join Date
    Mar 2017
    Posts
    13
    I tend to do things in a European style, sometimes, so formatting can get kinda tricky, I don't believe I've ever posted my own code, but it's funny that Pearson above all would have so many mistakes in programs that they sell to professors haha

    I tried doing the % 1 and it worked!!! Everything's all aligned + pretty now!
    Do you know (in pseudo) what "integer % 2 == 0" would mean? For future reference, if you get the chance

  10. #10
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    Quote Originally Posted by TahiriS719 View Post
    I tried doing the % 1 and it worked!!! Everything's all aligned + pretty now!
    Do you know (in pseudo) what "integer % 2 == 0" would mean? For future reference, if you get the chance
    You mean % 2 == 1, not % 1 (which is always equal to 0).
    % is the modulus (or remainder) operator which gives the remainder of integer division.
    14 % 4 == 2 since 4 goes into 14 three times with two remainder.
    So integer % 2 yields 0 (no remainder) if integer is even and 1 if it's odd.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Card shuffle game
    By newbie30 in forum C Programming
    Replies: 5
    Last Post: 08-13-2009, 04:19 PM
  2. throw or print error
    By l2u in forum C++ Programming
    Replies: 5
    Last Post: 08-01-2008, 12:26 AM
  3. Card Shuffle Help
    By killmequick in forum C Programming
    Replies: 26
    Last Post: 04-03-2008, 04:00 PM
  4. Sound card error: Driver not found
    By kawk in forum Tech Board
    Replies: 5
    Last Post: 05-30-2007, 12:46 AM
  5. Card shuffle and deal want to put on Stack
    By sugie in forum C++ Programming
    Replies: 4
    Last Post: 12-12-2005, 08:40 PM

Tags for this Thread