【问题标题】:Why is my hand counter resetting itself to zero?为什么我的手动计数器会自动归零?
【发布时间】:2014-03-27 19:15:53
【问题描述】:

我正在使用 ANSI C C90 标准在 GCC 中创建一个小型应用程序。

我的头文件:

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

#define DECKSZ 52
#define HAND_SIZE 5

#define STACKMAX 52
#define EMPTY -1
#define FULL (STACKMAX-1)

typedef enum boolean {false, true} boolean;

typedef struct card {
    enum pip {ACE=1, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING} pips;
    enum suit {SPADES, CLUBS, HEARTS, DIAMONDS} suits;
    char cardName[20];
} card;

typedef struct stack {
    card s[STACKMAX];
    int top;
} stack;

extern card deck[];

void initDeck(card[]);
void shuffleDeck(card[]);
void displayHand(card*);
void arrangeHand(card*);
void swap(card*, card*);
boolean isFlush(card[]);
boolean isStraight(card[]);
boolean isXOfAKind(card[], int, enum pip);
boolean isStraightFlush(card[]);
boolean isFullHouse(card[]);
boolean isTwoPair(card[]);
boolean isEmpty(stack*);
boolean isFull(stack*);
void push(card, stack*);
card pop(stack*);
void reset(stack*);

我的主文件:

#include "Poker.h"

int main(void) {

    int i, j;
    int numHands = 0;
    int flushCount = 0;
    int straightCount = 0;
    int xOfAKindCount = 0;
    int straightFlushCount = 0;
    int fullHouseCount = 0;
    int isTwoPairCount = 0;

    card deck[DECKSZ] = {0};
    card hand[HAND_SIZE] = {0};

    stack deckStack = {0};
    stack handStack = {0};

    initDeck(deck);
    shuffleDeck(deck);
    reset(&deckStack);

    for (i = 0; i < DECKSZ; i++) {
        push(deck[i], &deckStack);
    }

    do {
        numHands += 1;
        reset(&handStack);
        for (i = 0; i < HAND_SIZE; i++) {
            push(pop(&deckStack), &handStack);
            if (isEmpty(&deckStack)) {
                reset(&handStack);
                i = HAND_SIZE;
                shuffleDeck(deck);
                reset(&deckStack);
                numHands -= 1;
                for (j = 0; j < DECKSZ; j++) {
                    push(deck[j], &deckStack);
                }
            }
            hand[i] = handStack.s[i];
        }

        arrangeHand(hand);
        /*displayHand(hand);*/

        flushCount += isFlush(hand);
        straightCount += isStraight(hand);
        xOfAKindCount += isXOfAKind(hand, 2, 0);
        straightFlushCount += isStraightFlush(hand);
        fullHouseCount += isFullHouse(hand);
        isTwoPairCount += isTwoPair(hand);

        printf("Flushes:%d Straights:%d SF's:%d Number of Hands:%d\r",
            flushCount, straightCount, straightFlushCount, numHands);
    } while (1);

    printf("\n");

    return EXIT_SUCCESS;
}

void initDeck(card deck[]) {
    int i;
    for (i = 0; i < DECKSZ; i++) {
        deck[i].pips = (const)((i % 13) + 1);
        deck[i].suits = (const)(i / 13);
    }
}

void shuffleDeck(card deck[]) {
    int i, j;
    for (i = 0; i < DECKSZ; i++) {
        j = rand() % DECKSZ;
        swap(&deck[i], &deck[j]);
    }
}

void displayHand(card hand[]) {
    int i, tmpPip = 0, tmpSuit = 0;
    const char *pipNames[] = {"Ace","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten","Jack","Queen","King"};
    const char *suitNames[] = {" of Spades"," of Hearts"," of Diamonds"," of Clubs"};
    for (i = 0; i < HAND_SIZE; i++) {
        tmpPip = (hand[i].pips) - 1;
        tmpSuit = (hand[i].suits);
        strcpy(hand[i].cardName, pipNames[tmpPip]);
        strcat(hand[i].cardName, suitNames[tmpSuit]);
        printf("%s\n", hand[i].cardName);
    }
}

void arrangeHand(card *hand) {
    int i, j;
    for (i = HAND_SIZE-1; i >= 0; i--) {
        for (j = 0; j < i; j++) {
            if ((hand+j)->pips > (hand+j+1)->pips)
                swap(hand+j, hand+j+1);
        }
    }
}

void swap(card *c1, card *c2) {
    card temp;
    temp = *c1;
    *c1 = *c2;
    *c2 = temp;
}

boolean isFlush(card hand[]) {
    int i, count = 0, result = 0;
    for (i = 0; i < HAND_SIZE-1; i++) {
        if (hand[i].suits != hand[i+1].suits) {
            count++;
        }
    }
    if (count == HAND_SIZE)
        result = 1;
    return ((boolean) (result));
}

boolean isStraight(card hand[]) {
    int i, count = 0, result = 0;
    for (i = 0; i < HAND_SIZE - 1; i++) {
        if (hand[i].pips == (hand[i+1].pips + 1)) {
            count++;
        }
    }
    if (count == HAND_SIZE)
        result = 1;
    return ((boolean) (result));
}

boolean isXOfAKind(card hand[], int x, enum pip pipsIgnored) {
    int i, count = 0, result = 0;
    for (i = 0; i < HAND_SIZE - 1; i++) {
        if (hand[i].pips == hand[i+1].pips) {
            if (hand[i].pips != pipsIgnored) {
                count++;
            }
        }
    }
    if (count == (x - 1))
        result = 1;
    return count;
}

boolean isStraightFlush(card hand[]) {
    int result = 0;
    result = isFlush(hand);
    result = isStraight(hand);
    return ((boolean) (result));
}

boolean isFullHouse(card hand[]) {
    int result = 0;
    result = isXOfAKind(hand, 3, 0);
    result = isXOfAKind(hand, 2, 0);
    return ((boolean) (result));
}

boolean isTwoPair(card hand[]) {
    int result = 0;
    result = isXOfAKind(hand, 2, hand->pips);
    result = isXOfAKind(hand, 2, hand->pips);
    return ((boolean) (result));
}

boolean isEmpty(stack *stk) {
    return ((boolean) (stk->top == EMPTY));
}

boolean isFull(stack *stk) {
    return ((boolean) (stk->top == FULL));
}

void push(card c, stack *stk) {
    stk->top++;
    stk->s[stk -> top] = c;
}

card pop(stack *stk) {
    return (stk->s[stk->top--]);
}

void reset(stack *stk) {
    stk->top = EMPTY;
}

我的问题是关于我的 main() 函数中的变量 numHands。每次我在甲板堆栈上调用 reset() 时,它似乎都会将自身重置为零。我根本不希望它重置。有谁知道它为什么重置为零,以及如何让它不重置?谢谢!

【问题讨论】:

  • 您的代码中有numHands -= 1; 语句。该语句似乎是唯一一个numHands 可以更改为零(在循环中)的语句。调试您的程序,特别注意该行(或在减量之前放置printf("numHands: %d\n", numHands);)。同时编译时启用 ALL 警告 (clang -Weverything ...) 并注意这些警告。
  • 我在主文件中收到missing initializer 警告,其中包含以下代码行:card deck[DECKSZ] = {0};card hand[HAND_SIZE] = {0};stack deckStack = {0};stack handStack = {0};。我唯一的其他警告是因为我没有在我的struct card... 中明确给出enum pip...enum suit
  • 而对于numHands,当我在递减之前打印它的值时,它的值是11,但是下次我打印flushCountstraightCount它的值是@987654340 @...
  • +1 表示(不是这样)SSCCE 问题。

标签: c variables loops iteration poker


【解决方案1】:

在这里,您通过访问hand 的越界元素来触发未定义行为

        for (i = 0; i < HAND_SIZE; i++) {
            push(pop(&deckStack), &handStack);
            if (isEmpty(&deckStack)) {
                reset(&handStack);
                i = HAND_SIZE;                     /* <== set i to 5 */
                shuffleDeck(deck);
                reset(&deckStack);
                numHands -= 1;
                for (j = 0; j < DECKSZ; j++) {
                    push(deck[j], &deckStack);
                }
            }
            hand[i] = handStack.s[i];             /* <== illegal hand[5] */
        }

我怀疑在您之前运行程序时,由无效访问触发的未定义行为改变了numHands 的值。今天它可能会做一些不同的事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-02
    • 1970-01-01
    • 2013-01-14
    • 1970-01-01
    • 1970-01-01
    • 2017-03-31
    • 2016-07-20
    • 2013-11-25
    相关资源
    最近更新 更多