Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 功能无法始终打印正确的输出_C_Linked List - Fatal编程技术网

C 功能无法始终打印正确的输出

C 功能无法始终打印正确的输出,c,linked-list,C,Linked List,经过几个小时和许多咖啡的调试,我和我的朋友都能猜出到底出了什么问题 这是一款用C语言编写的小型纸牌游戏,使用链表在牌组和手中存放牌s。在main()中,我有一个循环,打印两名玩家的牌,然后从他们的牌中随机播放一张牌,并将其放置在牌组的末尾。为此,我有一个函数playCard() 问题是,它正在打印玩家手上不存在的卡。我只能想象卡一定存在于卡组中,但我不知道它为什么要打印它。我还确保列表的末尾NULLed,以阻止类似的事情发生 有人知道这里出了什么问题吗 这是我的密码: #include <

经过几个小时和许多咖啡的调试,我和我的朋友都能猜出到底出了什么问题

这是一款用C语言编写的小型纸牌游戏,使用链表在
牌组
中存放
s。在
main()
中,我有一个循环,打印两名玩家的
,然后从他们的
中随机播放一张牌,并将其放置在
牌组的末尾。为此,我有一个函数
playCard()

问题是,它正在打印玩家手上不存在的
卡。我只能想象
一定存在于
卡组
中,但我不知道它为什么要打印它。我还确保列表的末尾
NULL
ed,以阻止类似的事情发生

有人知道这里出了什么问题吗

这是我的密码:

#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;
    }
}
#包括
#包括
#包括
#包括
typedef结构卡;
结构卡
{
int值;
int-id;
卡片*下一张卡片;
};
typedef结构甲板
{
整数大小;
卡片*卡片;
}甲板;
typedef结构手
{
整数大小;
卡片*卡片;
}手;
卡片*createCard();
Deck*createDeck();
Hand*createHand();
int addCard(卡*卡,卡*卡);
int cardExists(int id,组*组);
int cardExistsC(卡*卡,卡*卡);
无效洗牌(牌组*牌组);
内部填充手(内部尺寸,手*手,甲板*甲板);
无效手牌(手牌*手牌);
int游戏卡(int id,手牌*手牌,牌组*牌组);
int main(int argc,字符**argv)
{
//初始化随机数生成器的种子
srand(时间(空));
int可播放=1;
Deck*Deck=createDeck();
Hand*player1=createHand();
Hand*player2=createHand();
如果(牌组==NULL | |玩家1==NULL | |玩家2==NULL)
{
if(deck!=NULL)
免费(甲板);
如果(player1!=NULL)
免费(player1);
如果(player2!=NULL)
免费(player2);
可播放=0;
}
如果(!可玩)
{
返回-1;
}
其他的
{
int i=0;
对于(i=0;i<52;i++)
{
Card*temp=createCard();
addCard(临时,甲板);
}
洗牌(牌组);
副手(7名,球员1名,甲板);
fillHand(7人,球员2人,甲板);
对于(i=0;i<7;i++)
{
表演者(玩家1);
表演者(玩家2);
扑克牌(-1,玩家1,扑克牌);
扑克牌(-1,扑克牌2,扑克牌);
}
免费(甲板);
免费(player1);
免费(player2);
}
返回0;
}
//创建一张新卡,生成随机ID(0-10000)和0-10之间的值
卡片*createCard()
{
卡片*卡片=空;
卡片=(卡片*)malloc(卡片大小);
卡片->id=rand()%10000;
卡片->值=rand()%10;
卡片->下一张卡片=空;
回程卡;
}
//创建新组块并将大小设置为0,在组块内创建列表
Deck*createDeck()
{
Deck*Deck=NULL;
甲板=(甲板*)malloc(甲板尺寸);
甲板->尺寸=0;
卡片组->卡片=NULL;
返回甲板;
}
//创建新手并将大小设置为0,在手内创建列表
Hand*createHand()
{
Hand*Hand=NULL;
hand=(hand*)malloc(sizeof(hand));
手->尺寸=0;
手牌->卡片=空;
回手;
}
//将创建的卡添加到组中,如果已添加卡,则返回1;如果未添加卡,则返回0;如果检测到重复id,则返回-1
int addCard(卡*卡,卡*卡)
{
//如果卡组或卡未初始化,则无法添加卡
如果(卡片==NULL | |卡片==NULL)返回0;
//如果牌组大小为0,则这必须是第一张牌
如果(组->大小==0)
{
//添加卡片并增加卡片组大小
卡片组->卡片=卡片;
甲板->尺寸++;
//检查卡是否已成功添加
如果(卡片存在(卡片->id,卡片组)==1 | |卡片存在(卡片,卡片组)==1)返回1;
//如果卡片检查失败,则返回0
返回0;
}
//如果牌组至少包含一张牌,则将其添加到牌列表的末尾
如果(甲板->尺寸>0)
{
//首先检查是否存在重复的ID
如果(卡片存在(卡片->id,卡片组)==1 | |卡片存在(卡片,卡片组)==1)返回-1;
//遍历到最后一张卡并添加新卡
卡片*p=卡片组->卡片;
while(p->next_card!=NULL)
{
p=p->下一张卡片;
}
p->下一张卡片=卡片;
甲板->尺寸++;
//检查卡是否已成功添加
如果(卡片存在(卡片->id,卡片组)==1 | |卡片存在(卡片,卡片组)==1)返回1;
}
//如果未成功运行任何内容,则返回0
返回0;
}
//确定给定id的卡组中是否存在卡*或卡*返回1,否则返回0
int cardExists(int id,组*组)
{
//如果未初始化组,则返回0
如果(deck==NULL)返回0;
//遍历卡片,检查id是否与任何当前卡片匹配
卡片*p=卡片组->卡片;
if(p->id==id)返回1;//检查id是否与第一张卡匹配
while(p->next_card!=NULL)
{
p=p->next_card;//转到下一张_card
if(p->id==id)返回1;//如果id匹配,则返回1
}
//没有重复的卡返回0
返回0;
}
int cardExistsC(卡*卡,卡*卡)
{
//如果甲板未初始化,则返回
如果(卡片==NULL | |卡片==NULL)返回0;
//遍历卡片,检查卡片是否与当前的任何卡片匹配
卡片*p=卡片组->卡片;
while(p->next_card!=NULL)
{
if(p==card)返回1;//如果id匹配,则返回1
p=p->next_card;//否则继续下一张_card
}
//没有重复的卡返回0
返回0;
}
//洗牌组-大小*100随机交换,或洗牌算法
无效洗牌(牌组*牌组)
{
//如果甲板未初始化,则返回
如果(deck==NULL)返回;
//声明要使用的变量
int d,i,j,x
// 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;
    }
}