分类扑克手[皇家冲洗失败]

时间:2016-10-18 16:59:58

标签: c c99 poker

我正在阅读 C编程:现代方法一书中的编程项目,并且我已将2个问题纳入我的程序但未能达到第3个就是找到皇家同花顺的手。

这是我到目前为止所做的:

/* 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 个答案:

答案 0 :(得分:3)

此:

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之间首先执行逻辑OR,然后执行该结果与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");