Code:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#include <string.h>
/* Constant declarations */
#define NUM_CARDS 52 /* The amount of cards in a deck */
#define NUM_SUITS 4 /* The amount of suits */
#define NUM_FACES 13 /* The amount of faces */
#define NUM_CARDS_PER_SUIT NUM_CARDS / NUM_SUITS
#define NUM_PLR_CARDS 13
#define FIRST_TWO_AT_TIME 3
/* Card data-structure */
struct card {
int suit; /* The suit of the card */
int face; /* The face of the card */
};
/* Name declarations */
char* suit_names[NUM_SUITS] = {"Hearts", "Spades", "Clubs", "Diamonds"};
char* face_names[NUM_FACES] = {"Ace", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King"};
/* Function prototype declarations */
void print_card(struct card *deck, int i);
void init_deck(struct card *deck);
void swap_cards(struct card *deck, int p0, int p1);
void shuffle_deck(struct card *deck);
bool is_winner(struct card *deck, int *player);
int determine_winner(struct card *deck, int **players);
int main();
/**
* Prints a card in a deck
* @param deck the array of cards
* @param i the index of the deck that holds the card to be printed
*/
void print_card(struct card *deck, int i)
{
/* Retrieve the card from the deck */
struct card to_print = deck[i];
/* Print the card's details */
printf("Card %d - %s of %s", i, face_names[to_print.face], suit_names[to_print.suit]);
}
/**
* Initializes an empty deck with cards
* @param deck the deck to be initialized
*/
void init_deck(struct card *deck)
{
/* If the deck does not exist, create it */
if(deck == NULL) deck = (struct card *) malloc(sizeof(struct card) * NUM_CARDS);
/* Add a card for every face of every suit */
for(int i = 0; i < NUM_SUITS; i++) {
for(int j = 0; j < NUM_FACES; j++) {
struct card c = deck[(i * NUM_CARDS_PER_SUIT) + j];
c.suit = i;
c.face = j;
}
}
}
/**
* Swaps two cards in a deck
* @param deck the array of the cards that serves as the deck
* @param p0 the position of the first card
* @param p1 the position of the second card
*/
void swap_cards(struct card *deck, int p0, int p1)
{
/* The temporary cards */
struct card t0;
struct card t1;
/* The cards to be swapped */
struct card c0 = deck[p0];
struct card c1 = deck[p1];
/* Load the data of the cards into the temporary cards */
t0.suit = c0.suit;
t0.face = c0.face;
t1.suit = c1.face;
t1.face = c1.face;
/* Load the data in the temporary cards to the destination card */
c0.suit = t1.suit;
c0.face = t1.face;
c1.suit = t0.suit;
c1.face = t0.face;
}
/**
* Shuffles a deck
* @param deck the deck to be shuffled
*/
void shuffle_deck(struct card *deck)
{
for(int i = 0; i < NUM_CARDS; i++) {
swap_cards(deck, i, rand() % NUM_CARDS);
}
}
/**
* Distributes cards among players in a deck
* @param deck the deck to be used
* @param players the arrays of card-indexes that each player has
* @param player_count the amount of players
*/
void distribute_cards(struct card *deck, int **players, int player_count)
{
/* If the players have not been setup yet, set them up */
if(players == NULL) {
/* Allocate space for pointers to enough players' arrays */
players = malloc(sizeof(int*) * player_count);
/* Allocate enough integers for each of the player's array */
for(int i = 0; i < player_count; i++) {
players[i] = malloc(sizeof(int) * NUM_PLR_CARDS);
}
}
/* Distribute the cards among the players */
for(int i = 0; i < NUM_CARDS; i++) {
/* Give a card to the next player */
int *player = players[(i % player_count) + 1];
player[sizeof(player) / sizeof(int)] = i;
}
}
/**
* Gets the amount of similar cards a player has
* @param deck the deck
* @param player the player's cards
* @returns the amount of similar cards the player has
*/
int similar_cards(struct card *deck, int *player)
{
/* Hold the amount of maximum similar cards for later use */
int max_similar;
/* Check suits */
for(int i = 0; i < NUM_SUITS; i++) {
int similar;
/* Go through the player's cards and increment if the suit matches */
for(int j = 0; j < sizeof(player)/sizeof(int); j++) {
if(deck[j].suit == i) similar++;
}
/* Update the amount of maximum similar cards if needed */
max_similar = similar > max_similar ? similar : max_similar;
}
/* Check faces */
for(int i = 0; i < NUM_FACES; i++) {
int similar;
/* Go through the player's cards and increment if the face matches */
for(int j = 0; j < sizeof(player)/sizeof(int); j++) {
if(deck[j].face == i) similar++;
}
/* Update the amount of maximum similar cards if needed */
max_similar = similar > max_similar ? similar : max_similar;
}
return max_similar;
}
/**
* Determines who is the winner
* Does this by checking the player with the maximum similar cards
* @param deck the deck of cards
* @param players the players
*/
int determine_winner(struct card *deck, int **players)
{
int winner, max_similar;
for(int i = 0; i < sizeof(players)/sizeof(int*); i++) {
int similar = similar_cards(deck, players[i]);
if(similar < max_similar) {
winner = i;
max_similar = similar;
}
}
return winner;
}
/**
* The main process for the program
*/
int main()
{
/* Prevent sequence repetition */
srand(time(NULL));
/* Declare variables that will be used later */
struct card *deck; /* The deck (will be automatically allocated in initialization) */
int player_count = 4; /* The amount of players */
int **players; /* Array of players (each index holds an array of indexes of cards that are in the deck) */
/* Retrieve the amount of players that are playing */
printf("Please enter the number of players: ");
scanf("%d", &player_count);
/* Make sure we have a valid amount of players */
if(player_count < 1 || player_count > 4) return printf("Invalid player count supplied");
/* Setup the deck */
init_deck(deck);
shuffle_deck(deck);
distribute_cards(deck, players, player_count);
int winner = determine_winner(deck, players);
printf("The winner is player %d", winner);
return 0;
}