
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define SUITS 4
#define FACES 13
#define HAND_SIZE 5


void shuffel(int deck[][FACES]);

void deal(int deck[][FACES], const char* face[], const char* suit[],int row1[], int col1[],int row2[], int col2[]);

int containsPair(int handCol[]);
int containsTwoPairs(int handCol[]);
int containsThreeOfKind(int handCol[]);
int containsFourOfKind(int handCol[]);
int containsFlush(int handRow[]);
int containsStraight(int handCol[]);
int containsFullHouse(int handCol[]);

int evaluateHand(int handRow[], int handCol[]);
const char* getHandName(int rank);



int main(void)
{
    int deck[SUITS][FACES] = { 0 };

    int row1[HAND_SIZE], col1[HAND_SIZE];
    int row2[HAND_SIZE], col2[HAND_SIZE];

    const char* suit[SUITS] = {"Hearts", "Diamonds", "Clubs", "Spades"};

    const char* face[FACES] = {"Ace", "Deuce", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King"};

    srand(time(NULL));

    shuffel(deck);

    deal(deck, face, suit,row1, col1, row2, col2);

    int rank1 = evaluateHand(row1, col1);
    int rank2 = evaluateHand(row2, col2);

    printf("\nPlayer 1 hand: %s\n", getHandName(rank1));
    printf("Player 2 hand: %s\n", getHandName(rank2));

    if (rank1 > rank2)
    {
        printf("\nPlayer 1 wins\n");
    }
    else if (rank2 > rank1)
    {
        printf("\nPlayer 2 wins\n");
    }
    else
    {
        printf("\nBoth players have the same hand category.\n");
    }

    return 0;
}


void shuffel(int deck[][FACES])
{
    for (int card = 1; card <= 52; card++)
    {
        int row;
        int column;

        do
        {
            row = rand() % SUITS;
            column = rand() % FACES;
        } while (deck[row][column] != 0);

        deck[row][column] = card;
    }
}



void deal(int deck[][FACES],const char* face[],const char* suit[],int row1[], int col1[],int row2[], int col2[])
{
    printf("Player 1 cards:\n");

    for (int card = 1; card <= 10; card++)
    {
        for (int row = 0; row < SUITS; row++)
        {
            for (int column = 0; column < FACES; column++)
            {
                if (deck[row][column] == card)
                {
                    int index = (card - 1) % HAND_SIZE;

                    if (card <= 5)
                    {
                        printf("%s of %s\n",face[column], suit[row]);

                        row1[index] = row;
                        col1[index] = column;
                    }
                    else
                    {
                        if (card == 6)
                            printf("\nPlayer 2 cards:\n");

                        printf("%s of %s\n",face[column], suit[row]);

                        row2[index] = row;
                        col2[index] = column;
                    }
                }
            }
        }
    }
}



int containsPair(int handCol[])
{
    int count[FACES] = { 0 };
    int pairs = 0;

    for (int i = 0; i < HAND_SIZE; i++)
        count[handCol[i]]++;

    for (int i = 0; i < FACES; i++)
    {
        if (count[i] == 2)
            pairs++;
    }

    return pairs == 1;
}



int containsTwoPairs(int handCol[])
{
    int count[FACES] = { 0 };
    int pairs = 0;

    for (int i = 0; i < HAND_SIZE; i++)
        count[handCol[i]]++;

    for (int i = 0; i < FACES; i++)
    {
        if (count[i] == 2)
            pairs++;
    }

    return pairs == 2;
}



int containsThreeOfKind(int handCol[])
{
    int count[FACES] = { 0 };

    for (int i = 0; i < HAND_SIZE; i++)
        count[handCol[i]]++;

    for (int i = 0; i < FACES; i++)
    {
        if (count[i] == 3)
            return 1;
    }

    return 0;
}



int containsFourOfKind(int handCol[])
{
    int count[FACES] = { 0 };

    for (int i = 0; i < HAND_SIZE; i++)
        count[handCol[i]]++;

    for (int i = 0; i < FACES; i++)
    {
        if (count[i] == 4)
            return 1;
    }

    return 0;
}



int containsFlush(int handRow[])
{
    for (int i = 1; i < HAND_SIZE; i++)
    {
        if (handRow[i] != handRow[0])
            return 0;
    }

    return 1;
}



int containsStraight(int handCol[])
{
    int temp[HAND_SIZE];

    for (int i = 0; i < HAND_SIZE; i++)
        temp[i] = handCol[i];

    
    for (int i = 0; i < HAND_SIZE ; i++)
    {
        for (int j = 0; j < HAND_SIZE - i - 1 ; j++)
        {
            if (temp[j] > temp[j + 1])
            {
                int swap = temp[j];
                temp[j] = temp[j + 1];
                temp[j + 1] = swap;
            }
        }
    }


    

    for (int i = 0; i < HAND_SIZE - 1; i++)
    {
        if (temp[i + 1] != temp[i] + 1)
        {
            return 0;
            
        }
    }

    
        return 1;

   
}


int containsFullHouse(int handCol[])
{
    
    return containsPair(handCol) && containsThreeOfKind(handCol);
}



int evaluateHand(int handRow[], int handCol[])
{
    int flush = containsFlush(handRow);
    int straight = containsStraight(handCol);

    if (flush && straight)
        return 8;

    if (containsFourOfKind(handCol))
        return 7;

    if (containsFullHouse(handCol))
        return 6;

    if (flush)
        return 5;

    if (straight)
        return 4;

    if (containsThreeOfKind(handCol))
        return 3;

    if (containsTwoPairs(handCol))
        return 2;

    if (containsPair(handCol))
        return 1;

    return 0;
}



const char* getHandName(int rank)
{
    switch (rank)
    {
    case 8: return "Straight Flush";
    case 7: return "Four of a Kind";
    case 6: return "Full House";
    case 5: return "Flush";
    case 4: return "Straight";
    case 3: return "Three of a Kind";
    case 2: return "Two Pairs";
    case 1: return "One Pair";
    default: return "High Card";
    }
}
