how to fill, shuffle, deal the card game - c

I some how got it working but I still have a problem with the sorting and making pairs so that I can determine the winner.
Pair them(Pairs are cards with the same value.)e.g Ace of Hearts & Ace of Spades make a pair.
I then count those pairs. hand with highest pairs wins.
This was what I was trying for the pairing but.. am still rellyy stuck with how I start the comparison to make the pairing.
This is the way I expect the results to be for every hand:
Hand 1:
Six of Spades, is Black
Seven of Diamonds, is Red
Eight of Spades, is Black
Ten of Hearts, is Red
Queen of Spades, is Black
Number of pairs: 0
Hand 2:
Three of Spades, is Black
Five of Diamonds, is Red
Five of Clubs, is Black
Nine of Diamonds, is Red
Queen of Diamonds, is Red
Number of pairs: 1
Highest pair is: Five
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct card {
const char *face;
const char *suit;
const char *color;
};
typedef struct card Card;
typedef unsigned char pairs;
void fillDeck( Card * const, const char *[], const char *[] ,const char *[]);
void shuffle( Card * const );
void print( const Card * const );
pairs findpairs(card *hand); /* finds any pairs in a hand */
int main()
{
int hand,cd,winner;
card hands[5][5],handssorted[5][5];
pairs numpairs[5],highest;
Card deck[52];
const char *face[] = { "Ace", "Two", "Three", "Four", "Five","Six", "Seven",
"Eight", "Nine", "Ten","Jack", "Queen", "King"};
const char *suit[] = { "Hearts", "Diamonds", "Clubs", "Spades"};
const char *color[]= {"Black","Red"};
srand( time( NULL ) );
fillDeck( deck, face, suit, color );
print( deck );
printf("\n ---------------------------------------------------------- \n");
shuffle( deck );
print( deck );
for(cd=0;cd<5;cd++)
{
}
for(hand=0;hand<5;hand++)
{
/* sort the hands here */
numpairs[hand]=findpairs(handssorted[hand]);
printf("Hand %i:\n",hand+1);
/* print the hands here */
/* print the number and value of any pairs here */
}
/* determine the winner and print it */
system("pause");
return 0;
}
//----------------------------------------------------------------------------- void fillDeck( Card * const wDeck, const char * wFace[], const char * wSuit[],
const char * wColor[])
{
int i;
for ( i = 0; i <= 51; i++ ) {
wDeck[i].face = wFace[ i % 13 ];
wDeck[i].suit = wSuit[ i / 13 ];
wDeck[i].color = wColor[i%2];
// if ()
// wDeck[i].suit = wSuit[ i / 13 ];
}
}
//------------------------------------------------------------------
void shuffle( Card * const wDeck )
{
int i, j;
Card temp;
for ( i = 0; i <= 51; i++ ) {
j = rand() % 52;
temp = wDeck[ i ];
wDeck[ i ] = wDeck[ j ];
wDeck[ j ] = temp;
}
}
//---------------------------------
void print( const Card * const wDeck )
{
int i;
for ( i = 0; i <= 51; i++ ){
printf( "\t%s\t of \t%-8s is \t%s \n \t", wDeck[i].face,
wDeck[i].suit,wDeck[i].color,
( i + 1 ) % 2 ? '\t' : '\n' );}
}
//--------------------------------------------------------------------------
pairs findpairs(card *hand)
{
pairs numpairs=0;
for ( int i = 0; i <= 5; i++ ){
if (hand[i].face == )
}
return numpairs;
}

You have a call to print(deck) in there immediately after srand() which uses the uninitialised deck array.
numpairs, findpairs, and handssorted are undefined
you are printing the entire deck for each hand. Is that really what you intend?
onst is not valid (presumably you meant const)
fillDeck() is not filling in the .color member of each Card
your shuffle algorithm is suspect. See Fisher-Yates shuffle
in print(), you are using the %c format specifier with a const char * type

This isn't an answer to your question (I'm not actually sure what you're asking), but I will point out that your shuffling algorithm is not random.
First, using % to limit rand to a range of values is usually a bad idea. (See Q13.16 from the comp.lang.c FAQ.)
Second, it looks like you might be trying to implement the Fisher-Yates shuffling algorithm, but your implementation is wrong. It's easy to see that your approach of swapping with previously-swapped elements is problematic; consider shuffling a deck of three elements { 0, 1, 2 }:
First iteration Second iteration
------------------------------------
{ 0, 1, 2 } { 1, 0, 2 }
{ 0, 1, 2 }
{ 0, 2, 1 }
------------------------------------
{ 1, 0, 2 } { 0, 1, 2 }
{ 1, 0, 2 }
{ 1, 2, 0 }
------------------------------------
{ 2, 1, 0 } { 1, 2, 0 }
{ 2, 1, 0 }
{ 2, 0, 1 }
The first column represents the possible states of the deck after the first iteration (where you swap deck[0] with deck[rand() % 3]).
The second column represents the possible states of the deck after the second iteration (where you swap deck[1] with deck[rand() % 3]).
There are 9 equally probable states---but this is obviously wrong since there should be only 3! = 6 permutations. And indeed, several states are duplicated, which means that they have a higher probability of occurring. (Note that even if I had proceeded to the third iteration, you'd end up with 27 states for only 6 permutations, and since 27 is not divisible by 6, you'd clearly end up with some states occurring more than others.)

This is the way I expect the results to be for every hand
Then assign statically to the hands the desired cards. In your model every card has already unique number from 0 to 51. If deck and hand are both set of numbers then the operation is as simple as removing number from one set and adding it to another.
You might want to implement functions to work with such int sets, representing deck, hands, etc.
j = rand() % 52;
If you are serious into making a game, you might want to check how to generate random numbers from a range too.

Related

Arrange one array and other array do the same

sorry if English no good, but I have questions please:
I have this array[quantity] that I will sort:
int main() {
int numberOfFruits[] = {3, 5, 2, 4, 1};
//I do sorting algorithm
}
but I also want other array do same thing and match.
char fruits[] = {"apple", "orange", "bannana", "peach", "watermelon"};
So after algrithm it will be:
int numberOfFruits[] = {1, 2, 3, 4, 5};
char fruits[] = {"watermelon", "banana", "apple", "peach", "orange"};
How I do this? Thank you.
First, a variable of type char is not able to hold a string (unless it holds the value 0, then it is an empty string). A string is a sequence of char, where the last char has the value 0. Typically a string is stored in an array, or you use a pointer char * to point to a string that is stored somewhere else. In your case, the name of the fruits are stored in a string literal, so you can use a char * to that. An since you want an array of strings, you should declare an array of char *:
char *fruits[] = {.....};
Now to your actual question:
When you have multiple things that belongs together, you can aggregate them together by declaring a struct:
struct fruit
{
int number;
char *name;
};
And you can define an array of struct fruit like this:
struct fruit fruits[] =
{
{1, "watermelon"},
{2, "banana"},
{3, "apple"},
{4, "peach"},
{5, "orange"}
}
When you now swap two element of fruits, you swap both number and name together:
/* Swap the i-th and j-th element in fruits */
struct fruit tmp = fruits[i];
fruits[i] = fruits[j];
fruits[j] = tmp;
I upvoted HAL9000’s answer because it suggests a better data structure than parallel arrays, but it doesn’t actually answer the title question: How do I sort parallel arrays?
Parallel Arrays
OP has presented an example of parallel arrays. I will add my favorite fruits to his:
int fruit_IDs [] = { 3, 5, 2, 4, 1 10, -7 };
char * fruit_names[] = { "apple", "orange", "banana", "peach", "watermellon", "grapefruit", "strawberry" };
Notice how the ID has no relation to any ordering or indexing of the list. It is just another piece of information. Here is another parallel array structure:
char * first_names[] = { "Harry", "Ron", "Hermione", "Severus" };
char * last_names [] = { "Potter", "Weasley", "Granger", "Snape" };
int year_born [] = { 1980, 1980, 1979, 1960 };
So, how do we sort them without breaking their index association?
Index Array
The simplest would be to use an additional array which is simply used as indices into the parallel arrays. Sticking with the fruits:
int fruit_indexes[NUM_FRUITS] = { 0, 1, 2, 3, 4, 5, 6 };
Now we have a layer of indirection into our parallel arrays. To print the arrays, we might write:
for (int n = 0; n < NUM_FRUITS; n++)
printf( "%d %s\n", fruit_IDs[fruit_indexes[n]], fruit_names[fruit_indexes[n]] );
As you can imagine, if we reorder the elements of the index array, we also reorder how we view the parallel arrays. For example, to see the fruits in reverse order:
int fruit_indexes[NUM_FRUITS] = { 6, 5, 4, 3, 2, 1, 0 };
You should notice right away that this additional array has consequences:
On the plus side, we no longer have to move stuff around in the parallel arrays to reorder them.
On the minus side, we have an additional array to deal with.
Let’s qsort() with the index array!
First, we need a comparitor for the fruit IDs, accessed via indirection through the index array:
int compare_indexed_fruits_by_ID( const void * a, const void * b )
{
// A and b are pointers to elements of the fruit_indices[] array
int ai = *(const int *)a;
int bi = *(const int *)b;
// We use those indices to compare fruit IDs
if (fruit_IDs[ai] < fruit_IDs[bi]) return -1;
if (fruit_IDs[ai] > fruit_IDs[bi]) return 1;
return 0;
}
Comparing by fruit name works the same way, except now we compare names instead of IDs:
int compare_indexed_fruits_by_name( const void * a, const void * b )
{
// A and b are pointers to elements of the fruit_indices[] array
int ai = *(const int *)a;
int bi = *(const int *)b;
// Use those indices to compare fruit names
return strcmp( fruit_names[ai], fruit_names[bi] );
}
The call to QSort is thereafter very simple — pass the correct comparison function and sort the index array:
qsort( fruit_indexes, NUM_FRUITS, sizeof(*fruit_indexes), &compare_indexed_fruits_by_ID );
Printing our fruits will give you:
-7 strawberry
1 watermellon
2 banana
3 apple
4 peach
5 orange
10 grapefruit
We can sort by name just as easily:
qsort( fruit_indexes, NUM_FRUITS, sizeof(*fruit_indexes), &compare_indexed_fruits_by_name );
Producing:
3 apple
2 banana
10 grapefruit
5 orange
4 peach
-7 strawberry
1 watermellon
Dynamic data, static arrays
One of the nice things about the index array is that you can still use it when adding and removing data from other arrays. Remember, to set up static arrays you need a data structure something like this:
#define MAX_NUM_PEOPLE 1000
char * first_names[MAX_NUM_PEOPLE];
char * last_names [MAX_NUM_PEOPLE];
int indices [MAX_NUM_PEOPLE];
int num_people = 0;
To add new data, just push it onto the back of your existing arrays as usual, checking of course that you have room:
if (num_people < MAX_NUM_PEOPLE)
{
first_names[num_people] = new first name;
last_names [num_people] = new last name;
indices [num_people] = num_people;
num_people += 1;
The new element will naturally be out of order, so you will have to sort the index array again.
qsort( indices, ... );
}
To delete an element you need only swap it off the end before sorting the index array again. Don’t forget to check your array bounds!
if (index_to_delete > 0 && index_to_delete < num_people)
{
first_names[indices[index_to_delete]] = first_names[num_people-1];
last_names [indices[index_to_delete]] = last_names [num_people-1];
indices[index_to_delete] = indices[num_people-1];
num_people -= 1;
qsort( indices, ... );
}
Dynamic data, dynamic arrays
This works very much like the static array version, only your arrays are dynamically-allocated.
char ** first_names = NULL;
char ** last_names = NULL;
int * indices = NULL;
int num_people = 0;
...
first_names = malloc( new_num_people * sizeof(*first_names) );
last_names = malloc( new_num_people * sizeof(*last_names) );
indices = malloc( num_num_people * sizeof(*indices) );
if (!first_names || !last_names || !indices)
{
free( indices );
free( last_names );
free( first_names );
fooey();
}
num_people = new_num_people;
Using realloc() to increase the size of your arrays works as usual as well, with the added complexity that you must check that every array was reallocated successfully.
Eliminating the index array
That index array can be kind of obnoxious. It would be nice to get rid of it after sorting. And, of course, you can!
Create it dynamically before sorting, initializing it to 0, 1, 2, ... as always, sort using the array intermediary, and then take the time to rearrange the other arrays with the new order.
void sort_fruits_by( void (*comparitor)(const void *, const void *) )
{
int indices[num_fruits];
for (int n = 0; n < num_fruits; n += 1)
indices[n] = n;
qsort( indices, num_fruits, sizeof(*indices), comparitor );
reorder_people_by_index( indices );
}
This rearrange bit is what takes some time and space:
void reorder_people_by_index( int * indices )
{
char * temp_names[num_people];
memcpy( temp_names, first_names, num_people*sizeof(char*) );
for (int n = 0; n < num_people; n += 1)
first_names[indices[n]] = temp_names[n];
memcpy( temp_names, last_names, num_people*sizeof(char*) );
for (int n = 0; n < num_people; n += 1)
last_names[indices[n]] = temp_names[n];
}
For the people we could reuse the char * temporary, but for fruits we would need both an int temporary and a char * — one for each type of parallel array.
Now the parallel arrays themselves are sorted differently. But you lose the sorting-an-array-of-integers-only advantage.
Conclusions
You can see that it really isn’t too difficult to maintain parallel arrays. The grief is in the details — you are maintaining multiple arrays!
This is why having a single array of structured data is ever so much more convenient.
But, if you have to do it with parallel arrays, it can be done.

Not sure why I'm getting a segmentation fault when shuffling cards in C

I know it has to do with my pointer variable, my goal is to implement the color of the suit to the preexisting code I was given. So I created a char pointer under the deck structure. It will print out everything correctly until I get to shuffle, in which case I get a segmentation fault.
#include <stdio.h>
#include <time.h> //time function
#include <stdlib.h> //random number generator functions
#include <string.h> //need for Linux
#define MAX 9
#define MAX_CARDS 52
#define MAX_RANKS 13
#define MAX_SUITS 4
#define COLS 2 //number of columns to display in output
//structure definition
struct card{
char *rank;
char suit[MAX];
char *color;
};
typedef struct card Card;
//array of pointers to strings for ranks
char *ranks[MAX_RANKS] = {"Ace", "Two", "Three", "Four", "Five", "Six", "Seven",
"Eight", "Nine", "Ten", "Jack", "Queen", "King"};
char *color[2] = {"(black)", "(red)"};
//two-dimensional array of strings for suits
char suits[MAX_SUITS][MAX] = {"Clubs", "Diamonds", "Hearts", "Spades"};
//[0][1] [0][2][0][3]
void initialize(Card []);
void shuffle(Card []);
void display(const Card[]);
int main(){
char newline = '\n'; //to repeat while loop
//declare an array of 52 cards
Card deck[MAX_CARDS] = {"","",""};
initialize(deck);
deck[0].color = "(black)" ;
deck[1].color = "(red)";
printf("Display an ordered deck of cards:\n");
display(deck);
while('\n' == newline){
printf("\nshuffling deck ... \n\n");
shuffle(deck);
display(deck);
printf("\n\nWould you like to shuffle again?\nIf so, press \"Enter\" key. If not, enter any other char. ");
newline = getchar();
}
return 0;
}
/*
initialize the deck of cards to string values
deck: an array of structure cards
*/
void initialize(Card deck[]){
int i = 0;
for(i=0;i<MAX_CARDS;i++){
deck[i].rank = ranks[i%MAX_RANKS];
strncpy(deck[i].suit, suits[i/MAX_RANKS], MAX);
}
}
/*
use the pseudo-random number generator to shuffle the cards
deck: an array of structure cards
*/
void shuffle(Card deck[]){
int swapper = 0; //index of card to be swapped
int i = 0; //counter
Card temp = {"", ""}; //temp holding place for swap
srand(time(NULL)); //seed the random numbers with current time
for(i=0;i<MAX_CARDS;i++){
//generate a pseudo-random number from 0 to 51
swapper = rand() % MAX_CARDS;
//swap current card with da swapper
temp = deck[i];
deck[i] = deck[swapper];
deck[swapper] = temp;
}
}
/*
display the deck of cards
deck: an array of structure cards
*/
void display(const Card deck[]){
int i = 0;
for(i=0;i<MAX_CARDS;i++)
{
printf("%5s of %-10s", deck[i].rank, deck[i].suit);//%5s makes "of" line up -10 makes cols.
if (strcmp(deck[i].suit, "Clubs") == 0 || strcmp(deck[i].suit, "Spades") == 0)
{
printf(" %5s", deck[0].color);
}
else
{
printf(" %5s", deck[1].color);
}
//put in a newline every %x loops
if((COLS-1) == (i%COLS)){
printf("\n");
}
}
}
This is because your cards have the color which you actually don't use, except here:
deck[0].color = "(black)" ;
deck[1].color = "(red)";
Now, when you shuffle the deck the chances are that you'd get another card there, whose .color is still NULL and your code crashes in printf("...%s...", deck[0].color);
The solution of course is to a) remove the color member altogether, b) then modify the printing code to
if (strcmp(deck[i].suit, "Clubs") == 0 || strcmp(deck[i].suit, "Spades") == 0) {
printf(" (black)");
}
else {
printf(" (red) ");
}
However, I'd personally use enums to represent the ranks and suits, for example
enum Suit {
HEARTS = 0,
SPADES,
DIAMONDS,
CLUBS
};
struct Card {
enum Suit suit;
...
};
and for printing
char *suit_to_string[4] = {"Hearts", "Spades", "Diamonds", "Clubs"};
...
printf("%s", suit_to_string[deck[i].suit]);

Cant get my program to work properly, same numbers when dealing cards

So I'm getting pretty far in my program thanks to the help I've gotten from here.
When I'm calling my function to print out random cards, but I get the same card every time.
So to sum it up, player 1 gets 5 of clubs, the next card is still 5 of clubs.. The dealer gets 5 of clubs too...
I used this in a loop to deal out 2 cards, but I still got 5 of clubs and 5 of clubs, so it's always the same cards (not just 5 of clubs, 9 of hearts etc).
Its the last bit of code in the function int player1()
Here's how my code looks:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define DIAMONDS 0
#define CLUBS 1
#define HEARTS 2
#define SPADES 3
#define COLOR_SIZE 13
#define NR_OF_SUITS 4
#define DECK_SIZE 52
#define JACK 11
#define QUEEN 12
#define KING 13
#define ACE 1
struct Card
{
int suit;
int value;
int *sum;
};
int player2(struct Card* deck);
int player1(struct Card* deck);
int printCards(struct Card *cardDeck);
void swapCards(struct Card *cardA, struct Card *cardB);
void shuffleCards(struct Card *cardDeck);
//==========================================================================
int main()
{
srand((unsigned)time(NULL));
//struct Card deck[DECK_SIZE]; //Statiskt allokerad array
struct Card * deck; //Dynamiskt allokerad array
int index;
int suit_index;
deck = (struct Card *)malloc(sizeof(struct Card) * DECK_SIZE);
for (suit_index = 0; suit_index < NR_OF_SUITS; suit_index++) /* Initiera kortleken */
for (index = 0; index < COLOR_SIZE; index++)
{
deck[suit_index*COLOR_SIZE + index].suit = suit_index;
deck[suit_index*COLOR_SIZE + index].value = index;
}
shuffleCards(deck);
player1(deck);
system("pause");
return 0;
}
//==========================================================================
int printCards(struct Card *cardDeck)
{
int sum = 0;
for (int i = 0; i < 1; i++)
{
switch (cardDeck[i].value + 1)
{
case ACE: printf("Ace ");
cardDeck[i].value = 11;
break;
case JACK: printf("Jack ");
cardDeck[i].value = 10;
break;
case QUEEN: printf("Queen");
cardDeck[i].value = 10;
break;
case KING: printf("King ");
cardDeck[i].value = 10;
break;
default: printf("%d ", cardDeck[i].value);
break;
}
printf("of ");
switch (cardDeck[i].suit)
{
case DIAMONDS: printf("Diamonds ");
break;
case HEARTS: printf("Hearts ");
break;
case CLUBS: printf("Clubs ");
break;
case SPADES: printf("Spades ");
break;
default: printf("Something went wrong!! ");
break;
}
printf("\n");
sum += cardDeck[i].value;
}
return sum;
}
//----------------------------------------------------------------------
void swapCards(struct Card * cardA, struct Card *cardB)
{
struct Card temp;
temp = *cardA;
*cardA = *cardB;
*cardB = temp;
}
//----------------------------------------------------------------------
void shuffleCards(struct Card *cardDeck)
{
for (int i = 0; i < DECK_SIZE; i++)
swapCards(&cardDeck[i], &cardDeck[rand() % 52]);
}
//----------------------------------------------------------------------
int player1(struct Card* deck) {
int i;
int val = 0;
int val2 = 0;
int sum1, sum2, sum3, first;
char name[20], name2[20];
//Player 1, gets 2 cards
gets(name);
printf("Welcome %s\n", name);
for (i = 0; i < 2; i++) {
sum1 = printCards(deck);
val += sum1;
}
printf("%s, your hand is %d\n\n",name, val);
//Player2, only 1 card so far
gets(name2);
printf("Welcome %s\n", name2);
sum2 = printCards(deck);
printf("%s, your hand has a total of %d\n\n", name2, sum2);
//Dealers turn, looping til value is greater or equal to 17
printf("Dealers turn\nDealers cards are:\n");
sum3 = printCards(deck);
val2 += sum3;
printf("%d Dealer has a total of \n", val2);
while (val2 < 17) {
printf("Dealer gets a new card\n");
sum3 = printCards(deck);
val2 += sum3;
printf("Dealers card is %d, dealers value is now %d\n", sum3, val2);
}
printf("Dealer has a total of %d\n", val2);
}
Question:
How do I get different cards every time I call my function?
Note:
I've tried using different variables, loops and such but it still wont work.
I really need a solution here, because I've tried like everything and I think this is the last problem I have.
I know my code isn't the prettiest, but I'll fix that later.
Few general remarks,
"I know my code isn't the prettiest, but I'll fix that later."
is part of your problem, your code is growing and you need to start considering separating it into different files, here is an excellent explanation on the topic of file organization.
Additionally, add some comments describing the different, not so obvious and easy to understand, parts of your code like loops, functions, etc. That will help you and any other reader understand the functionality of your code. for example if a function is doing to many things, should you consider breaking it into smaller functions, each making a single task and is this going to make your job easier in terms of finding an error.
Read more about classes and understand whether is a good idea to integrate all of the functions that act on struct Card into one single class.
P.S. Be patient do not expect to solve a problem for a half an hour, read and research more before asking a question, especially when the question is not technical.
Actually after i looked very carefully through the code, i could not find any place in which dealer, player1 and player2 get their own cards from the deck.
All you do in int player1(struct Card* deck) is continiosly use int printCards(struct Card *cardDeck), which ALWAYS prints a single card from the deck. Actually it always prints cardDeck[0], which by that time will never change. a big BUT is that printing cardDeck is not actually assigning cards to different players, it's just that - printing. Maybe you actually should create some struct, which will hold data about a player. Something like
struct Player
{
char* name; // name of player
struct listOfcards* list; // a pointer to a list of cards the player has
}
Where listOfcards is something like this
struct listOfcards
{
struct card* currCard // pointer to a current card
struct card* nextCard; // pointer to next card in list(NULL if no next card)
}
Be carefull though, this exaple is very simple, you will have to iterate listOfcards manualy to get all cards for current player. However, this very basic example allows you to add a card to the list at any time in your programm, and delete a card from the list at any time in the programm.
The commenters have already pointed out your mistake: You shuffle your deck, but you always look at the same card without discarding it from the deck. The deck gets smaller when you draw cards, so you need a means to keep track of how many cards are still in the deck or how many cards have already been drawn.
Your code has some design "smells". For example, you keep a pointer to the sum with the card struct, but a sum should be kept for each player, not for a card. A card has a score, of course, but that can be determined in a separate function.
It is good that you organise your code in various functions, but sometimes you make your functions do too much. printCards, for example, not only prints a card, it also draws a card from the deck and keeps a tally of the current score. Drawing a card from the deck, printing a card and calculating the score should be three separate functions. Eventually, you'll want to print cards without drawing them from the deck or get the score without printing it.
I recommend to use a deck structure tat hold up to 52 cards and from which cards can be drawn. Here's an example program that deals only with the card dealing, not with the game of Black Jack. (That's probably the fun part and left to you.)
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
enum {DIAMONDS, CLUBS, HEARTS, SPADES, MAX_SUIT};
enum {ACE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE,
TEN, JACK, QUEEN, KING, MAX_RANK};
#define MAX_CARD (MAX_RANK * MAX_SUIT)
struct Card {
int suit;
int rank;
};
struct Deck {
struct Card card[MAX_CARD];
size_t ncard;
};
/*
* Initialise deck
*/
void deck_init(struct Deck *deck)
{
int suit, rank, k = 0;
for (suit = 0; suit < MAX_SUIT; suit++) {
for (rank = 0; rank < MAX_RANK; rank++) {
deck->card[k].suit = suit;
deck->card[k].rank = rank;
k++;
}
}
deck->ncard = k;
}
/*
* Get a random card from the deck. It is illegal to call this
* when the deck has been exhausted.
*/
struct Card deck_deal(struct Deck *deck)
{
if (deck->ncard <= 0) {
fprintf(stderr, "Deck underflow\n");
exit(1);
}
int pick = deck->ncard * (rand() / (1.0 + RAND_MAX));
struct Card deal = deck->card[pick];
deck->card[pick] = deck->card[--deck->ncard];
return deal;
}
/*
* Print a card's name to the char buffer str of size len.
* Return the buffer, so it can be used in, e.g., printf.
*/
char *card_str(char *str, size_t len, struct Card c)
{
static const char *sname[] = {
"Diamonds", "Clubs", "Hearts", "Spades"
};
static const char *rname[] = {
"Ace", "Two", "Three", "Four", "Five", "Six", "Seven",
"Eight", "Nine", "Ten", "Jack", "Queen", "King"
};
snprintf(str, len, "%s of %s", rname[c.rank], sname[c.suit]);
return str;
}
/*
* Determine the card's score.
*/
int card_score(struct Card c)
{
if (c.rank == ACE) return 11;
if (c.rank > TEN) return 10;
return c.rank + 1;
}
/*
* Simple example code
*/
int main()
{
struct Deck deck;
int score = 0;
int ncard = 0;
srand(time(NULL));
deck_init(&deck);
while (deck.ncard && score < 17) {
struct Card c = deck_deal(&deck);
char buf[32];
puts(card_str(buf, sizeof(buf), c));
score += card_score(c);
ncard++;
}
printf("%d cards drawn with a score of %d.\n", ncard, score);
return 0;
}
Things to note:
The deck struct keeps the current number of cards still in the deck alongside the cards proper. When it is initialised, the deck is put into "factory order". Only when picking a card, a random decision is made. (You could as well shuffle the deck on initialisation and pick the topmost card if you wanted to, of course.)
Printing, drawing and evaluating a card are three separate functions. Drawing a card is an action on the deck that yields a card. Printing and evaluating operate on a single card.
Printing is achieved by printing to a char buffer here. This is somewhat ugly, but C's way to create strings. It has the advantage that you can use the function in a printf directly, but you must provide a char buffer.
When you have many constants with consecutive values, you can use an enum, which enumerates these constants for you. Enumerated values start at 0, so that you can put an extra value, such as MAX_SUIT and MAX_RANK here, at the end to give you the number of enumerated items.
The code for picking a card, printing it and evaluating it is a bit longer than yours, because these things have been separated. You can always write a function do do these three things, if you like, without sacrificing the nice modularity. (I suggest that you create a player struct for the player and the dealer, so that the pick-and-evaluate function can easily keep track of the scores.)
int printCards(struct Card *cardDeck)
{
int sum = 0;
static int i = 0;
if(i < DECK_SIZE)
{
switch (cardDeck[i].value + 1)
{...}
printf("of ");
switch (cardDeck[i].suit)
{...}
sum += cardDeck[i].value;
i++;
return sum;
}else
printf("There are no cards left");
return 0;
}
}
use a static variable i: static int i=0; and after you go through the function i++;
and if you reach i = 51 you can return that there are no cards left any more!
I hope i could help you with that! best luck with your project :)

Poker Program in c Programming

I've put together a program that deals out a hand poker perfectly. Now I want the program to realize when the hand that is dealt is straight, flush, pair, 3 of a kind, and 4 of kind. The program runs but never prints the right condition when needed to, I believe I have some placement or logic error that I can't find. Here's what I have so far.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SUITS 4
#define FACES 13
#define CARDS 52
#define HAND 5//draw only 5
#define TRUE 1//positive print condition
#define FALSE 0//negative print condition
//prototypes
shuffle( unsigned int wDeck[][FACES]);//shuffling modifies wDeck
deal(unsigned int wDeck[][FACES], const char *wFace[],
const char *wSuit[] );//dealing doesn't modify the arrays
//true/false conditions
typedef int bool;
bool straight, flush, four, three;
int pairs; //0,1, or 2
int main()
{
//initialize suit array
const char *suit[ SUITS ] =
{
"Hearts", "Diamonds", "Clubs", "Spades"
};
//initialize face array
const char *face[ FACES ] =
{
"Ace", "Deuce", "Three", "Four",
"Five", "Six", "Seven", "Eight",
"Nine", "Ten", "Jack", "Queen", "King"
};
int suitInHand[SUITS], facesInHand[FACES];
analyzeHand(suitInHand, facesInHand);
//initialize deck array
unsigned int deck[SUITS][FACES] = { 0 };
srand( time( NULL ) );//seed random-number generator
shuffle( deck );//shuffle the deck
deal( deck, face, suit );//deal the deck
}//end main
//shuffle cards in deck
shuffle( unsigned int wDeck[][FACES])
{
size_t row;//row number
size_t column;//column number
size_t card;//counter
//for each of the cards, choose slot of deck randomly
for( card = 1; card <= CARDS; ++card) {
//choose new random location until unoccupied slot found
do {
row = rand() % SUITS;
column = rand() % FACES;
}
while( wDeck[ row ][ column ] !=0);
//end do-while
//pace card number in chosen slot of deck
wDeck[ row ][ column ] = card;
}//end for
}//end function shuffle
//deal cards in deck
deal(unsigned int wDeck[][FACES], const char *wFace[],
const char *wSuit[] )
{
size_t card;//card counter
size_t row;//row counter
size_t column;//column counter
//deal each of the cards
for( card = 1; card <= HAND; ++card) {
//loop through rows of wDeck
for( row = 0; row < SUITS; ++row) {
//loop through column of wDeck for current row
for( column = 0; column < FACES; ++column) {
//if slot contains current card, display card
if( wDeck[ row ][ column ] == card ) {
printf("%5s of %-8s%c", wFace[ column ], wSuit[ row ],
card % 2 == 0 ? '\n' : '\t' );//2 column format
}//end if
}//end for
}//end for
}//end for
}//end function deal
analyzeHand(int suitsInHand[], int facesInHand[])
{
int num_consec = 0;
int rank, suit;
straight = FALSE;
flush = FALSE;
four = FALSE;
three = FALSE;
pairs = 0;
for (suit = 0; suit < SUITS; suit++)
if ( suitsInHand[suit] == 5)
flush = TRUE;
rank = 0;
while ( facesInHand[rank] == 0)
rank++;
for (; rank < FACES && facesInHand[rank]; rank++)
num_consec++;
if(num_consec == 5){
straight = TRUE;
return;
}
for(rank = 0; rank < FACES; rank++) {
if(facesInHand[rank] == 4)
four = TRUE;
if(facesInHand[rank] == 3)
three = TRUE;
if(facesInHand[rank] == 2)
pairs++;
}
if(four)
printf("Four of a kind\n");
else if(straight)
printf("Straight\n");
else if(pairs == 2)
printf("Two Pairs\n");
else if(pairs == 1)
printf("Pair\n");
else
printf("Better Luck Next Time\n");
}
There seems to be a problem with the logic in your main() function :
int suitInHand[SUITS], facesInHand[FACES];
analyzeHand(suitInHand, facesInHand);
You are declaring two arrays of ints without initializing them, and them you use them in your analyzeHand() function while they are empty.
You must populate those 2 arrays first if you want to get any kind of valid result.
EDIT : Depending on what kind of infos will be stored in those 2 arrays, their may be some problems with the logic of your analyzeHand() function.

Creating an array to hold a poker hand in C?

I have an assignment due in my computer science class (I posted this question a couple weeks ago but the way it was explained doesn't fit the program I'm supposed to do). I already have a program that shuffles and deals a deck right here.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void shuffle( int [][ 13 ] );
void deal ( const int[][ 13 ], const char *[], const char *[] );
int main()
{
const char *suit[4] ={"Hearts","Diamonds","Clubs","Spades"};
const char *face[13] ={"Ace", "Duece", "Three", "Four", "Five", "Six",
"Seven", "Eight","Nine", "Ten", "Jack", "Queen", "King"};
int deck[4][13] = {0};
int row, column, card = 1;
for( row = 0; row <= 3; row++ )
{
for(column = 0; column <= 12; column++)
{
deck[row][column] = card;
card++;
}
}
srand(time(0));
shuffle(deck);
deal(deck, face, suit);
return 0;
}
void shuffle( int wDeck[][13] )
{
int row, column, randomColumn, randomRow, card = 1, counter1, counter2, hold;
for( counter1 = 0; counter1 <= 3; counter1++)
{
for(counter2 = 0; counter2 <= 12; counter2++)
{
randomColumn = rand() % 13;
randomRow = rand() % 4;
hold = wDeck[counter1][counter2];
wDeck[counter1][counter2] = wDeck[randomRow][randomColumn];
wDeck[randomRow][randomColumn] = hold;
}
}
}
void deal( const int wDeck[][13], const char *wFace[], const char *wSuit[] )
{
int card, row, column;
for ( card = 1; card <= 52; card++ )
for (row = 0; row <= 3; row++ )
for ( column = 0; column <= 12; column++ )
if( wDeck[row][column] == card )
{
printf("%5s of %-8s%c",wFace[ column ], wSuit[row], card % 2 == 0 ? '\n' : '\t');
break;
}
}
I'm supposed to modify the deal function to deal a 5 card poker hand, and then later check to see what "rank" poker hand they have(two of a kind, flush). My teacher mentioned creating a separate double scripted array to do this but I could do it a different way. The problem is, I have to use the current deck/shuffle setup to do it. Could anyone explain how to do this? It's okay if it's inefficient, as long as it works.
With the existing deal prototype, there is no way to return information from it - it has no return value and all the arguments are const. Since the deck has already been shuffled (by shuffle()), I assume the idea is for the deal function to look at the first five cards in the deck array, and find the rank of them. That can either be done entirely within the deal function, or (better), by calling a int rank(int hand[5]) function from within the deal function.

Resources