2016-10-18 9 views
-1

Я следил за проектами программирования из книги C программирование: современный подход, и я включил 2 вопроса в свою программу, но не смог достичь 3-го, а именно, чтобы найти королевский флеш рука.Классификация рук в покере [ROYAL FLUSH IS FAILING]

Это то, что я сделал до сих пор:

/* Classifies a poker hand */ 

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

#define NUM_RANKS 13 
#define NUM_SUITS 4 
#define NUM_CARDS 5 
#define ROYAL_FLUSH ('A' || 'a' || 'K' || 'k' || 'Q' || 'q' || 'J' || 'j' || 'T' || 't') 
#define ACE_LOW (('A' || 'a') && '2' && '3' && '4' && '5') 

/* external variables */ 
/* int ROYAL_FLUSH[8, 9, 10, 11, 12] 
int num_in_rank[NUM_RANKS]; 
int num_in_suit[NUM_SUITS]; */ 
bool royal_flush, ace_low, straight, flush, four, three; 
int pairs; /* can be 0, 1 or 2 */ 

/* Prototypes */ 
int read_cards(int num_in_rank[NUM_RANKS], int num_in_suit[NUM_SUITS]); 
int analyze_hand(int num_in_rank[NUM_RANKS], int num_in_suit[NUM_SUITS]); 
void print_result(void); 


int main(void) 
{ 

    int num_in_rank[NUM_RANKS]; 
    int num_in_suit[NUM_SUITS]; 
    for(;;) { 
    read_cards(num_in_rank, num_in_suit); 
    analyze_hand(num_in_rank, num_in_suit); 
    print_result(); 
    } 
} 

int read_cards(int num_in_rank[NUM_RANKS], int num_in_suit[NUM_SUITS]) 
{ 

    bool card_exists[NUM_RANKS][NUM_SUITS]; 
    char ch, rank_ch, suit_ch; 
    int rank, suit; 
    bool bad_card; 
    int cards_read = 0; 

    for (rank = 0; rank < NUM_RANKS; rank++) { 
    num_in_rank[rank] = 0; 
    for (suit = 0; suit < NUM_SUITS; suit++) 
     card_exists[rank][suit] = false; 
    } 

    for (suit = 0; suit < NUM_SUITS; suit++) 
    num_in_suit[suit] = 0; 

    while (cards_read < NUM_CARDS) { 
    bad_card = false; 

    printf("Enter a card: "); 

    rank_ch = getchar(); 
    switch (rank_ch) { 
    case '0': exit(EXIT_SUCCESS); 
    case '2': rank = 0; break; 
    case '3': rank = 1; break; 
    case '4': rank = 2; break; 
    case '5': rank = 3; break; 
    case '6': rank = 4; break; 
    case '7': rank = 5; break; 
    case '8': rank = 6; break; 
    case '9': rank = 7; break; 
    case 't': case 'T': rank = 8; break; 
    case 'j': case 'J': rank = 9; break; 
    case 'q': case 'Q': rank = 10; break; 
    case 'k': case 'K': rank = 11; break; 
    case 'a': case 'A': rank = 12; break; 
    default: bad_card = true; 
    } 

    suit_ch = getchar(); 
    switch (suit_ch) { 
    case 'c': case 'C': suit = 0; break; 
    case 'd': case 'D': suit = 1; break; 
    case 'h': case 'H': suit = 2; break; 
    case 's': case 'S': suit = 3; break; 
    default: bad_card = true; 
    } 

    while ((ch = getchar()) != '\n') 
     if (ch != ' ') bad_card = true; 

    if (bad_card) 
     printf("Bad card; ignored.\n"); 
    else if (card_exists[rank][suit]) 
     printf("Duplicate card; ignored.\n"); 
    else { 
     num_in_rank[rank]++; 
     num_in_suit[suit]++; 
     card_exists[rank][suit] = true; 
     cards_read++; 
    } 
    } 
    return 0; 
} 

int analyze_hand(int num_in_rank[NUM_RANKS], int num_in_suit[NUM_SUITS]) 
{ 

    int num_consec = 0; 
    int rank, suit; 

    royal_flush = false; 
    straight = false; 
    ace_low = false; 
    flush = false; 
    four = false; 
    three = false; 
    pairs = 0; 


    /*check for royal flush */ 
    /* int arr[5] = {8, 9, 10, 11, 12}; 
    int i; */ 
    if (flush) 
    for (rank = 0; rank < NUM_RANKS; rank++) 
     if (num_in_rank[rank] == ROYAL_FLUSH) 
      continue; 
     else 
      break; 

    royal_flush = true; 


    /* check for flush */ 

    for (suit = 0; suit < NUM_SUITS; suit++) 
    if (num_in_suit[suit] == NUM_CARDS) 
     flush = true; 

/* check for ace-low straight */ 

    for (rank = 0; rank < NUM_RANKS; rank++) 
    if (num_in_rank[rank] == ACE_LOW) 
     ace_low = true; 

    /* check for straight */ 

    rank = 0; 
    while (num_in_rank[rank] == 0) rank++; 
    for (; rank < NUM_RANKS && num_in_rank[rank] > 0; rank++) 
    num_consec++; 
    if (num_consec == NUM_CARDS) { 
    straight = true; 
    return 0; 
    } 

    /* check for 4 of a kind, 3 of a kind and pairs */ 

    for (rank = 0; rank < NUM_RANKS; rank++) { 
    if (num_in_rank[rank] == 4) 
     four = true; 
    if (num_in_rank[rank] == 3) 
     three = true; 
    if (num_in_rank[rank] == 2) 
     pairs++; 
    } 
    return 0; 
} 

void print_result(void) 
{ 

    if (royal_flush && flush && straight) 
    printf("\nRoyal Flush"); 
    else if (straight && flush && royal_flush == false) 
    printf("\nStraight Flush"); 
    else if (four) 
    printf("\nFour of a kind"); 
    else if (three && pairs == 1) 
    printf("\nFull House"); 
    else if (flush) 
    printf("\nFlush"); 
    else if (straight) 
    printf("\nStraight"); 
    else if (ace_low) 
    printf("\nAce-low straight"); 
    else if (three) 
    printf("\nThree of a kind"); 
    else if (pairs == 2) 
    printf("\nTwo Pairs"); 
    else if (pairs == 1) 
    printf("\nPair"); 
    else 
    printf("\nHigh card"); 

printf("\n\n"); 

} 

Мой код печатает Royal Flush когда введенные карты не являются даже королевские флеш-карты, но на самом деле флеш-карты.

Я новичок в c, поэтому, пожалуйста, пройдите по критике.

Язык: c99; Компилятор: GCC

+1

что именно вы думаете '' A '||' a '||' K'etc ... 'на самом деле будет оцениваться? –

+0

Я думал, так как я уже проверял костюмы, называя 'flush', было правдой, тогда все, что мне нужно проверить, - это ранг карт, которые я определил вручную. –

+0

Да, но это выражение 'или' chain вычисляется во время компиляции, и РЕЗУЛЬТАТ цепочки становится вашей константой. поэтому везде, где вы используете определение ROYAL_FLUSH', вы не «вставляете» '' A '||' a'etc..' в код для оценки, вы вставляете значение, которое было оценено ONCE во время компиляции. –

ответ

2

Это:

if (num_in_rank[rank] == ROYAL_FLUSH) 

, который так же, как это:

if (num_in_rank[rank] == ('A' || 'a' || 'K' || 'k' || 'Q' || 'q' || 'J' || 'j' || 'T' || 't')) 

Не делать то, что вы думаете, что он делает. Это не сравнить num_in_rank[rank] против каждого из A, a и т.д. Что делает это выполнить логическое ИЛИ между первым A и a, то логическое ИЛИ этого результата с K и т.д.

Вам нужно сравнить переменную против каждого из них индивидуально.

Вы можете сделать это:

if ((num_in_rank[rank] == 'A') || (num_in_rank[rank] == 'a') || ... 

Или это:

char in_royal[] = { 'A', 'a', ... }; 

for (i=0;i<sizeof(in_royal);i++) { 
    if (num_in_rank[rank] == in_royal[i]) { 
     ... 

Там также проблема с тем, как это выложено:

if (flush) 
    for (rank = 0; rank < NUM_RANKS; rank++) 
     if (num_in_rank[rank] == ROYAL_FLUSH) 
      continue; 
     else 
      break; 

    royal_flush = true; 

Последняя строка находится вне блок if, и вы не будете записывать интересующий вас случай. Убедитесь в том, чтобы использовать фигурные скобки:

if (flush) { 
    royal_flush = true; 
    for (rank = 0; rank < NUM_RANKS; rank++) { 
     if ((num_in_rank[rank] == 'A') || (num_in_rank[rank] == 'a') || ...) { 
      continue; 
     } else { 
      royal_flush = false; 
      break; 
     } 
    } 
    } 

Как улучшение, а не проверки всех карт флеш-рояль в отдельности, просто проверить тузом. Это вместе с отдельными проверками на прямую и флеш (которые в настоящее время не находятся в вашем коде) будут фиксировать это. Тогда вы можете сделать это:

if (straight && flush && has_ace) 
    printf("\nRoyal Flush"); 

 Смежные вопросы

  • Нет связанных вопросов^_^