我使用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;
}
答案 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中没有。