Poker Program in c Programming - c

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.

Related

how to see if there are 1 or 2 poker pairs in a hand in C

I am trying to develop a C program that checks if there are 1 or 2 pairs in a 5 card poker hand.
I am using a 5x3 array where every line is a card (the 3rd column being for the \0 character). Every time I execute the code it always shows the "two pairs" print.
I want to make sure that each letter (i, j, a, b) representing each line is different. Any help?
P.S.: This is for a university/college project, I have only started programming a few months ago from absolute scratch, so any detailed explanations on my mistakes would be very much appreciated :)
#include <stdio.h>
#include <stdlib.h>
char (cards[5][3])=
{
"5S", "6D", "4H", "KD", "5C"
};
int main ()
{
pair (cards[5][3]);
return 0;
}
void pair (char (arg[n][0]))
{
int i,j,a,b;
if (i!=j!=a!=b)
{
if ((arg[i][0]==arg[a][0])&&(arg[b][0]!=arg[j][0]))
{
printf("2 -> pair");
}
if ((arg[i][0]==arg[a][0])&&(arg[b][0]==arg[j][0]));
{
printf("3 -> two pairs");
}
if ((arg[i][0]!=arg[a][0])&&(arg[b][0]!=arg[j][0]))
{
printf("there is no pair");
}
}
else
{
printf("there is no pair");
}
}
The posted code has several issues, both logical and syntactical, some have been pointed out in the comments.
Just to pick one, consider this line
if ((arg[i][0]==arg[a][0])&&(arg[b][0]==arg[j][0]));
{
// This body will never be executed ^
}
I'd suggest to restart from scratch and to proceed in small steps. See, for instance, the following minimal implementation
// Include all the needed header files, not the unneeded ones.
#include <stdio.h>
// Declare the functions prototype before their use, they will be defined after.
int count_pairs(int n, char const cards[][3]);
// Always specify the inner size, ^ when passing a multidimensional array
void show_score(int n_pairs);
int have_the_same_value(char const *a, char const *b);
int main (void)
{
char hand[5][3] = {
// ^^^^^^ You could omit the 5, here
"5S", "6D", "4H", "KD", "5C"
};
int n_pairs = count_pairs(5, hand);
// Always pass the size ^ if there isn't a sentinel value in the array
show_score(n_pairs);
return 0;
}
// This is a simple O(n^2) algorithm. Surely not the best, but it's
// a testable starting point.
int count_pairs(int n, char const cards[][3])
{
// Always initialize the variables.
int count = 0;
// Pick every card...
for (int i = 0; i < n; ++i)
{
// Compare (only once) with all the remaining others.
for (int j = i + 1; j < n; ++j)
{ // ^^^^^
if ( have_the_same_value(cards[i], cards[j]) ) {
++count;
}
}
}
return count;
}
int have_the_same_value(char const *a, char const *b)
{
return a[0] == b[0];
}
// Interpret the result of count_pairs outputting the score
void show_score(int n_pairs)
{
switch (n_pairs)
{
case 1:
printf("one pair.\n");
break;
case 2:
printf("two pairs.\n");
break;
case 3:
printf("three of a kind.\n");
break;
case 4:
printf("full house.\n");
break;
case 6:
printf("four of a kind.\n");
break;
default:
printf("no pairs.\n");
}
}
Note that my count_pairs function counts every possible pair, so if you pass three cards of the same kind, it will return 3 (given AC, AS, AD, all the possible pairs are AC AS, AC AD, AS AD).
How to correctly calculate all the poker ranks is left to the reader.
Major improvements can be made to the pair function to make it slimmer. However, this answers your questions and solves several corner cases:
#include <stdio.h>
#include <stdlib.h>
void pairCheck(char hand[][2])
{
int pairCount = 0;
int tmpCount = 0;
char tmpCard = '0';
char foundPairs[2] = {0};
// Check Hand One
for(int i =0; i < 5; i++)
{
tmpCard = hand[i][0];
for(int j = 0; j < 5; j++)
{
if(tmpCard == hand[j][0] && i != j)
{
tmpCount++;
}
if(tmpCount == 1 && (tmpCard != foundPairs[0] && tmpCard != foundPairs[1]))
{
foundPairs[pairCount] = tmpCard;
pairCount++;
}
tmpCount = 0;
}
}
printf("Pair Count Hand One: %i\r\n",pairCount);
//Reset Variables
foundPairs[0] = 0;
foundPairs[1] = 0;
tmpCard = '0';
pairCount = 0;
// Check Hand One
for(int i =0; i < 5; i++)
{
tmpCard = hand[i][1];
for(int j = 0; j < 5; j++)
{
if(tmpCard == hand[j][1] && i != j)
{
tmpCount++;
}
if(tmpCount == 1 && (tmpCard != foundPairs[0] && tmpCard != foundPairs[1]))
{
foundPairs[pairCount] = tmpCard;
pairCount++;
}
tmpCount = 0;
}
}
printf("Pair Count Hand Two: %i",pairCount);
}
int main ()
{
char cards[5][2] = { {'5','H'},{'6','D'},{'4','H'},{'K','D'},{'5','C'}};
pairCheck(cards);
return 0;
}
This function will treat three, four, or five of a kind as a single pair. If you want a different behavior the change should be easy.

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]);

Poker Game Results Between Two Players

I'm at the point where I'm trying to rank my players in the game, and determine the winner. You can read my code below, as I think I've documented the logic pretty well throughout.
What I need to do now is determine which player wins, given that there are two players. I've laid out functions for shuffling, dealing, and determining which type of hand it is.
//
// main.c
// Created by gixx88 on 7/22/15.
// Copyright (c) 2015 gixx88. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define SUITS 4
#define FACES 13
#define CARDS 52
#define HAND 5
#define PLAYERS 2
//prototypes for shuffle and deal
void shuffle( size_t wDeck[][FACES] ); //shuffling modifies wDeck
void deal( size_t wDeck[][FACES], const char *wFace[],
const char *wSuit[] ); //dealing doesn't modify the arrays
void dealHand(size_t wHands[][HAND], size_t wDeck[][FACES]);
//prototypes for determing suit and face
size_t determineSuit(size_t wCard);
size_t determineFace(size_t wCard);
//prototypes for determing poker hand
unsigned int findAPair(size_t wHand[HAND]);
unsigned int findTwoPairs(size_t wHand[HAND]);
unsigned int findThreeOfAKind(size_t wHand[HAND]);
unsigned int findFourOfAKind(size_t wHand[HAND]);
unsigned int findFlush(size_t wHand[HAND]);
unsigned int findFullHouse(size_t wHand[HAND]);
unsigned int findStraightFlush(size_t wHand[HAND]);
unsigned int findStraight (size_t wHand[HAND]);
//prototypes for determing player outcomes
unsigned int determingPlayerHand(size_t wHand[HAND]);
void playerRank( size_t wHands[PLAYERS][HAND]);
int main(void) {
//initialize suit array
const char *suit[SUITS] = {"Hearts", "Diamonds", "Clubs", "Spades" };
//initilize face array
const char *face[ FACES ] = { "Ace", "Deuce", "Three", "Four", "Five", "Six", "Seven",
"Eight", "Nine", "Ten", "Jack", "Queen", "King" };
//initilize deck array
size_t deck[ SUITS ][FACES] = {{0}};
size_t hands[PLAYERS][HAND] = {{0}};
srand(time(NULL)); //random seed generator
shuffle(deck); //shuffle the deck
dealHand(hands, deck);
playerRank(hands);
} //end main
//determine suit
size_t determineSuit(size_t wCard){
return wCard / SUITS;
} // end determine suit
//determine face
size_t determineFace(size_t wCard){
return wCard % FACES;
}//end determine face
//if four of a kind
//shuffle cards in deck
void shuffle( size_t wDeck[][FACES] ){
size_t row; //row number
size_t column; //column number
size_t card; //counter
for (card = 0; card <= CARDS; ++card){
//choose a random location until unoccupied slot found
do {
row = rand() % SUITS;
column = rand() % FACES;
} //end do
while (wDeck[row][column] != 0); //end do while
//place card number in chosen slot of deck
wDeck[row][column] = card;
}// end for
} //end shuffle function
//deal cards in deck
void deal( size_t 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 = 0; card <= CARDS; ++card){
//loop through rows of wDeck
for (row = 0; row < SUITS; ++row){
//loop through columns in wDeck for current row
for(column = 0; column < FACES; ++column){
//if slot contians current card, display card
if (wDeck[row][column] == card){
printf("%5s of %-8s%c", wFace[column], wSuit[row],
card % 2 == 0 ? '\n' : '\t'); //two column format
} //end if
} //end column for
} //end row for
} //end card for
} //end function deal
void dealHand(size_t wHands[][HAND], size_t wDeck[][FACES]){
size_t cards;
size_t players;
unsigned int current;
unsigned int current_suit;
unsigned int current_face;
for (cards = 0; cards <= HAND; cards ++){
for (players = 0; players < PLAYERS; players++){
current = cards * PLAYERS + players;
current_suit = current / SUITS;
current_face = current % FACES;
wHands[players][cards] = wDeck[current_suit][current_face];
} // end players for
} // end cards for
} // end deal hand
//PRINT THE CARD
void printCard(unsigned int wCard, const char wFaces[FACES], const char wSuit[SUITS]){
//find suit and face
size_t suit;
size_t face;
suit = determineSuit(wCard);
face = determineFace(wCard);
printf("%s or %s", wFaces[face], wSuit[suit]);
} //end print card
//******************************
//BEGIN HAND TYPE DETERMINATION
//******************************
//find A PAIR
unsigned int findAPair(size_t wHand[HAND]){
size_t countOfFaces[FACES] = { 0 };
unsigned int foundAPair = 1;
size_t card;
for (card = 0; card < HAND; card++)
{
size_t face = determineFace(wHand[card]);
countOfFaces[face]++;
if (countOfFaces[face] == 3)
{
return 1;
}
else if (countOfFaces[face] == 2)
{
if (foundAPair)
{
return 1;
}
foundAPair = 0;
}
}
return foundAPair;
} // end find a pair
//find TWO PAIRS
unsigned int findTwoPairs(size_t wHand[HAND]){
size_t countOfFaces[FACES] = { 0 };
unsigned int numberOfPairs = 0;
size_t card;
for (card = 0; card < HAND; card++){
size_t face = determineFace(wHand[card]);
countOfFaces[face]++;
if (countOfFaces[face] == 3)
{
return 1;
}
else if (countOfFaces[face] == 2)
{
numberOfPairs++;
}
}
return numberOfPairs == 2;
} //end find two pairs
//find THREE OF A KIND
unsigned int findThreeOfAKind(size_t wHand[HAND]){
size_t countOfFaces[FACES] = {0};
size_t card;
unsigned int foundThree = 1;
for (card = 0; card < HAND; card++){
size_t face = determineFace(wHand[card]);
countOfFaces[face]++;
if (countOfFaces[face] == 3){
foundThree = 0;
} //end if
else if (countOfFaces[face] == 4){
return 1;
} //end else if
else if (countOfFaces[face] == 2 && foundThree){
return 1;
} //end else if
} //end card for loop
return 1;
} //end find three of a kind
//find FOUR OF A KIND
unsigned int findFourOfAKind(size_t wHand[HAND]){
size_t countOfFaces[FACES] = {0};
size_t card;
for (card = 0; card < HAND; card++){
size_t face = determineFace(wHand[card]);
countOfFaces[face]++;
if (countOfFaces[face] == 4){
return 0;
} //end if
} //end card for loop
return 1;
} //end for of a kind
unsigned int findStraight (size_t wHand[HAND]){
size_t card;
size_t lowFace;
size_t highFace;
size_t firstSuit;
unsigned int foundSecondSuit = 1;
for (card = 0; card < HAND; card++)
{
size_t suit = determineSuit(wHand[card]);
size_t face = determineFace(wHand[card]);
// first card
if (card == 0)
{
lowFace = face;
highFace = face;
firstSuit = suit;
}
// all other cards
// check for two equal faces first
else if (face == lowFace || face == highFace)
{
return 1;
}
// update low and high face, if necessary
else
{
if (suit != firstSuit)
{
foundSecondSuit = 0;
}
// an Ace can only go low if the low face is at most a Five
if (face == 0 && lowFace > HAND - 1)
{
face = 13;
}
if (face < lowFace)
{
lowFace = face;
}
if (face > highFace)
{
highFace = face;
}
if ((highFace - lowFace + 1) != HAND)
{
return 1;
}
}
}
return foundSecondSuit;
}
//find FLUSH
unsigned int findFlush(size_t wHand[HAND]){
size_t card;
size_t firstSuit = 5;
for (card = 0; card < HAND; card++){
size_t suit = determineSuit(wHand[card]);
//determing if all cards are the same suit
if (card == 0){
firstSuit = suit;
} //end if
else if (suit != firstSuit){
return 1;
} //end else if
} //end card for loop
return 0;
} //end find flush
//find FULL HOUSE
unsigned int findFullHouse(size_t wHand[HAND]){
if (findAPair(wHand) && findThreeOfAKind(wHand)){
return 0;
} //end if
return 1;
} //end full house
//find STRAIGHT FLUSH
unsigned int findStraightFlush(size_t wHand[HAND]){
size_t lowFace;
size_t highFace;
size_t card;
size_t firstSuit;
for (card = 0; card < HAND; card++){
size_t suit = determineSuit(wHand[card]);
size_t face = determineFace(wHand[card]);
//determing if all cards are the same suit
if (card == 0){
firstSuit = suit;
lowFace = face;
highFace = face;
} //end if
else if (suit != firstSuit || face == lowFace || face == highFace){
return 1;
} //end else if
//determination for ace being high or low, which depends on hand
else
{
// an Ace can only go low if the low face is at most a Five
if (face == 0 && lowFace > HAND - 1)
{
face = 13;
}
if (face < lowFace)
{
lowFace = face;
}
if (face > highFace)
{
highFace = face;
}
if ((highFace - lowFace + 1) != HAND)
{
return 1;
}
}
}
return 0;
} //end straight flush
//****************************
//DETERMINING PLAYER OUTCOMES
//****************************
//determing PLAYER HAND
unsigned int determingPlayerHand(size_t wHand[HAND]){
if (findStraightFlush(wHand) == 0){
return 8;
} //end if
else if (findFourOfAKind(wHand) == 0){
return 7;
} //end else if
else if (findFullHouse(wHand) == 0){
return 6;
} //end else if
else if (findFlush(wHand) == 0){
return 5;
} //end else if
else if (findStraight(wHand) == 0){
return 4;
} //end else if
else if (findThreeOfAKind(wHand) == 0){
return 3;
} //end else if
else if (findTwoPairs(wHand) == 0){
return 2;
} //end else if
else if (findAPair(wHand) == 0){
return 1;
}
return 0;
} //end determing player hand
//determing PLAYER RANK
void playerRank( size_t wHands[PLAYERS][HAND]){
unsigned int player1 = determingPlayerHand(wHands);
unsigned int player2 = determingPlayerHand(wHands);
if (player1 > player2){
printf("%s", "Player 1 Wins!");
}//end if
else if (player2 > player1){
printf("%s", "Player 2 Wins!");
}
} //end player rank
I'm loathe to post this, but sadly, I've got to finish this by tomorrow and I've already been working on it 12 hours straight. My concern is that I set up my poker hand type function to only take one dimension of the two dimensional array. Is there a way to effectively build a ranking system for players with what I have?
Here are some notes I made to myself elsewhere that may also be useful: determingPlayerHand only takes one subscript of the two dimensional array. I need playerRanking to take both subscripts. How can I make this happen so that my rankings will return properly to each player? The ranking returning values should be fine, I think. I initially had it as just true or false, 1 or 0, but then realized that wasn't specific enough
Please let me know what other information I can provide if I need to make this more clear or relevant.
After M Oehm's comment, I want to update this to reflect some other information that I realized would be useful.
Part of the parameters of the problem I'm solving require certain things to be the way they are. If I had my choice in changing them, I think there are better ways to do this as well. However, the deck being as it is, the shuffling algorithm, and the deal algorithm are built to specification of the problem. As for hands evaluating to what they should, so far they do, and I wrote it based on the idea that ace needs to go high at a certain point, which is part of why it's so complicated. The two dimensional array with [PLAYERS][HAND] is meant to make it so that cards are dealt in alternating order to each player from the top of the deck, as would be done in real life.
You have gotten off to a bad start when chosing how to represent your deck and the hands.
You represent the cards as integers from 0 to 51 in the deck's factory order from Ace of Hearts to King of Clubs. That's fine. You can determine the rank and suit from the card number:
rank = card % 13;
suit = card / 13;
That's not what you do in your determineFace/Suit functions. Next, the deck ist a one-dimensional array of cards:
int deck[52];
You can shuffle this array with one of the well-known shuffling algorithms, e.g. Fisher-Yates. You represent the deck as two-dimensional array, which doesn't make the shuffling any easier. It it also not clear what the two dimensions of the deck are. (Okay, they are suit and rank, but after shuffling, that doesn't make sense any longer.)
In a one-dimensional array, the first player's hand are the first five cards and the second player's hand are cards 5 to 9.
Your algorithms to determine the hands are too complicated and have some copy-and-paste errors. Evaluating poker hands boils down to three criteria:
Flush: Are all cards of a hand of the same suit?
Straight: Are all ranks consecutive? (With the special rule that the ace can be played high or lowas appropriate)
Multiples: Most hands have pairs, triplets or quadruplets of cards or combinations thereof, so you need a "histogram" of ranks, sorted by occurrence.
With that data, you can determine your hands. You also need secondary data to distinguish between two equal hands, e.g. a pair of Kings and a pair of Nines.
I suggest you start afresh, switch on compiler warnings and implement shuffling, dealing and the three hand criteria step by step with verification between the steps. (You can call these steps "Milestones", if you like.)

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.

how to fill, shuffle, deal the card game

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.

Resources