Определение покерной комбинации в пяти картах

Программа псевдослучайным образом выбирает из колоды в 54 карты (2–10, валет, дама, король, туз в мастях пики, трефы, бубны, червы + 2 джокера) пять карт и отображает свой выбор.

После этого определяется, есть ли в сданных картах одна из комбинаций:

(a) Пара: две карты одного значения;
(b) Сет: три карты одного значения;
(c) Флэш: пять карт одной масти

Исходный код на языке C
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

// Размер колоды
#define DECK_SIZE 54
// Количество карт у игрока
#define HAND_SIZE 5

// Валет
#define JACK 11
// Дама
#define QUEEN 12
// Король
#define KING 13
// Туз
#define ACE 14
// Джокер
#define JOKER 15


// Трефы
#define CLUB 1
// Пики
#define SPADE 2
// Черви
#define HEART 3
// Буби
#define DIAMOND 4

// Цвета для джокеров
// Черный
#define BLACK 5
// Красный
#define RED 6


typedef struct {
    // Карта
    unsigned short int value;
    // Масть
    unsigned short int lear;
} poker_card;


// Получить псевдо-случайное число
unsigned int get_pseudo_random_number(unsigned int begin, unsigned int end, int additional_entropy)
{
    // Временная энтропия для псевдо-рандома
    srand(time(NULL) * additional_entropy);
    return rand() % end + begin;
}

// Инициализация карточной колоды
void init_card_deck(poker_card deck[])
{
    int i, j;
    int x = 0;
    poker_card card;
    for (i = CLUB; i <= DIAMOND; i++) {
        for (j = 2; j <= ACE; j++) {
            card.lear = i;
            card.value = j;
            deck[x] = card;
            x++;
        }
    }
    // Добавление двух джокеров в колоду
    card.value = JOKER;
    card.lear = BLACK;
    deck[x] = card;
    x++;
    card.lear = RED;
    deck[x] = card;
}

// Раздать 5 случайных карт
void deal_the_cards(poker_card hand[], poker_card deck[], unsigned int hand_size)
{
    int i, x;
    for (i = 0; i < hand_size; i++) {
        x = get_pseudo_random_number(0, DECK_SIZE - 1, i + 1);
        hand[i] = deck[x];
    }
}

// Перевести масть в человеческий формат и вывести на экран
char* print_tr_card_lear(unsigned short int lear)
{
    char* s;
    switch(lear) {
        case CLUB:
            // черви
            s = "clubs"; 
            break;
        case SPADE:
            // пики
            s = "spades";
            break;
        case HEART:
            // черви
            s = "hearts";
            break;
        case DIAMOND:
            // бубны
            s = "diamonds";
            break;
        case BLACK:
            // черный джокер
            s = "black";
            break;
        case RED:
            // красный джокер
            s = "red";
            break;
        default:
            s = "";
            break;
    }
    printf("%s", s);
}

// Перевести номинал карты в человеческий формат и вывести на экран
void print_tr_card_value(unsigned short int value)
{
    char* s;
    if (value <= 10) {
        printf("%d", value);
    }
    switch (value) {
        case JACK:
            // валет
            s = "jack";
            break;
        case QUEEN:
            // дама
            s = "queen";
            break;
        case KING:
            // король
            s = "king";
            break;
        case ACE:
            // туз
            s = "ace";
            break;
        case JOKER:
            // джокер
            s = "joker";
            break;
        default:
            s = "";
            break;
    }
    printf("%s", s);
}

void sort_hand(poker_card hand[], unsigned int size)
{
    int i, j;
    poker_card sort_buf;
    for (j = 0; j < size - 1; j++) {
        for (i = 0; i < size - j - 1; i++) {
            if (hand[i].value > hand[i + 1].value) {
                sort_buf = hand[i];
                hand[i] = hand[i + 1];
                hand[i + 1] = sort_buf;
            }
        }
    }
}

void print_detected_combination(poker_card hand[], unsigned int size)
{
    // Количество карт одного значения
    int repeat_value = 1;
    // Количество карт одной масти
    int repeat_lear = 1;
    int i;

    for (i = 0; i < size - 1; i++) {
        if (hand[i].value == hand[i + 1].value || hand[i].value == JOKER || hand[i + 1].value == JOKER) {
            repeat_value++;
        }
        if (hand[i].lear == hand[i + 1].lear || hand[i].value == JOKER || hand[i + 1].value == JOKER) {
            repeat_lear++;
        }
    }

    if (repeat_value == 2) {
        // Пара
        printf("Pair detected!\n");
    } else if (repeat_value == 3) {
        // Сет
        printf("Set detected!\n");
    } else if (repeat_value == 4) {
        // Покер
        printf("Poker detected!\n");
    }
    // Флеш
    if (repeat_lear == size) {
        printf("Flash detected!\n");
    } else if (repeat_value < 2) {
        printf("No combinations detected...\n");
    }
}

// Перевести карту в человеческий формат и вывести на экран
void print_tr_card(poker_card card)
{
    print_tr_card_lear(card.lear);
    printf(" ");
    print_tr_card_value(card.value);
    printf("\n");
}


int main(int argc, char* argv[])
{
    poker_card deck[DECK_SIZE];
    init_card_deck(deck);

    // Карточная рука
    poker_card hand[5];
    // Раздать карты одному игроку
    deal_the_cards(hand, deck, HAND_SIZE);
    sort_hand(hand, HAND_SIZE);
    int i;
    for (i = 0; i < HAND_SIZE; i++) {
        print_tr_card(hand[i]);
    }
    printf("\nCombinations:\n");
    print_detected_combination(hand, HAND_SIZE);
    return 0;
}
Источник: code-live.ru