2014-07-13 51 views
1

我使用Eclipse CDT在C中創建了一個簡單的控制檯BlackJack遊戲。 我有一個奇怪的問題,即在運行日食產生的DEBUG可執行程序工作正常,如圖所示:C控制檯遊戲 - Eclipse CDT調試和發佈不同

------- 
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來構建的釋放,而不是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 /建造問題,但請讓我知道如果你需要查看源。由於有大約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

那麼沒有任何相關的代碼就很難說出任何東西。 –

+0

@JoachimPileborg我已經添加了相關文件的源代碼。 – Cristian

+0

順便說一句,當你運行調試版本時,你是否在調試器中運行它? –

回答

1

在閱讀過我自己的問題,我通過這個答案跌跌撞撞。

問題在於deck.c文件,deck_next_card函數。我們可以看到next_card變量只在該函數的範圍內被賦值,它並不是malloc'd

通過分配它自己的內存,它的工作原理版本中:

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沒有。

+0

這是[*未定義行爲*](http://en.wikipedia.org/wiki/Undefined_behavior)的問題,它可以在某些情況下工作,但在其他情況下不起作用。他們也可能很難找到。 –