C控制台游戏 - Eclipse CDT调试和发布是不同的

时间:2014-07-13 13:09:35

标签: c eclipse eclipse-cdt

我使用Eclipse CDT在C中创建了一个简单的控制台BlackJack游戏。 我有一个奇怪的问题,运行eclipse生成的DEBUG可执行文件,程序工作正常,如图所示:

-------
PLAYERS
-------
Player-1: (18) [ eight:spade, king:heart ]
>> (H)it/(C)heck: c

------
DEALER
------
Dealer: (21) [ king:diamond, ace:diamond ]

-------
RESULTS
-------
Player-1: Loss - 18 under dealer's 21.

但是,当我切换Eclipse以构建RELEASE而不是DEBUG时,生成的可执行文件如下:

-------
PLAYERS
-------
Player-1: (4) [ four:(null), (null):(null) ]
>> (H)it/(C)heck: h
Player-1: (4) [ four:(null), (null):(null), (null):(null) ]
>> (H)it/(C)heck: h
Player-1: (4) [ four:(null), (null):(null), (null):(null), (null):(null) ]
>> (H)it/(C)heck: c

------
DEALER
------
Dealer: (0) [ (null):(null), (null):(null) ]
Dealer: (0) [ (null):(null), (null):(null), (null):(null) ]
Dealer: (0) [ (null):(null), (null):(null), (null):(null), (null):(null) ]
...
...

我希望这更像是Eclipse / CDT / Build问题,但如果您需要查看源代码,请告诉我。我没有发布源代码,因为大约有15个以上的文件。

提前感谢您的帮助。

编辑:添加了源代码。

card.h

#ifndef CARD_H_
#define CARD_H_

/* The various ranks of a Card. */
enum Rank {
    ACE,
    TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN,
    JACK, QUEEN, KING
};

/* The various suits of a Card. */
enum Suit {
    CLUB, DIAMOND, HEART, SPADE
};

/* A structure which defines a Card. */
struct Card {
    enum Rank rank;
    enum Suit suit;
};

/*
 * Each possible Card rank contains two possible values. This structure can
 * be used to contain the two values.
 */
struct CardValue {
    int value1;
    int value2;
};

/* Creates a Card with a suit and a rank. */
struct Card create_card(const enum Rank rank, const enum Suit suit);

/* Takes a Rank enum and provides a string representation. */
char* rank_to_string(const enum Rank rank);

/*
 * Takes a Rank enum and provides a structure containing the rank's possible
 * values. Each Rank has two possible values, as the Ace is both 1 and 11.
 */
struct CardValue rank_to_value(const enum Rank rank);

/* Takes a Suit enum and provides a string representation. */
char* suit_to_string(const enum Suit suit);

/* Takes a Card structure and outputs its members as a string. */
char* card_to_string(const struct Card card);

#endif /* CARD_H_ */

card.c

#include "card.h"
#include <stdio.h>
#include <stdlib.h>

struct Card create_card(const enum Rank rank, const enum Suit suit)
{
    struct Card card;
    card.rank = rank;
    card.suit = suit;
    return card;
}

char* rank_to_string(const enum Rank rank)
{
    switch (rank) {
        case ACE: return "ace";
        case TWO: return "two";
        case THREE: return "three";
        case FOUR: return "four";
        case FIVE: return "five";
        case SIX: return "six";
        case SEVEN: return "seven";
        case EIGHT: return "eight";
        case NINE: return "nine";
        case TEN: return "ten";
        case JACK: return "jack";
        case QUEEN: return "queen";
        case KING: return "king";
    }
    return 0;
}

struct CardValue rank_to_value(const enum Rank rank)
{
    struct CardValue card_value;
    switch (rank) {
        case ACE:
            card_value.value1 = 1;
            card_value.value2 = 11;
            break;
        case TWO:
            card_value.value1 = 2;
            card_value.value2 = 2;
            break;
        case THREE:
            card_value.value1 = 3;
            card_value.value2 = 3;
            break;
        case FOUR:
            card_value.value1 = 4;
            card_value.value2 = 4;
            break;
        case FIVE:
            card_value.value1 = 5;
            card_value.value2 = 5;
            break;
        case SIX:
            card_value.value1 = 6;
            card_value.value2 = 6;
            break;
        case SEVEN:
            card_value.value1 = 7;
            card_value.value2 = 7;
            break;
        case EIGHT:
            card_value.value1 = 8;
            card_value.value2 = 8;
            break;
        case NINE:
            card_value.value1 = 9;
            card_value.value2 = 9;
            break;
        case TEN:
        case JACK:
        case QUEEN:
        case KING:
            card_value.value1 = 10;
            card_value.value2 = 10;
            break;
        default:
            card_value.value1 = 0;
            card_value.value2 = 0;
    }
    return card_value;
}

char* suit_to_string(const enum Suit suit)
{
    switch (suit) {
        case CLUB: return "club";
        case DIAMOND: return "diamond";
        case HEART: return "heart";
        case SPADE: return "spade";
    }
    return 0;
}

char* card_to_string(const struct Card card)
{
    size_t buffer_size = 15;
    char* output = malloc(sizeof(char) * buffer_size);
    snprintf(output, sizeof(char) * buffer_size, "%s:%s",
            rank_to_string(card.rank), suit_to_string(card.suit));
    return output;
}

hand.h

#ifndef HAND_H_
#define HAND_H_

#define BUSTED 21
#define MAX_HAND_SIZE 22

/*
 * Creates a structure representing a Hand of Cards. The 'cards' member is
 * an array of cards within the hand, and the 'index' member is the location
 * of the last inserted card.
 */
struct Hand {
    struct Card* cards;
    int index;
};

/* Creates a structure for a Hand of cards. */
struct Hand create_hand();

/* Adds a Card to a Hand. */
void add_card_to_hand(struct Hand* hand, const struct Card card);

/*
 * Finds the highest possible, non-busted value for a Hand of cards. If the
 * Hand is busted, the value will be greater than 21.
 */
int hand_to_value(const struct Hand hand);

/* A String representation of a Hand of cards. */
char* hand_to_string(const struct Hand hand);

#endif /* HAND_H_ */

hand.c

#include "hand.h"
#include "card.h"
#include <stdlib.h>
#include <string.h>

struct Hand create_hand()
{
    struct Hand hand;
    hand.cards = malloc(sizeof(struct Card) * MAX_HAND_SIZE);
    hand.index = 0;
    return hand;
}

void add_card_to_hand(struct Hand* hand, const struct Card card)
{
    /*
     * The 'index' member of the structure contains the incremented location
     * of the last inserted card.
     */
    hand->cards[hand->index] = card;
    hand->index++;
}

int hand_to_value(const struct Hand hand)
{
    /* Create a structure which holds the possible value combinations. */
    struct CardValue hand_value;
    hand_value.value1 = 0;
    hand_value.value2 = 0;

    /* Loop through each card in the hand and sum the possible totals. */
    int i;
    for (i = 0; i < hand.index; i++) {
        struct Card card = hand.cards[i];
        struct CardValue card_value = rank_to_value(card.rank);
        hand_value.value1 += card_value.value1;
        hand_value.value2 += card_value.value2;
    }

    /* If both totals are busted, return the lower of the 2. */
    if (hand_value.value1 > BUSTED && hand_value.value2 > BUSTED) {
        if (hand_value.value1 < hand_value.value2) {
            return hand_value.value1;
        } else {
            return hand_value.value2;
        }
    /* If the first total is busted, return the second total. */
    } else if (hand_value.value1 > BUSTED) {
        return hand_value.value2;
    /* If the second total is busted, return the first total. */
    } else if (hand_value.value2 > BUSTED) {
        return hand_value.value1;
    /* No totals are busted, return the highest of the two. */
    } else if (hand_value.value1 >= hand_value.value2) {
        return hand_value.value1;
    } else if (hand_value.value1 < hand_value.value2) {
        return hand_value.value2;
    }
    return 0;
}

char* hand_to_string(const struct Hand hand)
{
    /* Allocate memory for a string representation of the Hand. */
    size_t buffer_size = 500;
    char* output = malloc(sizeof(char) * buffer_size);
    memset(output, 0, buffer_size);

    /*
     * Concatenate the string representations of the cards to the string
     * representation of the Hand.
     */
    int i;
    strcat(output, "[ ");
    for (i = 0; i < hand.index; i++) {
        struct Card card = hand.cards[i];
        char* card_string = card_to_string(card);
        strcat(output, card_string);
        free(card_string);
        if (i + 1 < hand.index) {
            strcat(output, ", ");
        }
    }
    strcat(output, " ]\n");
    return output;
}

加入deck.h

#ifndef DECK_H_
#define DECK_H_

#define DECK_SIZE 52

/*
 * Creates a structure representing a Deck of Cards. The 'cards' member is
 * an array of cards within the deck, and the 'iterator' member is the location
 * of the last accessed card.
 */
struct Deck {
    struct Card* cards;
    int iterator;
    int number_of_decks;
};

/*
 * Creates a new Deck of cards. The 'number_of_decks' parameter dictates how
 * many 52-card decks will be generated in the Deck.
 */
struct Deck create_deck(const int number_of_decks);

/* Shuffles the cards within the Deck. */
void shuffle_deck(struct Deck* deck);

/*
 * Returns the next Card structure in the Deck, or NULL if the iterator has
 * reached the end of the Deck.
 */
struct Card* deck_next_card(struct Deck* deck);

#endif /* DECK_H_ */

deck.c

#include "deck.h"
#include "card.h"
#include <time.h>
#include <stddef.h>
#include <stdlib.h>

struct Deck create_deck(const int number_of_decks)
{
    /*
     * Allocate memory for a deck of cards, ensuring that the size of a deck,
     * as well as the number of decks are considered.
     */
    struct Deck deck;
    deck.iterator = 0;
    deck.number_of_decks = number_of_decks;
    int total_number_of_cards = (DECK_SIZE * number_of_decks);
    deck.cards = malloc(sizeof(struct Card) * total_number_of_cards);

    /*
     * For the amount of decks requested, create a card with each possible
     * rank and suit combination and add them to the deck. The loop_index will
     * be used to access each array member for the deck.
     */
    int deck_index;
    int suit_index;
    int rank_index;
    int loop_index = 0;
    for (deck_index = 0; deck_index < number_of_decks; deck_index++) {
        for (suit_index = CLUB; suit_index <= SPADE; suit_index++) {
            for (rank_index = ACE; rank_index <= KING; rank_index++) {
                struct Card card = create_card(rank_index, suit_index);
                deck.cards[loop_index] = card;
                loop_index++;
            }
        }
    }
    return deck;
}

void shuffle_deck(struct Deck* deck)
{
    /* Use the current time as the seed to our rand() function. */
    srand(time(0));

    /* Use the 'Fisher-Yates shuffle' algorithm. */
    int i;
    int total_number_of_cards = (DECK_SIZE * deck->number_of_decks);
    for (i = total_number_of_cards - 1; i > 0; i--)
    {
        int j = rand() % (i + 1);
        struct Card temp = deck->cards[j];
        deck->cards[j] = deck->cards[i];
        deck->cards[i] = temp;
    }
}

struct Card* deck_next_card(struct Deck* deck)
{
    /*
     * The 'iterator' member of the Deck contains the last accessed card.
     * Using this variable, we are able to traverse the Deck. If the iterator
     * is greater than the amount of cards there are in the deck, we
     * return NULL.
     */
    struct Card* next_card;
    if (deck->iterator < (DECK_SIZE * deck->number_of_decks)) {
        struct Card card = deck->cards[deck->iterator];
        deck->iterator++;
        next_card = &card;
    } else {
        next_card = NULL;
    }
    return next_card;
}

1 个答案:

答案 0 :(得分:1)

在阅读我自己的问题时,我偶然发现了答案。

问题在于deck.c文件,deck_next_card功能。我们可以看到next_card变量仅在函数范围内分配,而不是malloc'd

通过分配自己的内存,它可以在RELEASE:

中运行
struct Card* deck_next_card(struct Deck* deck)
{
    /*
     * The 'iterator' member of the Deck contains the last accessed card.
     * Using this variable, we are able to traverse the Deck. If the iterator
     * is greater than the amount of cards there are in the deck, we
     * return NULL.
     */
    struct Card* next_card = malloc(sizeof(struct Card)); # edit 1.
    if (deck->iterator < (DECK_SIZE * deck->number_of_decks)) {
        next_card = &deck->cards[deck->iterator]; # edit 2.
        deck->iterator++;
    } else {
        next_card = NULL;
    }
    return next_card;
}

让我失望的是它如何在DEBUG版本中完美运行,然后在RELEASE中没有。