
#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 dealHand(int deck[][FACES], int startCard,
    int handRow[], int handCol[]);

void displayHand(int handRow[], int handCol[],
    const char* face[], const char* suit[]);

void playerChooseCards(int replace[]);

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

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

int cardsToReplace(int rank);

void markCardsToReplace(int handRow[], int handCol[],int rank, int replace[]);

void replaceCards(int deck[][FACES],int handRow[], int handCol[],int replace[], int* nextCard);

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

    int playerRow[HAND_SIZE], playerCol[HAND_SIZE];
    int dealerRow[HAND_SIZE], dealerCol[HAND_SIZE];

    int playerReplace[HAND_SIZE] = { 0 };
    int dealerReplace[HAND_SIZE] = { 0 };

    int nextCard = 11;

    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((unsigned int)time(NULL));

    shuffel(deck);


    dealHand(deck, 1, playerRow, playerCol);
    dealHand(deck, 6, dealerRow, dealerCol);

    printf("Your hand:\n");
    displayHand(playerRow, playerCol, face, suit);


    playerChooseCards(playerReplace);


    int dealerRank = evaluateHand(dealerRow, dealerCol);

    markCardsToReplace(dealerRow, dealerCol, dealerRank, dealerReplace);

    replaceCards(deck, dealerRow, dealerCol, dealerReplace, &nextCard);

    replaceCards(deck, playerRow, playerCol, playerReplace, &nextCard);

    int playerRank = evaluateHand(playerRow, playerCol);
    dealerRank = evaluateHand(dealerRow, dealerCol);

    printf("\nYour final hand:\n");
    displayHand(playerRow, playerCol, face, suit);
    printf("Your hand: %s\n", getHandName(playerRank));

    printf("\nComputer's final hand:\n");
    displayHand(dealerRow, dealerCol, face, suit);
    printf("Computer's hand: %s\n", getHandName(dealerRank));

    if (playerRank > dealerRank)
        printf("\nYou win!\n");
    else if (dealerRank > playerRank)
        printf("\nComputer wins!\n");
    else
        printf("\nIt's a draw by hand category!\n");


}
void shuffel(int deck[][FACES])
{
    for (int card = 1; card <= SUITS * FACES; card++)
    {
        int row, col;

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

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



void dealHand(int deck[][FACES], int startCard, int handRow[], int handCol[])
{
    int cardNumber = startCard;

    for (int i = 0; i < HAND_SIZE; i++)
    {
        int found = 0;

        for (int row = 0; row < SUITS && !found; row++)
        {
            for (int col = 0; col < FACES; col++)
            {
                if (deck[row][col] == cardNumber)
                {
                    handRow[i] = row;
                    handCol[i] = col;
                    found = 1;
                    break;
                }
            }
        }

        cardNumber++;
    }
}



void displayHand(int handRow[], int handCol[],const char* face[], const char* suit[])
{
    for (int i = 0; i < HAND_SIZE; i++)
    {
        printf("%d. %s of %s\n",
            i + 1,
            face[handCol[i]],
            suit[handRow[i]]);
    }
}



void playerChooseCards(int replace[])
{
    int number;

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

    printf("\nHow many cards do you want to replace? (0-3): ");
    scanf("%d", &number);

    while (number < 0 || number > 3)
    {
        printf("Enter a number from 0 to 3: ");
        scanf("%d", &number);
    }

    for (int i = 0; i < number; i++)
    {
        int position;

        printf("Enter card position to replace (1-5): ");
        scanf("%d", &position);

        while (position < 1 || position > 5 ||
            replace[position - 1] == 1)
        {
            printf("Invalid or repeated position. Try again: ");
            scanf("%d", &position);
        }

        replace[position - 1] = 1;
    }
}



int containsPair(int handCol[], int replace[])
{
    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++;
    }

    if (pairs != 1)
        return 0;

    if (replace != NULL)
    {
        for (int i = 0; i < HAND_SIZE; i++)
            replace[i] = (count[handCol[i]] == 2) ? 0 : 1;
    }

    return 1;
}



int containsTwoPairs(int handCol[], int replace[])
{
    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++;
    }

    if (pairs != 2)
        return 0;

    if (replace != NULL)
    {
        for (int i = 0; i < HAND_SIZE; i++)
            replace[i] = (count[handCol[i]] == 2) ? 0 : 1;
    }

    return 1;
}



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

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

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

    if (!found)
        return 0;

    if (replace != NULL)
    {
        for (int i = 0; i < HAND_SIZE; i++)
            replace[i] = (count[handCol[i]] == 3) ? 0 : 1;
    }

    return 1;
}



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

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

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

    if (!found)
        return 0;

    if (replace != NULL)
    {
        for (int i = 0; i < HAND_SIZE; i++)
            replace[i] = (count[handCol[i]] == 4) ? 0 : 1;
    }

    return 1;
}


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

    if (replace != NULL)
    {
        for (int i = 0; i < HAND_SIZE; i++)
            replace[i] = 0;
    }

    return 1;
}


int containsStraight(int handCol[], int replace[])
{
    int values[HAND_SIZE];

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


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

    int straight = 1;

    for (int i = 1; i < HAND_SIZE; i++)
    {
        if (values[i] != values[i - 1] + 1)
        {
            straight = 0;
            break;
        }
    }

    

    if (!straight)
        return 0;

    if (replace != NULL)
    {
        for (int i = 0; i < HAND_SIZE; i++)
            replace[i] = 0;
    }

    return 1;
}


int containsFullHouse(int handCol[])
{
    int count[FACES] = { 0 };
    int hasThree = 0;
    int hasPair = 0;

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

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

        if (count[i] == 2)
            hasPair = 1;
    }

    return hasThree && hasPair;
}



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

    if (flush && straight)
        return 8;

    if (containsFourOfKind(handCol, NULL))
        return 7;

    if (containsFullHouse(handCol))
        return 6;

    if (flush)
        return 5;

    if (straight)
        return 4;

    if (containsThreeOfKind(handCol, NULL))
        return 3;

    if (containsTwoPairs(handCol, NULL))
        return 2;

    if (containsPair(handCol, NULL))
        return 1;

    return 0;
}


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


int cardsToReplace(int rank)
{
    if (rank == 0) return 3; 
    if (rank == 1) return 3; 
    if (rank == 2) return 1; 
    if (rank == 3) return 2; 

    return 0;
}



void markCardsToReplace(int handRow[], int handCol[],int rank, int replace[])
{
    for (int i = 0; i < HAND_SIZE; i++)
        replace[i] = 0;

    int number = cardsToReplace(rank);

    if (number == 0)
        return;

    if (rank == 1)
    {
        containsPair(handCol, replace);
    }
    else if (rank == 2)
    {
        containsTwoPairs(handCol, replace);
    }
    else if (rank == 3)
    {
        containsThreeOfKind(handCol, replace);
    }
    else if (rank == 0)
    {
        
        for (int i = 0; i < HAND_SIZE; i++)
            replace[i] = 1;

        
        int best1 = -1;
        int best2 = -1;
        int value1 = -1;
        int value2 = -1;

        for (int i = 0; i < HAND_SIZE; i++)
        {
            
            int value = (handCol[i] == 0) ? 13 : handCol[i];

            if (value > value1)
            {
                value2 = value1;
                best2 = best1;

                value1 = value;
                best1 = i;
            }
            else if (value > value2)
            {
                value2 = value;
                best2 = i;
            }
        }

        if (best1 != -1)
            replace[best1] = 0;

        if (best2 != -1)
            replace[best2] = 0;
    }
}



void replaceCards(int deck[][FACES],
    int handRow[], int handCol[],
    int replace[], int* nextCard)
{
    for (int i = 0; i < HAND_SIZE; i++)
    {
        if (replace[i] == 1)
        {
            int found = 0;

            while (*nextCard <= SUITS * FACES && !found)
            {
                for (int row = 0; row < SUITS && !found; row++)
                {
                    for (int col = 0; col < FACES; col++)
                    {
                        if (deck[row][col] == *nextCard)
                        {
                            handRow[i] = row;
                            handCol[i] = col;
                            found = 1;
                            break;
                        }
                    }
                }

                (*nextCard)++;
            }
        }
    }
}




