Code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <stdbool.h>
#define DECK_SIZE 52
#define SINGLE_DECK 52
#define FULL_HAND 5
#define SINGLE_CARD 1
#define MIN_PLAYER 2
#define MAX_PLAYER 4
enum Suit { SPADES = 0, HEARTS = 1, CLUBS = 2, DIAMONDS = 3};
enum Card_Value {TWO =2, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE};
enum Input_Codes {SUCCESS = 0, INPUT_TO_LONG, INPUT_BLANK, INCORRECT_ENTRY};
typedef struct
{
enum Suit suit;
enum Card_Value value;
char code[5];
bool in_play;
} Card;
typedef struct
{
int bank;
int bets;
char player_name[10];
Card cards[5];
}Hand;
void initalize_deck(Card *p_deck);
void initalize_random_generator(void);
void shuffle_deck(Card *p_deck);
void get_card_code(int suit, int face_value, char *p_temp_string);
int get_num_players(void);
void get_player_names(int num_of_players, Hand *p_player);
int get_input(char line[], int linesize);
void flush_line(void);
int get_full_hand(int player_num, int num_cards_delt, Card *p_deck, Hand *p_player);
void deal_cards(int player_num, int num_of_cards, int num_of_cards_in_hand, int num_cards_delt, Card *p_deck, Hand *p_player);
void move_deck(int *cards_in_play, Card deck[]);
void print_deck(Card deck[]);
void set_bank(int num_players, Hand *p_player);
void get_bets(int num_players, int *p_pooled_bets, Card *p_deck, Hand *p_player);
void show_hand(int player_number, Hand *p_player);
int get_bet(int bank, int past_bets, int highest_bet, char name[]);
int check_bets_equal(int player_num, int highest_bet, Hand *p_player);
int player_folded(int player, int num_players, int *p_pooled_bets, Card *p_deck, Hand *p_player);
void put_card_back(Card card, Card *p_deck);
int transfer_bets_to_pool(int num_of_players, Hand *p_player);
int main()
{
int num_of_players = 0, num_cards_delt = 0, bet_pool = 0;
Card deck[DECK_SIZE];
initalize_random_generator();
initalize_deck(deck);
num_of_players = get_num_players();
// declare variable player array and set bank array
Hand player[num_of_players];
get_player_names(num_of_players, player);
set_bank(num_of_players, player);
num_cards_delt = get_full_hand(num_of_players, num_cards_delt, deck, player);
move_deck(&num_cards_delt, deck);
get_bets(num_of_players, &bet_pool, deck, player); //TODO FINISH CODE
bet_pool = transfer_bets_to_pool(num_of_players, player);
}
void initalize_deck(Card *p_deck)
{
int face_value, suit_value, num_deck, card_count = 0, deck_count = DECK_SIZE / SINGLE_DECK;
char temp_str[5];
for (num_deck = 0; num_deck < deck_count; num_deck++)
{
for (suit_value = SPADES; suit_value <= DIAMONDS; suit_value++)
{
for (face_value = TWO; face_value <= ACE; face_value++)
{
get_card_code(suit_value, face_value, temp_str);
p_deck[card_count] = (Card) {suit_value, face_value};
p_deck[card_count].in_play = false;
strcpy(p_deck[card_count++].code, temp_str);
}
}
}
shuffle_deck(p_deck);
}
void initalize_random_generator(void)
{
srand((unsigned) time(NULL));
}
void shuffle_deck(Card *p_deck)
{
int i, random_card;
Card temp_card;
for (i = 0; i < DECK_SIZE; i++)
{
temp_card = p_deck[i];
random_card = rand() % DECK_SIZE;
p_deck[i] = p_deck[random_card];
p_deck[random_card] = temp_card;
}
}
void get_card_code(int suit, int face_value, char *p_temp_string)
{
/*******************************************
* Thanks to flp1969 for this code. Suit: *
* goes from 0 spades, 1 hearts ,2 clubs, *
* and 3 is diamonds. Card: ace = 0, 2 = 1,*
* 3 = 2 ... 10 = 9, J = 10, Q = 11, K = 12*
*******************************************/
int c = 0x1f0a1;
if (face_value == ACE)
{
face_value -= 14;
}
else
{
face_value -= 1;
}
switch ( suit )
{ //deliberate fall through
case 2: // clubs
c += 0x10;
case 3: // diamonds
c += 0x10;
case 1: // hearts
c += 0x10;
}
switch ( face_value )
{
case 0 ... 10:
c += face_value;
break;
default:
c += face_value + 1;
}
p_temp_string[0] = 0xf0 | ((c >> 18) & 7);
p_temp_string[1] = 0x80 | ((c >> 12) & 0x3f);
p_temp_string[2] = 0x80 | ((c >> 6) & 0x3f);
p_temp_string[3] = 0x80 | (c & 0x3f);
}
int get_num_players(void)
{
int number = 0, line_size, check_digit;
char line[3];
line_size = sizeof(line);
do
{
printf("Enter the number of players (2 - 4): ");
check_digit = get_input(line, line_size);
switch (check_digit)
{
case INPUT_TO_LONG:
printf("Incorrect Entry: Number entered must be a single digit\n");
break;
case INPUT_BLANK:
printf("Incorrect Entry: Number of players cannot be blank\n");
break;
case SUCCESS:
if (!sscanf(line, " %1d", &number))
{
printf("Incorrect entry:Please enter a digit only\n");
check_digit = INCORRECT_ENTRY;
}
else if (number < 1 || number > 4)
{
printf("Incorrect entry: Too many players\n");
check_digit = INCORRECT_ENTRY;
}
}
}while (check_digit);
return number;
}
/***************************************************
* Thanks to laserlight for the 2 functions below *
***************************************************/
int get_input(char line[], int linesize)
{
if (!fgets(line, linesize, stdin))
{
// maybe the user triggered EOF or something, so for our purposes, bail out:
fprintf(stderr, "Error: unexpected end-of-file or read failure\n");
exit(EXIT_FAILURE);
}
char *newline = strchr(line, '\n');
if (!newline) //name too long
{
flush_line();
return INPUT_TO_LONG;
}
if (newline == line)
{
return INPUT_BLANK;
}
*newline = '\0';
return SUCCESS;
}
void get_player_names(int num_of_players, Hand players[])
{
int i, line_size, check_digit;
char line[sizeof(players->player_name) + 1]; // +1 for newline
line_size = sizeof(line) + 1;
for (i = 0; i < num_of_players; i++)
{
do
{
printf("Please enter player %d's name: ", i + 1);
check_digit = get_input(line, line_size);
switch (check_digit)
{
case INPUT_TO_LONG:
printf("Incorrect Entry: name must have a length of no more than %d characters\n", line_size - 2);
break;
case INPUT_BLANK:
printf("Incorrect Entry: name cannot be blank\n");
}
}
while (check_digit);
strcpy(players[i].player_name, line);
}
// this is ok for debugging, otherwise it should not be here:
for (int i = 0; i < num_of_players; i++)
{
printf("Player %d's name is %s\n", i + 1, players[i].player_name);
}
}
void flush_line(void)
{
char c;
while ((c = getchar()) != '\n' && c != EOF)
{}
}
void move_deck(int *cards_in_play, Card deck[])
{
int i, j;
do
{
for ( i = 0, j = *cards_in_play ; j < 52 ; i++, j++ )
{
deck[i] = deck[j];
}
for ( ; i < 52 ; i++ )
{
deck[i].in_play = true;
}
} while (deck[0].in_play);
print_deck(deck);
*cards_in_play = 0;
}
void print_deck(Card deck[])
{
int i;
for (i = 0; i < 52; i++)
{
if (deck[i].in_play)
{
printf("ee ");
}
else
{
printf("%d%d ", deck[i].suit, deck[i].value);
}
}
printf("\n");
}
int get_full_hand(int player_num, int num_cards_delt, Card *p_deck, Hand *p_player)
{
int i, j;
for (j = 0; j < FULL_HAND; j++)
{
for (i = 0; i < player_num; i++)
{
deal_cards(i, SINGLE_CARD, j, num_cards_delt, p_deck, p_player);
num_cards_delt++;
}
}
return num_cards_delt;
}
void deal_cards(int player_num, int num_of_cards, int num_of_cards_in_hand, int num_cards_delt, Card *p_deck, Hand *p_player)
{
int i;
for (i = 0; i < num_of_cards; i++)
{
strcpy(p_player[player_num].cards[num_of_cards_in_hand].code, p_deck[num_cards_delt].code);
p_deck[num_cards_delt].in_play = true;
//printf("p_player[player_num].hand[num_of_cards_in_hand].card_code is %s to here\n", p_player[player_num].hand[num_of_cards_in_hand].card_code);
}
}
void set_bank(int num_players, Hand *p_player)
{
int i;
for (i = 0; i < num_players; i++)
{
p_player[i].bank = 1000;
p_player[i].bets = 0;
}
}
//*
int player_folded(int player, int num_players, int *p_pooled_bets, Card *p_deck, Hand *p_player)
{
int i;
Card temp_card;
if (player == num_players - 1)
{
return num_players -1;
}
else
{
for (i = player; i < num_players; i++)
{
p_player[i]= p_player[i + 1];
}
}
for (i = 0; i < FULL_HAND; i++)
{
temp_card = p_player[player].cards[i],
put_card_back(temp_card, p_deck);
}
*p_pooled_bets += p_player[player].bets;
print_deck(p_deck);
return num_players - 1;
}
int check_bets_equal(int player_num, int highest_bet, Hand *p_player)
{
int i;
for (i = 0; i < player_num; i++)
{
if (p_player[i].bets != highest_bet)
{
return 0;
}
}
return 1;
}
int get_bet(int bank, int past_bets, int highest_bet, char name[])
{
int temp_bet = 0;
do
{
if (!highest_bet) //first time run
{
printf("%s Your bank is £%d\nPlease place your bet ", name, bank);
}
else
{
printf("%s Your bank is £%d\nYour mimimun bet is %d please place your bet ", name, bank,
highest_bet - past_bets);
}
scanf("%d", &temp_bet);
if (!temp_bet)
{
printf("%s folded\n", name);
break;
}
if (bank - temp_bet < 0)
{
printf("Sorry you dont have enough in your account for that\n");
temp_bet = -1;
}
}while (temp_bet < (highest_bet - past_bets));
return temp_bet;
}
void show_hand(int player_number, Hand *p_player)
{
int i;
printf("\033c");
printf("%s's hand is: ", p_player[player_number].player_name);
for (i = 0; i < FULL_HAND; i++)
{
printf("%s ", p_player[player_number].cards[i].code);
}
printf("\n");
}
void get_bets(int num_players, int *p_pooled_bets, Card *p_deck, Hand *p_player)
{
int i, highest_bet = 0, temp_bet, loop = 1;
while (loop)
{
for (i = 0; i < num_players; i++)
{
show_hand(i, p_player);
temp_bet = get_bet(p_player[i].bank, p_player[i].bets, highest_bet, p_player[i].player_name);
if (temp_bet)
{
p_player[i].bets += temp_bet;
p_player[i].bank -= temp_bet;
highest_bet = p_player[i].bets;
}
//*
else
{
num_players = player_folded(i, num_players, p_pooled_bets, p_deck, p_player);
i -= 1;
}
//*/
if (check_bets_equal(num_players, highest_bet, p_player))
{
loop = 0;
break;
}
}
}
}
//*/
int transfer_bets_to_pool(int num_of_players, Hand *p_player)
{
int i, pooled_bets;
for (i = 0; i < num_of_players; i++)
{
pooled_bets += p_player[i].bets;
}
return pooled_bets;
}
void put_card_back(Card card, Card *p_deck)
{
int i;
for (i = 0; i < 52; i++)
{
if (p_deck[i].in_play)
{
p_deck[i] = card;
p_deck[i].in_play = false;
break;
}
}
}
when i deal the cards the suit and face value are correct. but when i come to put them back in the deck if a player folds they are silly numbers. i suspect half the issue is i have to pass the deck round like sweets at a children's party just to get it to the function that actually puts the card back one at a time.