2016-06-17 13 views
0

これをデバッグしようとしている数時間と多くのコーヒーを飲んだ後、私も私の友人は何がうまくいかないのかを理解することができます。機能が一貫して正しい出力を出力しない

Cで書かれた小さなカードゲームで、Cardを持つリンクされたリストを使用して、DeckHandに入っています。 main()で私はHandの2人のプレイヤーを印刷し、Handからランダムなカードを出してDeckの最後に置くループを持っています。これを行うには、私は関数playCard()を持っています。

問題は、プレーヤーのHandに存在しないCardが印刷されています。私はCardDeckに存在しなければならないと想像することができますが、なぜそれが印刷されているのか分かりません。私はまた、リストの最後にNULLがあり、これが起こったようなことを止めることを保証しました。

ここで間違っていることを知っている人はいますか?

は、ここに私のコードです:

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

typedef struct CARD Card; 

struct CARD 
{ 
    int value; 
    int id; 
    Card *next_card; 
}; 

typedef struct Deck 
{ 
    int size; 
    Card *cards; 
}Deck; 

typedef struct Hand 
{ 
    int size; 
    Card *cards; 
}Hand; 


Card* createCard(); 
Deck* createDeck(); 
Hand* createHand(); 
int addCard(Card* card, Deck* deck); 
int cardExists(int id, Deck* deck); 
int cardExistsC(Card* card, Deck* deck); 
void shuffle(Deck* deck); 
int fillHand(int size, Hand* hand, Deck* deck); 
void showHand(Hand* hand); 
int playCard(int id, Hand* hand, Deck* deck); 


int main(int argc, char** argv) 
{ 
    // Initialise seed for random number generator 
    srand(time(NULL)); 
    int playable = 1; 

    Deck* deck = createDeck(); 
    Hand* player1 = createHand(); 
    Hand* player2 = createHand(); 

    if (deck == NULL || player1 == NULL || player2 == NULL) 
    { 
     if (deck != NULL) 
      free(deck); 
     if (player1 != NULL) 
      free(player1); 
     if (player2 != NULL) 
      free(player2); 
     playable = 0; 
    } 

    if (!playable) 
    { 
     return -1; 
    } 
    else 
    { 
     int i = 0; 
     for (i = 0; i < 52; i++) 
     { 
      Card* temp = createCard(); 
      addCard(temp, deck); 
     } 

     shuffle(deck); 

     fillHand(7, player1, deck); 
     fillHand(7, player2, deck); 

     for (i = 0; i < 7; i++) 
     { 
      showHand(player1); 
      showHand(player2); 

      playCard(-1, player1, deck); 
      playCard(-1, player2, deck); 
     } 

     free(deck); 
     free(player1); 
     free(player2); 
    } 

    return 0; 
} 


// Create a new card generating a random ID (0-10,000)and value from 0-10 
Card* createCard() 
{ 
    Card* card = NULL; 
    card = (Card*)malloc(sizeof(Card)); 
    card->id = rand() % 10000; 
    card->value = rand() % 10; 
    card->next_card = NULL; 
    return card; 
} 

// Creates a new deck and sets the size to 0, creates a list within the deck 
Deck* createDeck() 
{ 
    Deck* deck = NULL; 
    deck = (Deck*)malloc(sizeof(Deck)); 
    deck->size = 0; 
    deck->cards = NULL; 
    return deck; 
} 

// Creates a new hand and sets the size to 0, creates a list within the hand 
Hand* createHand() 
{ 
    Hand* hand = NULL; 
    hand = (Hand*)malloc(sizeof(Hand)); 
    hand->size = 0; 
    hand->cards = NULL; 
    return hand; 
} 

// Adds a created card to a deck, returns 1 if card was added, 0 if card wasn't, -1 if a duplicate id was detected 
int addCard(Card* card, Deck* deck) 
{ 
    // If the deck or the card is not initialised, the card cannot be added 
    if (deck == NULL || card == NULL) return 0; 

    // If deck size 0, this must be the first card 
    if (deck->size == 0) 
    { 
     // Add the card and increment the deck size 
     deck->cards = card; 
     deck->size++; 

     // Check if the card was added successfully 
     if (cardExists(card->id, deck) == 1 || cardExistsC(card, deck) == 1) return 1; 

     // Returns 0 if card check failed 
     return 0; 
    } 

    // If deck contains at least a card, then add it to the end of the List of cards 
    if (deck->size > 0) 
    { 
     // First check if a duplicate ID exists 
     if (cardExists(card->id, deck) == 1 || cardExistsC(card, deck) == 1) return -1; 

     // Traverse to the last card and add the new card 
     Card *p = deck->cards; 
     while (p->next_card != NULL) 
     { 
      p = p->next_card; 
     } 
     p->next_card = card; 
     deck->size++; 

     // Check if the card was added successfully 
     if (cardExists(card->id, deck) == 1 || cardExistsC(card, deck) == 1) return 1; 
    } 

    // If nothing runs successfully, return 0 
    return 0; 
} 

// Determines if a card exists within a deck given an id or a card* returns 1, otherwise 0 
int cardExists(int id, Deck* deck) 
{ 
    // If deck is not initialised, return 0 
    if (deck == NULL) return 0; 

    // Traverse through the cards checking if the id matches any of the current cards 
    Card *p = deck->cards; 
    if (p->id == id) return 1; // Check if id matches the first card 
    while (p->next_card != NULL) 
    { 
     p = p->next_card; // Move on to the next_card 
     if (p->id == id) return 1; // If id matches, return 1 
    } 

    // No duplicate cards return 0 
    return 0; 
} 

int cardExistsC(Card* card, Deck* deck) 
{ 
    // If deck is not initialised, return 
    if (deck == NULL || card == NULL) return 0; 

    // Traverse through the cards checking if the card matches any of the current cards 
    Card *p = deck->cards; 
    while (p->next_card != NULL) 
    { 
     if (p == card) return 1; // If id matches, return 1 
     p = p->next_card; // Else move on to the next_card 
    } 

    // No duplicate cards return 0 
    return 0; 
} 

// Shuffles deck - size*100 randoms swaps, or a shuffling algorithm 
void shuffle(Deck* deck) 
{ 
    // If deck is not initialised, return 
    if (deck == NULL) return; 

    // Declare vars for use 
    int d, i, j, x, r1, r2; 
    Card *o = deck->cards; // The List of cards 
    Card *p1, *p2, *t; // Temp cards 
    d = deck->size; // Deck size 
    i = 0; // Loop var 
    j = d * 100; // Amount of swaps needed 
    x = 0; // Inner loop var 

      // Initialise pointers 
    p1 = NULL; 
    p2 = NULL; 
    t = NULL; 

    // Swaps two cards while less than amount of reqired swaps 
    while (i < j) 
    { 
     // Create two random numbers 
     r1 = rand() % d; 
     r2 = rand() % d; 

     // Traverse through the List od cards in the deck r1 and r2 number of times 
     while (x <= r1 || x <= r2 && o->next_card != NULL) 
     { 
      if (x == r1) p1 = o; // p1 == o when x == r1 
      if (x == r2) p2 = o; // p2 == o when x == r2 
      o = o->next_card; 
      x++; 
     } 

     // Hold p1 in t 
     t = p1; 
     // Replace p1 with p2 
     p1->id = p2->id; 
     p1->value = p2->value; 
     // Replace p2 with t 
     p2->id = t->id; 
     p2->value = t->value; 

     i++; 
    } 
} 

// Moves the top x cards of the deck to the hand structure returns hand size 
int fillHand(int size, Hand* hand, Deck* deck) 
{ 
    // If deck and hand is not initialised or size less than 0, return 
    if (deck == NULL || !(size >= 0)) return 0; 

    // Initialise vars for use 
    Card *h = hand->cards; 
    Card *d = deck->cards; 
    int x = 1; 

    // Make h == d 
    h = d; 
    // Start the hand here 
    hand->cards = h; 

    // Traverse 'size' amount through the hand and deck 
    while (x < size && h->next_card != NULL && d->next_card != NULL) 
    { 
     h = h->next_card; 
     d = d->next_card; 
     x++; 
    } 
    // Update hand->size 
    hand->size = x; 
    // Move the card after the new hand list up to be the new top of deck 
    deck->cards = d->next_card; 
    deck->size = deck->size - x; 
    // End the hand here 
    h->next_card = NULL; 
    return hand->size; 
} 

// prints the hand to the console showing ID and value, one card per line in the format ###\tID-Value 
void showHand(Hand* hand) 
{ 
    // If hand is not initialised, return 
    if (hand == NULL) return; 

    // Declare vars for use 
    int val, id; 
    Card *p = hand->cards; 
    // Traverse through the List of Cards printing each one's value and id 
    while (p->next_card != NULL) 
    { 
     val = p->value; 
     id = p->id; 
     printf("###\t %d-%d\n", id, val); 
     p = p->next_card; 
    } 
    printf("\n"); 
} 

// Removes the card from hand and displays the card ID and Value in the format ***ID-Value, a value of -1 in id indicates a random card, returns played card id 
int playCard(int id, Hand* hand, Deck* deck) 
{ 
    // If hand is not initialised, return 
    if (hand == NULL || deck == NULL) return 0; 

    // Setup vars for use 
    Card *d, *h, *p; 
    int i, cid, cval; 
    d = deck->cards; 
    h = hand->cards; 
    p = h; 
    i = 0; 

    // If card is to be randomly chosen 
    if (id == -1) 
    { 
     i = rand() % hand->size; // Get a random number 
     i++; 
     while (i > 0 && h->next_card != NULL) // Move i times through the list 
     { 
      p = h; // make p == current card so it becomes the previous card 
      h = h->next_card; // Move to the next card 
      i--; // Decrement i 
     } 

     // Go to end of the deck 
     while (d->next_card != NULL) 
     { 
      d = d->next_card; 
     } 

     // Get card data 
     cid = h->id; 
     cval = h->value; 
     // Print the card data 
     printf("***%d-%d\n\n", cid, cval); 

     // Put the randomly chosen card from the hand to the end of deck 
     d->next_card = h; 
     // Remove the card from hand 
     p->next_card = h->next_card; 
     // Move to the card added to the deck 
     d = d->next_card; 
     // Ensure the end card is the last in the list 
     d->next_card = NULL; 
     // Increment deck size 
     deck->size++; 
     // Decrement hand size 
     hand->size--; 
     return -1; 
    } 
    else 
    { 
     // Go to end of the deck 
     while (d->next_card != NULL) 
     { 
      d = d->next_card; 
     } 

     // Get card data 
     cid = h->id; 
     cval = h->value; 
     // Print the card data 
     printf("***%d-%d\n\n", cid, cval); 

     // Put the randomly chosen card from the hand to the end of deck 
     d->next_card = h; 
     // Remove the card from hand and make the following card the new head of the list 
     hand->cards = h->next_card; 
     // Move to the card added to the deck 
     d = d->next_card; 
     // Ensure the end card is the last in the list 
     d->next_card = NULL; 
     // Increment deck size 
     deck->size++; 
     // Decrement hand size 
     hand->size--; 
     return cid; 
    } 
} 
+0

'main'および任意の他の機能を追加してください。入力。 [ask]と[mcve]を参照してください。 –

+0

リンクされたリストは扱いにくく、エラーが発生する可能性があります。リンクされたリストのコードをゲームロジックから分離するのが最善です。例えば、項目に 'n'を見つけ、それをリストから切り離し、項目へのポインタを返す一般的な' extractItemAtPosition(int n) '関数を書いてください。その後、ゲームロジックは、1行のコードでプレーヤーの手札からカードを受け取ることができます。 – user3386109

+1

'deck =(Deck *)malloc((sizeof(Card)* 52)+ sizeof(Deck));'構造体に52枚のカードの配列が含まれていません。あふれている構造体でトリックをしていますか?リンクされたリストがどのように実装されているかのようには見えません。 –

答えて

2

いくつかのバグがリンクされたリストにアクセスするためのループの一部でありました。

Shuffleに重複カードが生成されるという明確なバグがありました。

私はplayCardにザッとチェックを行なったし、それは私が他のバグの一部を固定した後、私は間違いなく、異なる出力(注取得

大丈夫になります。私はそのようsrandが固定値を使用するように変更をあなたのバージョンと私の比較が機能します)

-Wallコンパイラオプションでは、whileループの1つにあいまいなフラグが付きます。私はそれに注釈をつけて、私がと思っているものに基づいてかっこを付けました。

その他のバグがあるかもしれませんが、私が見つけたものに注釈を付けました。 [可能な場合]私は次のように使用していることに注意してください:

// NOTE/BUG: ... 
#if 0 
// original code 
#else 
// fixed code 
#endif 

はとにかく、ここで変更されたコードは、[無償スタイルのクリーンアップをご容赦ください]です。

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

typedef struct CARD Card; 

struct CARD { 
    int value; 
    int id; 
    Card *next_card; 
}; 

typedef struct Deck { 
    int size; 
    Card *cards; 
} Deck; 

typedef struct Hand { 
    int size; 
    Card *cards; 
} Hand; 

Card *createCard(); 
Deck *createDeck(); 
Hand *createHand(); 
int addCard(Card *card, Deck *deck); 
int cardExists(int id, Deck *deck); 
int cardExistsC(Card *card, Deck *deck); 
void shuffle(Deck *deck); 
int fillHand(int size, Hand *hand, Deck *deck); 
void showHand(Hand *hand); 
int playCard(int id, Hand *hand, Deck *deck); 

int 
main(int argc, char **argv) 
{ 
    // Initialise seed for random number generator 
    srand(3); 
    int playable = 1; 

    Deck *deck = createDeck(); 
    Hand *player1 = createHand(); 
    Hand *player2 = createHand(); 

    if (deck == NULL || player1 == NULL || player2 == NULL) { 
     if (deck != NULL) 
      free(deck); 
     if (player1 != NULL) 
      free(player1); 
     if (player2 != NULL) 
      free(player2); 
     playable = 0; 
    } 

    if (!playable) { 
     return -1; 
    } 

    int i = 0; 

    // NOTE/BUG: does not fill deck if a duplicate is found (i.e. ignores 
    // addCard return) 
#if 0 
    for (i = 0; i < 52; i++) { 
     Card *temp = createCard(); 
     addCard(temp, deck); 
    } 
#else 
    for (i = 0; i < 52; i++) { 
     while (1) { 
      Card *temp = createCard(); 
      if (addCard(temp, deck) > 0) 
       break; 
      printf("DUPLICATE createCard\n"); 
     } 
    } 
#endif 

    shuffle(deck); 

    fillHand(7, player1, deck); 
    fillHand(7, player2, deck); 

    for (i = 0; i < 7; i++) { 
     showHand(player1); 
     showHand(player2); 

     playCard(-1, player1, deck); 
     playCard(-1, player2, deck); 
    } 

    free(deck); 
    free(player1); 
    free(player2); 

    return 0; 
} 

// Create a new card generating a random ID (0-10,000)and value from 0-10 
Card * 
createCard() 
{ 
    Card *card = NULL; 

    card = (Card *) malloc(sizeof(Card)); 
    card->id = rand() % 10000; 
    card->value = rand() % 10; 
    card->next_card = NULL; 
    return card; 
} 

// Creates a new deck and sets the size to 0, creates a list within the deck 
Deck * 
createDeck() 
{ 
    Deck *deck = NULL; 

    deck = (Deck *) malloc(sizeof(Deck)); 
    deck->size = 0; 
    deck->cards = NULL; 
    return deck; 
} 

// Creates a new hand and sets the size to 0, creates a list within the hand 
Hand * 
createHand() 
{ 
    Hand *hand = NULL; 

    hand = (Hand *) malloc(sizeof(Hand)); 
    hand->size = 0; 
    hand->cards = NULL; 
    return hand; 
} 

// Adds a created card to a deck, returns 1 if card was added, 0 if card wasn't, -1 if a duplicate id was detected 
int 
addCard(Card *card, Deck *deck) 
{ 
    // If the deck or the card is not initialised, the card cannot be added 
    if (deck == NULL || card == NULL) 
     return 0; 

    // If deck size 0, this must be the first card 
    if (deck->size == 0) { 
     // Add the card and increment the deck size 
     deck->cards = card; 
     deck->size++; 

     // Check if the card was added successfully 
     // NOTE/BUG: superfluous check -- this will always return 1 
     if (cardExists(card->id, deck) == 1 || cardExistsC(card, deck) == 1) 
      return 1; 

     // Returns 0 if card check failed 
     // NOTE/BUG: otherwise, this is _fatal_ 
     return 0; 
    } 

    // If deck contains at least a card, then add it to the end of the List of cards 
    if (deck->size > 0) { 
     // First check if a duplicate ID exists 
     if (cardExists(card->id, deck) == 1 || cardExistsC(card, deck) == 1) 
      return -1; 

     // Traverse to the last card and add the new card 
     Card *p = deck->cards; 

     while (p->next_card != NULL) { 
      p = p->next_card; 
     } 
     p->next_card = card; 
     deck->size++; 

     // Check if the card was added successfully 
     if (cardExists(card->id, deck) == 1 || cardExistsC(card, deck) == 1) 
      return 1; 
    } 

    // If nothing runs successfully, return 0 
    return 0; 
} 

// Determines if a card exists within a deck given an id or a card* returns 1, otherwise 0 
int 
cardExists(int id, Deck *deck) 
{ 
    // If deck is not initialised, return 0 
    if (deck == NULL) 
     return 0; 

    // Traverse through the cards checking if the id matches any of the current cards 
    Card *p = deck->cards; 

#if 0 
    if (p->id == id) 
     return 1;      // Check if id matches the first card 
    while (p->next_card != NULL) { 
     p = p->next_card;    // Move on to the next_card 
     if (p->id == id) 
      return 1;     // If id matches, return 1 
    } 
    if (p->id == id) 
     return 1;      // Check if id matches the first card 
#else 
    while (p != NULL) { 
     if (p->id == id) 
      return 1;     // If id matches, return 1 
     p = p->next_card;    // Move on to the next_card 
    } 
#endif 

    // No duplicate cards return 0 
    return 0; 
} 

int 
cardExistsC(Card *card, Deck *deck) 
{ 
    // If deck is not initialised, return 
    if (deck == NULL || card == NULL) 
     return 0; 

    // Traverse through the cards checking if the card matches any of the current cards 
    Card *p = deck->cards; 

#if 0 
    while (p->next_card != NULL) { 
     if (p == card) 
      return 1;     // If id matches, return 1 
     p = p->next_card;    // Else move on to the next_card 
    } 
#else 
    while (p != NULL) { 
     if (p == card) 
      return 1;     // If id matches, return 1 
     p = p->next_card;    // Else move on to the next_card 
    } 
#endif 

    // No duplicate cards return 0 
    return 0; 
} 

// Shuffles deck - size*100 randoms swaps, or a shuffling algorithm 
void 
shuffle(Deck *deck) 
{ 
    // If deck is not initialised, return 
    if (deck == NULL) 
     return; 

    // Declare vars for use 
    int d, 
    i, 
    j, 
    x, 
    r1, 
    r2; 
    Card *o = deck->cards;    // The List of cards 
    Card *p1, *p2; 

    d = deck->size;      // Deck size 
    i = 0;        // Loop var 
    j = d * 100;      // Amount of swaps needed 
    x = 0;        // Inner loop var 

    // Initialise pointers 
    p1 = NULL; 
    p2 = NULL; 

    // Swaps two cards while less than amount of reqired swaps 
    while (i < j) { 
     // Create two random numbers 
     r1 = rand() % d; 
     r2 = rand() % d; 

     // Traverse through the List od cards in the deck r1 and r2 number of times 
     // NOTE/BUG: this gets flagged by the compiler with -Wall and really 
     // is ambiguous: 
     // which is it? 
     // while (((x <= r1) || (x <= r2)) && (o->next_card != NULL)) 
     // 
     // while ((x <= r1) || ((x <= r2) && (o->next_card != NULL))) 
#if 0 
     while (x <= r1 || x <= r2 && o->next_card != NULL) { 
#else 
     while (((x <= r1) || (x <= r2)) && (o->next_card != NULL)) { 
#endif 
      if (x == r1) 
       p1 = o;     // p1 == o when x == r1 
      if (x == r2) 
       p2 = o;     // p2 == o when x == r2 
      o = o->next_card; 
      x++; 
     } 

     // NOTE/BUG!!! -- this does _not_ preserve the values correctly for the 
     // swap 
#if 0 
     // Hold p1 in t 
     Card *t;         // Temp cards 
     t = p1; 

     // Replace p1 with p2 
     p1->id = p2->id; 
     p1->value = p2->value; 

     // Replace p2 with t 
     p2->id = t->id; 
     p2->value = t->value; 
#else 
     // Hold p1 in t 
     Card t;         // Temp cards 
     t = *p1; 

     // Replace p1 with p2 
     p1->id = p2->id; 
     p1->value = p2->value; 

     // Replace p2 with t 
     p2->id = t.id; 
     p2->value = t.value; 
#endif 

     i++; 
    } 
} 

// Moves the top x cards of the deck to the hand structure returns hand size 
int 
fillHand(int size, Hand *hand, Deck *deck) 
{ 
    // If deck and hand is not initialised or size less than 0, return 
    if (deck == NULL || !(size >= 0)) 
     return 0; 

    // Initialise vars for use 
    Card *h = hand->cards; 
    Card *d = deck->cards; 
    int x = 1; 

    // Make h == d 
    h = d; 
    // Start the hand here 
    hand->cards = h; 

    // Traverse 'size' amount through the hand and deck 
    while (x < size && h->next_card != NULL && d->next_card != NULL) { 
     h = h->next_card; 
     d = d->next_card; 
     x++; 
    } 

    // Update hand->size 
    hand->size = x; 

    // Move the card after the new hand list up to be the new top of deck 
    deck->cards = d->next_card; 
    deck->size = deck->size - x; 

    // End the hand here 
    h->next_card = NULL; 

    return hand->size; 
} 

// prints the hand to the console showing ID and value, one card per line in the format ###\tID-Value 
void 
showHand(Hand *hand) 
{ 
    // If hand is not initialised, return 
    if (hand == NULL) 
     return; 

    // Declare vars for use 
    int val, 
    id; 
    Card *p = hand->cards; 

    // Traverse through the List of Cards printing each one's value and id 
    // NOTE/BUG: would fail if only one card in hand 
#if 0 
    while (p->next_card != NULL) { 
     val = p->value; 
     id = p->id; 
     printf("###\t %d-%d\n", id, val); 
     p = p->next_card; 
    } 
#else 
    while (p != NULL) { 
     val = p->value; 
     id = p->id; 
     printf("###\t %d-%d\n", id, val); 
     p = p->next_card; 
    } 
#endif 
    printf("\n"); 
} 

// Removes the card from hand and displays the card ID and Value in the format ***ID-Value, a value of -1 in id indicates a random card, returns played card id 
int 
playCard(int id, Hand *hand, Deck *deck) 
{ 
    // If hand is not initialised, return 
    if (hand == NULL || deck == NULL) 
     return 0; 

    // Setup vars for use 
    Card *d, 
    *h, 
    *p; 
    int i, 
    cid, 
    cval; 

    d = deck->cards; 
    h = hand->cards; 
    p = h; 
    i = 0; 

    // If card is to be randomly chosen 
    if (id == -1) { 
     i = rand() % hand->size;  // Get a random number 
     i++; 
     while (i > 0 && h->next_card != NULL) // Move i times through the list 
     { 
      p = h;      // make p == current card so it becomes the previous card 
      h = h->next_card;   // Move to the next card 
      i--;      // Decrement i 
     } 

     // Go to end of the deck 
     while (d->next_card != NULL) { 
      d = d->next_card; 
     } 

     // Get card data 
     cid = h->id; 
     cval = h->value; 
     // Print the card data 
     printf("***%d-%d\n\n", cid, cval); 

     // Put the randomly chosen card from the hand to the end of deck 
     d->next_card = h; 

     // Remove the card from hand 
     p->next_card = h->next_card; 

     // Move to the card added to the deck 
     d = d->next_card; 

     // Ensure the end card is the last in the list 
     d->next_card = NULL; 

     // Increment deck size 
     deck->size++; 

     // Decrement hand size 
     hand->size--; 

     return -1; 
    } 
    else { 
     // Go to end of the deck 
     while (d->next_card != NULL) { 
      d = d->next_card; 
     } 

     // Get card data 
     cid = h->id; 
     cval = h->value; 
     // Print the card data 
     printf("***%d-%d\n\n", cid, cval); 

     // Put the randomly chosen card from the hand to the end of deck 
     d->next_card = h; 
     // Remove the card from hand and make the following card the new head of the list 
     hand->cards = h->next_card; 

     // Move to the card added to the deck 
     d = d->next_card; 

     // Ensure the end card is the last in the list 
     d->next_card = NULL; 

     // Increment deck size 
     deck->size++; 

     // Decrement hand size 
     hand->size--; 

     return cid; 
    } 
} 
+0

ああ、あなたは私のヒーローです!私はコードをテストし、それは私に望ましい出力を与える。私は間違いから学ぶためにこれを見直します。私はシャッフルが問題と関係していると思っていたので、私はあなたの答えを見るまでそれを書き直していました。また、当時はGCCでコンパイルしていませんでしたが、VS 2015でコンパイルされたコンパイラを使用していたため、警告が表示されませんでしたが、GCCに準拠していることを確認しましたが、コードを整理するのは、通常は最後に行います。これありがとう! – PairedPrototype

+1

あなたは大歓迎です!バグではありませんが、いくつかの関数は、 'hand'または' deck'が 'NULL'であることを早期にチェックし、早い段階で返ってきます。それらのいくつか(例えば 'playCard')については、ポインタがその時点で非nullであるべきであるということは公理であるため、戻り値をある種の致命的な打ち切りで置き換えます(例えば、' printf( "playCard:FATAL .. \ n "); exit(1);')このような内部論理エラーが検出されたときにプログラムをできるだけ早く停止するほうが良いでしょう。 'deck'の場合は、プログラムの開始時にヌルチェックを行います。そのため、nullでないことが保証されています。 –