2016-10-18 52 views
-1

我正在關注本書的編程項目C編程:現代方法我已將2個問題納入我的程序,但未能實現第三個尋找皇家同花順手。分類:撲克牌手[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

是的,但是''或'鏈表達式在編譯時被評估,並且鏈的結果成爲你的常量。所以無論你在哪裏使用'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]針對每個Aa等什麼是確實是進行邏輯或第一Aa,然後邏輯之間或與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");