Search code examples
cfunctionpointersstructtypedef

How to shuffle a deck of struct cards without using an array in c


I have this code. I create 10 cards in function createDeck and i want to shuffle the cards in function MyDeckOutput without using an array. Can someone help??

I have no idea and my teacher wants like that. I am not allow to use c++ or something extern. :/

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

typedef struct Card
{
    char name[50];
    int maxAlter;
    float maxGewicht;
    double maxLaenge;
    struct Card* pNext;
} cards;

cards* createDeck()
{
    cards* pStart = NULL;
    cards* pLast = NULL;
    cards* pNew = (cards*)malloc(sizeof(cards));
    for (int iElm = 0; iElm < 10; iElm++) {
        cards* pNew = (cards*)malloc(sizeof(cards));
        if (iElm == 0) { strcpy_s(pNew->name, "Ameisenbaer"); pNew->maxAlter = 14; pNew->maxGewicht = 39; pNew->maxLaenge = 0.90; pNew->pNext = NULL; }
        if (iElm == 1) { strcpy_s(pNew->name, "Biber"); pNew->maxAlter = 21; pNew->maxGewicht = 30; pNew->maxLaenge = 1.02; pNew->pNext = NULL; }
        if (iElm == 2) { strcpy_s(pNew->name, "Brauenbaer"); pNew->maxAlter = 30; pNew->maxGewicht = 600; pNew->maxLaenge = 1.50; pNew->pNext = NULL; }
        if (iElm == 3) { strcpy_s(pNew->name, "Delfin"); pNew->maxAlter = 45; pNew->maxGewicht = 150; pNew->maxLaenge = 7.00; pNew->pNext = NULL; }
        if (iElm == 4) { strcpy_s(pNew->name, "Elefant"); pNew->maxAlter = 70; pNew->maxGewicht = 6000; pNew->maxLaenge = 3.00; pNew->pNext = NULL; }
        if (iElm == 5) { strcpy_s(pNew->name, "Esel"); pNew->maxAlter = 14; pNew->maxGewicht = 39; pNew->maxLaenge = 0.90; pNew->pNext = NULL; }
        if (iElm == 6) { strcpy_s(pNew->name, "Federmaus"); pNew->maxAlter = 21; pNew->maxGewicht = 30; pNew->maxLaenge = 1.02; pNew->pNext = NULL; }
        if (iElm == 7) { strcpy_s(pNew->name, "Fuchs"); pNew->maxAlter = 30; pNew->maxGewicht = 600; pNew->maxLaenge = 1.50; pNew->pNext = NULL; }
        if (iElm == 8) { strcpy_s(pNew->name, "Gorilla"); pNew->maxAlter = 45; pNew->maxGewicht = 150; pNew->maxLaenge = 7.00; pNew->pNext = NULL; }
        if (iElm == 9) { strcpy_s(pNew->name, "Giraffe"); pNew->maxAlter = 70; pNew->maxGewicht = 6000; pNew->maxLaenge = 3.20; pNew->pNext = NULL; }
        pNew->pNext = NULL;
        if (pStart == NULL) pStart = pNew;
        if (pLast != NULL) pLast->pNext = pNew;
        pLast = pNew;
    }
    return pStart;
}

/*void MyDeckOutput(cards* pStart)
{
    int iEle = 0;
    for (cards* pOut = pStart; pOut != NULL; pOut = pOut->pNext)
    {
        iEle++;
        if (iEle < 6) printf("name = %s\n", pOut->name);
    }
}*/

void MyDeckOutput(cards* pStart)
{
    for (cards* pOut = pStart; pOut != NULL; pOut = pOut->pNext) printf("name = %s\n", pOut->name);
}

void shuffleDeck(cards* pStart)
{
    cards* shuffled = NULL;
    cards* end = NULL;
    int numberOfCards = 10; // cards number
    srand(time(NULL)); // seeds the random nr generator with the current
    while (numberOfCards > 0)
    {
        int index = rand() % numberOfCards;
        cards* previousCard = NULL;
        cards* selectedCard = pStart->pNext;
        // iterate over linked list
        if (!shuffled)
            end = shuffled = selectedCard;
        else
            end->pNext = selectedCard;

        if (previousCard)
            previousCard->pNext = selectedCard->pNext;
        end->pNext = NULL;
        --numberOfCards;

        printf("name = %s%i\n", selectedCard->name, index);
    }
}

int main()
{
    cards* pStart = createDeck();
    MyDeckOutput(pStart);
    printf("\n\nShuffel:\n");
    shuffleDeck(pStart);

    system("pause");
    return 0;
};

Solution

  • The commentor @user3386109 is spot on with his suggestion.

    To help you get started, here's a little code snippet to do what you need to do.

    void shuffleDeck(cards *deck)
    {
        cards *shuffled = NULL;
        cards *end = NULL;
        int numberOfCards = countDeck(deck); //Count number of cards in your deck
        srand(time(NULL));  //Seeds the random number generator with the current 
        while (numberOfCards > 0)
        {
            int index = rand()%numberOfCards;
            cards *previousCard = NULL;
            cards *selectedCard;
            //Iterate over linked list until you arrive at index 'x'.
            if (!shuffled)
                end = shuffled = selectedCard;
            else
                end->next = selectedCard;
    
            if (previousCard)
                previousCard->next = selectedCard->next;
            end->next = NULL;
            --numberOfCards;
        }
    }
    

    Please note that this code is incomplete on purpose and merely meant to give you an idea on how to do it.

    Edit: I'm not really supposed to do this, but this shuffle code works for me.

    cards *shuffleDeck(cards *deck)
    {
        cards *shuffled = NULL;
        cards *end = NULL;
        int numberOfCards = countDeck(deck); //Count number of cards in your deck
        srand(time(NULL));  //Seeds the random number generator with the current
        while (numberOfCards > 0)
        {
            int index = rand()%numberOfCards;
            cards *previousCard = NULL;
            cards *selectedCard = deck;
        
            //Iterate over linked list until you arrive at index 'x'.
            for (int i = 0; i < index && selectedCard; ++i)
            {
                previousCard = selectedCard;
                selectedCard = selectedCard->pNext;
            }
        
            if (!shuffled)
                shuffled = selectedCard;
            else if (end)
                end->pNext = selectedCard;
            end = selectedCard;
        
            if (selectedCard)
            {
                if (previousCard)
                    previousCard->pNext = selectedCard->pNext;  //Closes the gap between the previous element and the next element.
                else
                    deck = selectedCard->pNext;                 //Resets the anchor element.
                selectedCard->pNext = NULL;
            }
            --numberOfCards;
        }
        
        return shuffled;
    }
    
    int main()
    {
        MyDeckOutput(shuffleDeck(createDeck()));
        return 0;
    };
    

    I will leave filling the gaps to you (how to count the number of the cards).

    Please also note, that your 'creating a card' is faulty. Either use curly braces ({}) around your assignments or, better yet, use a dedicated function.

    Alternatively I recommend reading about 'switch/case' statements.