Thread: Display if a specific card is in the hand

  1. #1
    Registered User
    Join Date
    Oct 2018
    Posts
    11

    Question Display if a specific card is in the hand

    I'm supposed to code a program for a Euchre card game. The code was from the book, my teacher wanted us to do the following:



    • Modify card_shuffle_deal.c to only contain cards with face values of 9, 10, Jack, Queen, King, and Ace. The suits will stay the same (Hearts, Diamonds, Clubs, and Spades).




    • Modify card_shuffle_deal.c to deal 5 cards instead of 52 cards. More specifically: after the cards are shuffled, deal 5 cards and print only those 5 onto the screen.




    • We’re going to call those 5 cards “the hand.” Write a function that uses pointers to determine if the hand contains a Jack.


    I already completed the first two objectives, and I think I got the "the hand" part. But the problem I am having with my program is that it does in fact work, however it is giving the wrong output. Instead of saying "A Jack has been found!" it says "A Ace has been found!" and everytime I run it it will say that even if that card is not present.

    The only stuff I added to the code was:
    the_hand(hand, face, suit)
    void the_hand()
    unsigned int hand[5][2]

    And the stuff in the void the_hand() part on the bottom. Anyway here is my code, I tried Googling as much as I could, but really can't find much. I did find some poker games made in C and used some of the code as a reference. What am I doing wrong that I'm not getting the result(s) I'm looking for? Any tips in the right direction would be appreciated.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <string.h>
    #include <stddef.h>
    
    #define SUITS 4
    #define FACES 6
    #define CARDS 24
    #define THEE_HAND 5 
    
    
    // prototypes
    void shuffle(unsigned int wDeck[][FACES]); // shuffling modifies wDeck
    void deal(unsigned int wDeck[][FACES], unsigned int hand[][2], const char *wFace[], const char *wSuit[]);
    void the_hand(unsigned int hand[][2], const char *wFace[], const char *wSuit[]) ;
    //~ void jack(const char *wFace[3], const char *wSuit[]) ;
    
    //~ void jack_ace(unsigned int wHands[][FACES], unsigned int hand[][2],
                //~ const char *wFace[], const char *wSuit[]) ;
    
    int main(void) {
        // initialize deck array
        unsigned int deck[SUITS][FACES] = {0};
        unsigned int hand[5][2];
        srand(time(NULL)); // seed the RNG
        shuffle(deck); // shuffle the deck
    
        // initialize suit array
        const char *suit[SUITS] = {"Hearts", "Diamonds", "Clubs", "Spades"};
    
        // initialize face array
        const char *face[FACES] = {"Ace", "Nine", "Ten","Jack", "Queen", "King"};
    
        deal(deck, hand, face, suit); // deal the deck
        the_hand(hand, face, suit);
        //~ jack_ace(hand, deck, face, suit);
    }
    
    // shuffle cards in deck
    void shuffle(unsigned int wDeck[][FACES]) {
        // for each of the cards, choose slot of deck randomly
        for (size_t card = 20; card <= CARDS; card++) {
            size_t row;
            size_t column;
    
            // choose new random location until unoccupied slot found
            do {
                row = rand() % SUITS;
                column = rand() % FACES;
            } while (wDeck[row][column] != 0);
    
            // place card number in chosen slot of deck
            wDeck[row][column] = card;
        }
    }
    
    // deal cards in deck
    void deal(unsigned int wDeck[][FACES], unsigned int hand[][2], const char *wFace[], const char *wSuit[]) {
        // deal each of the cards
        for (size_t card = 20; card <= CARDS; card++) {
            // loop through rows of wDeck
            for (size_t row = 0; row < SUITS; row++) {
                // loop through columns of wDeck for current row
                for (size_t column = 0; column < FACES; column++) {
                    // if slot contains current card, display card
    
             // end if
                    if (wDeck[row][column] == card) {
                        printf("%5s of %-8s%c", 
                                wFace[column], wSuit[row],
                                card % 2 == 0 ? '\n' : '\t');
    
            } // end if
                } // end column for loop
            } // end row for lop
        } // end card for loop
    } // end deal function
    
    void the_hand(unsigned int hand[][2], const char *wFace[], const char *wSuit[]) {
    
    unsigned int jack[FACES] = {0};
    int hold;
    
        for(size_t k = 5; k <= THEE_HAND; k++){
        for(size_t i = 0; i < FACES; i++){
            hold = (hand[i][1]) %5;
            jack[hold] = jack[hold]+1;
        for(size_t j = 0; j < CARDS; j++){
            if(jack[j] != 0 && jack[j] == 3){
                printf("A %4s has been found!\n", wFace[j]);
                    
                    }        
                }
            }
        }
    }

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    At no point do you ever assign anything to hand[this][that], so why you think when it gets to your the_hand function that you can check the values in it is a mystery.

    Let's look at the logic in your the_hand function nonetheless:

    The outer loop goes from k = 5 to 5, so it is not clear why this loop exists.

    The middle loop goes from i = 0 to 5, and does:
    • Finds the modulus of the value in the hand[i][1] when divided by 5. Given that hand[i][1] doesn't have a meaningful value in here, who knows what this will be, but also note that, assuming you store the rank of the card in this array slot, you will be equating aces and kings, since they both have rank 0 modulo 5 (there are six ranks, so two of them must collide the way you've done it).
    • You increment jack[random value from above].
    • You then run an inner loop for j = 0 to j = 23, which does:
      • First, a redundant check on whether the value of jack[j] is both 3 and nonzero (which, if it is three, we can safely say it is nonzero). Note that this checks for three of the same kind of card, presumably, rather than the existence of any particular card, and also wanders quite far off the edge of the array.
      • It then prints a message based on the face value array.
    • After the conclusion of this inner loop, the middle loop also concludes.


    Notice that the inner loop runs for each iteration of the middle loop, rather than at the end of it, despite your indentation.
    You need to make sure that your hand array has meaningful values (I have no idea what you want the first slot to represent in any event), and then you need to check only one slot (rather than a loop), specifically, the slot where the Jacks are going to be.

  3. #3
    Registered User
    Join Date
    Oct 2018
    Posts
    11
    Quote Originally Posted by tabstop View Post
    At no point do you ever assign anything to hand[this][that], so why you think when it gets to your the_hand function that you can check the values in it is a mystery.

    Let's look at the logic in your the_hand function nonetheless:

    The outer loop goes from k = 5 to 5, so it is not clear why this loop exists.

    The middle loop goes from i = 0 to 5, and does:
    • Finds the modulus of the value in the hand[i][1] when divided by 5. Given that hand[i][1] doesn't have a meaningful value in here, who knows what this will be, but also note that, assuming you store the rank of the card in this array slot, you will be equating aces and kings, since they both have rank 0 modulo 5 (there are six ranks, so two of them must collide the way you've done it).
    • You increment jack[random value from above].
    • You then run an inner loop for j = 0 to j = 23, which does:
      • First, a redundant check on whether the value of jack[j] is both 3 and nonzero (which, if it is three, we can safely say it is nonzero). Note that this checks for three of the same kind of card, presumably, rather than the existence of any particular card, and also wanders quite far off the edge of the array.
      • It then prints a message based on the face value array.

    • After the conclusion of this inner loop, the middle loop also concludes.


    Notice that the inner loop runs for each iteration of the middle loop, rather than at the end of it, despite your indentation.
    You need to make sure that your hand array has meaningful values (I have no idea what you want the first slot to represent in any event), and then you need to check only one slot (rather than a loop), specifically, the slot where the Jacks are going to be.




    For hand[this][that] I saw that poker programs written in C had it so I figured that it could help.

    The outer loop part I meant to put k = 0 not 5, but it still doesn't do anything. I figured I'd treat it though like the card = 0 part in void deal()

    For the middle loop that stuff was related to the 'pairs' section of the poker program I referenced from. should I just get rid of hand[] all-together?

    For jack[j] = 3 I assumed that since I set it as unsigned int jack[FACES] = 0 that if I did jack[j] = 3 it would mean that I'm looking for Jack which is 3.

    Also, I see you brought up the hand thing, what I was thinking with that too was that hand[5][3] meaning the hand having 5 cards and 3 being the face of the cards.

    Also, considering the face that the suits are in the column row I'm going to assume that I should make a for loop only for that, correct?
    I originally had this for void the_hand

    Code:
    void the_hand(unsigned int wDeck[][FACES], const char *wFace[], const char *wSuit[]) {
        // find the jack in the hand
        for (size_t card = 20; card <= CARDS; card++) {
            // loop through rows of wDeck
            for (size_t row = 0; row < SUITS; row++) {
                // loop through columns of wDeck for current row
                for (size_t column = 3; column > 2 && column < 4; column++) {
                    // if finds a Jack in the hand
                    if(wDeck[row][column] != 0 && wDeck[row][column] == card){
                            printf("A %4s of %-4s%c has been found!\n", 
                                    wFace[column], wSuit[row], 
                                    card % 2 == 0 ? '\t' : '\t');
                    }        
                } // end if
            } // end column for loop
        } // end row for lop
    }

    But it would say "A Jack has been found!" twice if there are two Jacks, rather than just say it once.


    But it would say "A Jack has been found!" twice if there are two Jacks, rather than just say it once.
    Last edited by SirZombieton; 11-08-2018 at 08:35 PM.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Suppose you do fix the problem that your deck is actually "empty": if you then shuffle the deck, dealing a hand is simple: just assign the first or last N cards from the deck to get a hand of N cards. You don't need random selection since the deck has been shuffled. If you don't shuffle the deck, then use random selection to deal the hand.

    Now, to shuffle the deck, look up a shuffle algorithm called Knuth shuffle, also known as Fisher-Yates shuffle. What you're doing right now is terribly inefficient for shuffling. You would need to adapt it for a 2D array, but the idea remains the same.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Oct 2018
    Posts
    11
    Quote Originally Posted by laserlight View Post
    Suppose you do fix the problem that your deck is actually "empty": if you then shuffle the deck, dealing a hand is simple: just assign the first or last N cards from the deck to get a hand of N cards. You don't need random selection since the deck has been shuffled. If you don't shuffle the deck, then use random selection to deal the hand.

    Now, to shuffle the deck, look up a shuffle algorithm called Knuth shuffle, also known as Fisher-Yates shuffle. What you're doing right now is terribly inefficient for shuffling. You would need to adapt it for a 2D array, but the idea remains the same.
    What do you mean deck is "empty"? And are you saying if I figure out how to properly shuffle that could help?

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by SirZombieton
    What do you mean deck is "empty"?
    Oh, my mistake: you're not shuffling the deck, you're populating it randomly. Amounts to the same thing though, and it remains the case that this method means that as you reach the last few cards to populate, you're going to run into far more collisions than desirable. Unfortunately, I don't think you can adapt Knuth shuffle for populating the deck randomly; you may actually need to populate the deck in some preset order and then shuffle.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Oct 2018
    Posts
    11
    Gotcha, but I'm confused as to how that would help my issue with only display "A Jack has been found!" once when at least one jack is in the hand

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Looking at your shuffle function again, why do you start card from 20 and end it at CARDS, that is 24? Your instructions tell you to populate with 24 cards, right? The dealing of 5 cards to form a hand comes later.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    Oct 2018
    Posts
    11
    I start cards from 20 because it outputs 5 cards. Unless I should output 24 cards first, then make it to randomly choose 5 of them to put in the hand. Does that sound right?

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I think so. What you're doing is more efficient, but your instructions say "after the cards are shuffled, deal 5 cards". If you were to deal 5 cards immediately, then the shuffling step is redundant.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    Registered User
    Join Date
    Oct 2018
    Posts
    11
    Quote Originally Posted by laserlight View Post
    I think so. What you're doing is more efficient, but your instructions say "after the cards are shuffled, deal 5 cards". If you were to deal 5 cards immediately, then the shuffling step is redundant.


    My teacher finally gave me a hint and will give no more:

    1. You don't need to deal all of the cards in the deck array. You only need to deal the first five cards. Leave all the other values in the deck array as 0.
    2. You don't need to create a new array called the hand. The hand is just a concept I introduced to explain the requirements. It's a lot easier to modify the deck array.


    I kind of think that the way my teacher phrased the goal originally was a little confusing. But that hint sounds like what you were saying.

    What do you mean by "If you were to deal 5 cards immediately, then the shuffling step is redundant"? Do you mean that the cards should be shuffled every time you are dealt a card?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Find Highest Card in Hand and swap with Other Hand
    By Amrita Ramnauth in forum C Programming
    Replies: 1
    Last Post: 04-19-2016, 01:29 PM
  2. Replies: 6
    Last Post: 03-09-2016, 02:37 PM
  3. How to display item at specific tab position
    By yeefc128 in forum C++ Programming
    Replies: 4
    Last Post: 11-27-2013, 09:16 PM
  4. Replies: 5
    Last Post: 08-19-2013, 12:01 AM
  5. how to sort a player's hand in seven card rummy
    By dex0391 in forum C Programming
    Replies: 4
    Last Post: 06-19-2010, 09:40 PM

Tags for this Thread