Thread: Need help with structs

  1. #1
    Registered User
    Join Date
    Apr 2019
    Posts
    3

    Need help with structs

    I started programming a couple of months ago and thought I should set myself a challenge so I've decided to create a Blackjack game. I've created a struct for the cards but I don't know how to define each card, please help!

    // Written by Maxime Turner
    // File: main.c


    // ************************************************** ************************************************** **


    // Header files


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


    // ************************************************** ************************************************** **


    // Function prototyping


    int getBet();
    void dealCard();


    // ************************************************** ************************************************** **


    // Global variables


    int bank;
    int bet;
    time_t t;


    struct cards // This defines the characteristics of a card
    {
    char suit[5];
    char rank[5];
    };
    struct cards card[52]; // There are 52 cards in a deck (4 suits with 13 ranks each)
    // Beginning of cards with "Clubs" as suit
    strcpy(card[0].suit, 'c');
    card[0].rank = '2';
    card[1].suit = 'c';
    card[1].rank = '3';
    card[2].suit = 'c';
    card[2].rank = '4';
    card[3].suit = 'c';
    card[3].rank = '5';
    card[4].suit = 'c';
    card[4].rank = '6';
    card[5].suit = 'c';
    card[5].rank = '7';
    card[6].suit = 'c';
    card[6].rank = '8';
    card[7].suit = 'c';
    card[7].rank = '9';
    card[8].suit = 'c';
    card[8].rank = "10";
    card[9].suit = 'c';
    card[9].rank = 'J';
    card[10].suit = 'c';
    card[10].rank = 'Q';
    card[11].suit = 'c';
    card[11].rank = 'K';
    card[12].suit = 'c';
    card[12].rank = 'A';
    // Beginning of cards "Diamonds" as suit
    card[13].suit = 'd';
    card[13].rank = '2';
    card[14].suit = 'd';
    card[14].rank = '3';
    card[15].suit = 'd';
    card[15].rank = '4';
    card[16].suit = 'd';
    card[16].rank = '5';
    card[17].suit = 'd';
    card[17].rank = '6';
    card[18].suit = 'd';
    card[18].rank = '7';
    card[19].suit = 'd';
    card[19].rank = '8';
    card[20].suit = 'd';
    card[20].rank = '9';
    card[21].suit = 'd';
    card[21].rank = "10";
    card[22].suit = 'd';
    card[22].rank = 'J';
    card[23].suit = 'd';
    card[23].rank = 'Q';
    card[24].suit = 'd';
    card[24].rank = 'K';
    card[25].suit = 'd';
    card[25].rank = 'A';
    // Beginning of cards "Hearts" as suit
    card[26].suit = 'h';
    card[26].rank = '2';
    card[27].suit = 'h';
    card[27].rank = '3';
    card[28].suit = 'h';
    card[28].rank = '4';
    card[29].suit = 'h';
    card[29].rank = '5';
    card[30].suit = 'h';
    card[30].rank = '6';
    card[31].suit = 'h';
    card[31].rank = '7';
    card[32].suit = 'h';
    card[32].rank = '8';
    card[33].suit = 'h';
    card[33].rank = '9';
    card[34].suit = 'h';
    card[34].rank = "10";
    card[35].suit = 'h';
    card[35].rank = 'J';
    card[36].suit = 'h';
    card[36].rank = 'Q';
    card[37].suit = 'h';
    card[37].rank = 'K';
    card[38].suit = 'h';
    card[38].rank = 'A';
    // Beginning of cards "Spades" as suit
    card[39].suit = 's';
    card[39].rank = '2';
    card[40].suit = 's';
    card[40].rank = '3';
    card[41].suit = 's';
    card[41].rank = '4';
    card[42].suit = 's';
    card[42].rank = '5';
    card[43].suit = 's';
    card[43].rank = '6';
    card[44].suit = 's';
    card[44].rank = '7';
    card[45].suit = 's';
    card[45].rank = '8';
    card[46].suit = 's';
    card[46].rank = '9';
    card[47].suit = 's';
    card[47].rank = "10";
    card[48].suit = 's';
    card[48].rank = 'J';
    card[49].suit = 's';
    card[49].rank = 'Q';
    card[50].suit = 's';
    card[50].rank = 'K';
    card[51].suit = 's';
    card[51].rank = 'A';


    struct playerHand // This creates the player's hand
    {
    char suit[5];
    char rank[5];
    };
    struct playerHand playerCard[5]; // This allows the player to hold up to 5 cards


    struct dealerHand // This creates the dealer's hand
    {
    char suit[5];
    char rank[5];
    };
    struct dealerHand dealerCard[5]; // This allows the dealer to hold up to 5 cards


    // ************************************************** ************************************************** **


    // Main function


    int main()
    {
    bank = 100;


    getBet();


    dealCard();
    printf("Your first card is: %c%c\n", card[i].rank, card[i].suit);


    return 0;
    }


    // ************************************************** ************************************************** **


    // Function to receive the user's bet


    int getBet()
    {
    do // Will keep running until the user enters valid bet
    {
    printf("You have %d$.\n", bank);
    printf("How much do you want to bet? ");
    printf("You must enter a value between 1 and %d.\n", bank);
    printf("Your bet: ");
    scanf(" %d", &bet);


    if (bet >= 1 && bet <= bank)
    {
    return(bet);
    }
    else
    {
    printf("\nYou did not enter a valid bet.\n\n");
    }
    } while ((bet < 1) || (bet > bank));
    }


    // ************************************************** ************************************************** **


    // Function deals a card, ensuring that it is not being duplicated


    void dealCard(struct cards card)
    {
    int i, j;
    int cardDup = 0;


    do // Will keep running until there is no longer a duplicate card
    {
    card[i] = (rand() %52);


    for (j = 0; j < i; j++)
    {
    if (card[i] == card[j])
    {
    cardDup = cardDup + 1;
    }


    } while (cardDup == 1);


    }


    // ************************************************** ************************************************** **
    Last edited by turner_max; 04-26-2019 at 04:18 PM.

  2. #2
    Registered User
    Join Date
    Apr 2019
    Posts
    662
    a couple of tips maybe. an array of structs with each element holding a card or 2 arrays in a single struct 1 for suit and 1 for value

  3. #3
    Registered User
    Join Date
    Apr 2019
    Posts
    57
    I would start with something like this.

    Code:
    #include <stdio.h>
    
    // Numeric representation of suits, 0,1,2,3
    enum { HEARTS, DIAMONDS, SPADES, CLUBS };
    
    // String representation of suits and ranks
    const char *suit_str[] = {
      [HEARTS] = "hearts",
      [DIAMONDS] = "diamonds",
      [SPADES] = "spades",
      [CLUBS] = "clubs"
    };
    
    const char *rank_str[] = {
      "", // Rank 0 is not valid
      "one",
      "two",
      "three",
      "four",
      "five",
      "six",
      "seven",
      "eight",
      "nine",
      "ten",
      "jack",
      "queen",
      "king",
      "ace"
    };
    
    typedef struct {
      int rank;  // Ranks are int 1-14, 14 being ace
      int suit;  // Suit is 0-3, defined in the enum above
    } Card;
    
    Card deck[52];
    
    void init_deck(void) {
      for(int suit = 0, i = 0; suit < 4; suit++)
        for(int rank = 1; rank <= 14; rank++, i++)
          deck[i] = (Card){.rank=rank, .suit=suit};
    }
    
    void shuffle_deck(void) {
      // ...
    }
    
    void print_card(int idx) {
      printf("%s of %s\n", rank_str[deck[idx].rank], suit_str[deck[idx].suit]);
    }
    
    int main(void) {
      init_deck();
      shuffle_deck();
    
      for(int i = 0; i < 52; i++)
        print_card(i);
    }
    The first thing you'll want to do is decide on a way to numerically represent most things. In this case, suits and rank are represented by integers. I also included tables of numeric representation to string representation, which is useful for display later on.

    Next thing, if you find yourself listing out an entire deck of cards, stop and think because there's probably a better way of doing things. Since we have numeric representations of the cards, we can just initialize the deck with a nested for loop that loops over the suits and ranks. All of that gets cleaned up.

    Let's take a look at your structs again.

    Code:
    struct cards // This defines the characteristics of a card
    {
      char suit[5];
      char rank[5];
    };
    struct cards card[52]; // There are 52 cards in a deck (4 suits with 13 ranks each)
    I'm a bit confused here. If you're representing cards as characters, why are the arrays 5 long? Later, you're also conflating character literals and string literals, you should review this. In fact, what you're should be a compiler error.

    Other than that, our representation of the deck is quite similar, we have a card structure that has suit and rank and an array of 52 of them. So you're pretty close to something workable here.

    Code:
    struct playerHand // This creates the player's hand
    {
      char suit[5];
      char rank[5];
    };
    struct playerHand playerCard[5]; // This allows the player to hold up to 5 cards
    
    
    struct dealerHand // This creates the dealer's hand
    {
      char suit[5];
      char rank[5];
    };
    struct dealerHand dealerCard[5]; // This allows the dealer to hold up to 5 cards
    Here's where things start to go off the rails a bit. You already have a representation of a card, you shouldn't need to make any other structs here. Here's how I might approach this.

    Code:
    int playerHand[5];
    int dealerHand[5];
    Why ints? These ints are just indices into the deck. So a player might end up with cards 12,22,-1,-1,-1 after the initial deal, those -1's signify there is no card in that slot.

    When the game is played, the deck array gets shuffled. The program keeps an index of the top card, starting at 0. Cards are "dealt" by copying that index into either playerHand or dealerHand and then incrementing the top card index.

    Once you can represent cards and deal them into hands, all that's left is to make the actual game. Hope this helps.

  4. #4
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,859
    The best place to start is with a "card". Each card has a display ('1', '2', 'J', 'Q', ...) and a value (1 .. 14) - The "value" will help with sorts later on.

    So.. each card should start with something like this...
    Code:
    typedef struct
    {
        char Display;
        int Value;
        
    } Card;
    This allows you to make your "hand" in different ways, such as an array, or linked list...

    You might have have different types of hands, such as TexasHoldem, FiveCardDraw, SevenCardStud, ... - I'd probably implement them as another typedef with an array, as they have different amount of cards.

    You can also have a deck to begin with that can be shuffled - I'd probably implement that as a linked list in another typedef called "Deck"
    Fact - Beethoven wrote his first symphony in C

  5. #5
    Registered User
    Join Date
    Apr 2019
    Posts
    3
    Thanks for your help! I've made some adjustments based on your feedback and the program is no longer showing any build errors! However it's still not working as it should...

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <time.h>
    #include <string.h>
    
    
    // Numeric representation of suits, 0,1,2,3
    enum { HEARTS, DIAMONDS, SPADES, CLUBS };
    
    
    // String representation of suits and ranks
    const char *suit_str[] = {
      [HEARTS] = "hearts",
      [DIAMONDS] = "diamonds",
      [SPADES] = "spades",
      [CLUBS] = "clubs"
    };
    
    
    const char *rank_str[] = {
      "", // Rank 0 is not valid
      "one",
      "two",
      "three",
      "four",
      "five",
      "six",
      "seven",
      "eight",
      "nine",
      "ten",
      "jack",
      "queen",
      "king",
      "ace"
    };
    
    
    typedef struct {
      int rank;  // Ranks are int 1-14, 14 being ace
      int suit;  // Suit is 0-3, defined in the enum above
    } Card;
    
    
    Card deck[52];
    
    
    void init_deck(void) {
      for(int suit = 0, i = 0; suit < 4; suit++)
        for(int rank = 1; rank <= 14; rank++, i++)
          deck[i] = (Card){.rank=rank, .suit=suit};
    }
    
    
    int getBet();
    int dealCard();
    int bank;
    int bet;
    int i, j;
    
    
    int main()
    {
        bank = 100;
        init_deck();
    
    
        getBet();
    
    
        dealCard();
        printf("Your first card is %s of %s\n", rank_str[deck[i].rank], suit_str[deck[i].suit]);
    
    
        return 0;
    }
    
    
    int getBet()
    {
        do // Will keep running until the user enters valid bet
        {
            printf("You have %d$.\n", bank);
            printf("How much do you want to bet? ");
            printf("You must enter a value between 1 and %d.\n", bank);
            printf("Your bet: ");
            scanf(" %d", &bet);
    
    
            if (bet >= 1 && bet <= bank)
            {
                return(bet);
            }
            else
            {
                printf("\nYou did not enter a valid bet.\n\n");
            }
        } while ((bet < 1) || (bet > bank));
    }
    
    
    int dealCard()
    {
        int i, j;
        int cardDup = 0;
    
    
            do
            {
                // Card rank is one of 13 (2-10, J, Q, K, A)
                deck[i].rank = (rand() %13+1);
                // Card suit is one of 4 (club, diamond, heart, spade)
                deck[i].suit = (rand() %4);
    
    
                // Loop that ensures there is no more than 6 copies of the same card in play (since there are 6 decks)
                for (j = 0; j < i; j++)
                {
                    if ((deck[i].rank == deck[j].rank) && (deck[i].suit == deck[j].suit))
                    {
                        cardDup = cardDup + 1;
                    }
                }
            } while (cardDup == 1);
    
    
        return((deck[i].rank) && (deck[i].suit));
    
    
    }

  6. #6
    Registered User
    Join Date
    Apr 2019
    Posts
    662
    is it me being thick or have you not seeded the rand function?? if i run this
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    int main()
    {
        int i, random_number;
    
        //srand((unsigned) time(NULL));
    
        for (i= 0; i<=10; i++)
        {
            random_number = rand() % 10 + 1;
            printf("%d\n", random_number);
        }
        return 0;
    }
    i get the same 10 random numbers in the same order every time i run it. where as if i seed it with srand((unsigned) time(NULL)) i get different order of numbers every time

    hope this helps
    coop

  7. #7
    Registered User
    Join Date
    Apr 2019
    Posts
    3
    That helps a lot! Thanks

  8. #8
    Registered User
    Join Date
    May 2010
    Posts
    4,456
    You should also be getting several warnings (if your compiler is properly configured) that you need to fix.

    Why all those horrible global variables

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 01-08-2013, 07:55 AM
  2. Typedef Structs inside Typdef structs
    By gremory in forum C Programming
    Replies: 21
    Last Post: 12-30-2011, 07:48 PM
  3. [ noob question ] Help with structs within structs
    By Riverfoot in forum C Programming
    Replies: 3
    Last Post: 04-26-2011, 07:24 PM
  4. Passing Structs Into An Array Of Structs.
    By TheTaoOfBill in forum C Programming
    Replies: 3
    Last Post: 10-07-2010, 09:38 AM
  5. passing structs & pointers to structs as arguments
    By Markallen85 in forum C Programming
    Replies: 6
    Last Post: 03-16-2004, 07:14 PM

Tags for this Thread