-
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);
}
// ************************************************** ************************************************** **
-
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
-
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.
-
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"
-
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));
}
-
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
-
-
You should also be getting several warnings (if your compiler is properly configured) that you need to fix.
Why all those horrible global variables