これをデバッグしようとしている数時間と多くのコーヒーを飲んだ後、私も私の友人は何がうまくいかないのかを理解することができます。機能が一貫して正しい出力を出力しない
Cで書かれた小さなカードゲームで、Card
を持つリンクされたリストを使用して、Deck
とHand
に入っています。 main()
で私はHand
の2人のプレイヤーを印刷し、Hand
からランダムなカードを出してDeck
の最後に置くループを持っています。これを行うには、私は関数playCard()
を持っています。
問題は、プレーヤーのHand
に存在しないCard
が印刷されています。私はCard
がDeck
に存在しなければならないと想像することができますが、なぜそれが印刷されているのか分かりません。私はまた、リストの最後に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;
}
}
'main'および任意の他の機能を追加してください。入力。 [ask]と[mcve]を参照してください。 –
リンクされたリストは扱いにくく、エラーが発生する可能性があります。リンクされたリストのコードをゲームロジックから分離するのが最善です。例えば、項目に 'n'を見つけ、それをリストから切り離し、項目へのポインタを返す一般的な' extractItemAtPosition(int n) '関数を書いてください。その後、ゲームロジックは、1行のコードでプレーヤーの手札からカードを受け取ることができます。 – user3386109
'deck =(Deck *)malloc((sizeof(Card)* 52)+ sizeof(Deck));'構造体に52枚のカードの配列が含まれていません。あふれている構造体でトリックをしていますか?リンクされたリストがどのように実装されているかのようには見えません。 –