0

In a do-while loop a new card must be drawn until it doesn't satisfy the requirements.When the card is "A Spade" we should add it to the deck and just stop drawing random cards.Sometimes the output finishes with "A Spade", but sometimes it is some different card type.I believe there is something wrong with the code.

#define _CRT_SECURE_NO_WARNINGS

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

const char const available_values[13] =
{
    '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'
};

const char* const available_paints[4] =
{
    "club", "diamond", "heart", "spade"
};

typedef struct card_t
{
    char value;
    char* paint;
} Card;

void initialize_card(Card* card)
{
    int value_index = rand() % 13;
    int paint_index = rand() % 4;

    card->value = available_values[value_index];
    card->paint = available_paints[paint_index];
}

Card* card_draw()
{
    Card card;
    initialize_card(&card);

    return &card;
}

int main() {
    srand((unsigned int)time(NULL));
    unsigned count = 0;
    Card* card;
    Card* old_deck = NULL;
    Card* new_deck;
    do {
        new_deck = old_deck;
        count++;
        old_deck = calloc(count, sizeof(Card));
        if (!old_deck) {
            printf("Memory allocation error");
            break;
        }
        for (unsigned i = 0; i < count-1; i++) {
            old_deck[i] = new_deck[i];
            free(new_deck);
        }
        card = card_draw();
        old_deck[count-1] = *card;

        printf("%c %s\n\n", card->value, card->paint);

    } while (card->value != 'A' && card->paint != "Spade");

    return 0;
}

New version:

Constant.h: https://pastebin.com/av9pBabk

Main.cpp: https://pastebin.com/jJttNWjj

I hope it could be useful, thank you all!

nickland200
  • 47
  • 10
  • I would venture to suggest that the `free(new_deck);` line should be *outside* the `for` loop that it's currently in. – Adrian Mole Jan 04 '20 at 09:36
  • Also, you can't compare `char[]` strings (or `const char*` strings) using the `==` or `!=` operators - use `strcmp()`. (And "Spade" is *not* the same string as "spade".) – Adrian Mole Jan 04 '20 at 09:39
  • The 4 duplicates I've linked to address the 3 distinct problems you have in your code. You do not really need to *return* a pointer in the `card_draw`, just return the entire structure value. Also, the deck initialization is not correct. You cannot just add some random cards and call it a deck of cards, a deck of cards has each card only exactly once. What you need to do is to make a deck of cards and *shuffle it* – Antti Haapala -- Слава Україні Jan 04 '20 at 09:49
  • Adrian, you are god damn right.Also, Antti, I will check those links you have provided.Thank you both! – nickland200 Jan 04 '20 at 11:56

1 Answers1

0
Card* card_draw()
{
    Card card;
    initialize_card(&card);

    return &card;
}

This function's return value is useless. It's the address of card. But once the function returns, card no longer exists since it's local to the function. So the return value of this function cannot be used.

    card = card_draw();
    old_deck[count-1] = *card;

Oops, You dereference the pointer returned from card_draw, but it points to an object that no longer exists and so cannot be dereferenced.

Either make this function return a Card by value instead of a pointer or create the object in the caller and pass its address to this function.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278