dimanche 11 juin 2023

Unsure why the following C++ code is giving me error C2280

I am learning C++ and trying to get out of tutorial hell, so I wanted to try my hand at a basic BlackJack game. I'm currently running into trouble with my shuffle function and I'm not sure why the code isn't compiling. I keep getting the following error:

"'Deck &Deck::operator =(const Deck &)': attempting to reference a deleted function BlackJack E:\Visual Studio Projects\BlackJack\Deck.cpp 43"

When I comment out the below lines, the program compiles normally. I just don't understand what is happening with the two lines that are making it not compile.

deck.cards.erase(deck.cards.begin() + index);

deck = shuffledDeck;

Here is my Deck.h file:

#ifndef DECK_H
#define DECK_H
#include <vector>
#include "Card.h"
using namespace std;

class Deck : public Card
{
    private:
        // Empty vector of cards to be filled by initializeDeck
        vector<Card> cards;

        // Stores cards after they have been in the Player or Dealer's hand
        vector<Card> spentCards;

    public:
        short int deckSize {52};
        short int numDecks = 1;
        Deck();

        // Takes in a Deck object (which contains a vector of cards) and creates a vector with all the required cards,
        // and creates duplicates if you want more than 1 deck;
        void initializeDeck(Deck& deck, short int numDecks);

        // Creates a new vector and pulls random cards from the original vector until the original vector is empty
        void shuffle(Deck& deck);

        // Prints out the entire vector of cards created, one card at a time. It calls on the printCard() function inside the card class
        void printDeck(const Deck& deck);

};
#endif


Here is the Deck.cpp file:

#include <iostream>
#include <vector>
#include <cstdlib>
#include "Deck.h"
#include "Card.h"
using namespace std;

Deck::Deck()
{
}

void Deck::initializeDeck(Deck& deck, short int numDecks)
{
    for (int i = 0; i < numDecks; i++)
    {
        for (int suit = 0; suit < numSuits; suit++)
        {
            Card card;
            for (int rank = 1; rank <= numRanks; rank++)
            {
                card.setSuit((Suit)suit);
                card.setRank(Rank(rank));
                deck.cards.push_back(card);
            }
        }
    }
}



void Deck::shuffle(Deck& deck)
{
    Deck shuffledDeck;

    srand(time(nullptr));

    while (!deck.cards.empty())
    {
        int index = rand() % deck.cards.size();
        shuffledDeck.cards.push_back(deck.cards[index]);
        deck.cards.erase(deck.cards.begin() + index);
    }
    deck = shuffledDeck;
}

void Deck::printDeck(const Deck& deck)
{
    for (Card card : deck.cards)
    {
        printCard(card);
    }
}

Here is the Card.h file:

#ifndef CARD_H
#define CARD_H
#include <string>
using std::string;

// This is not assigning value, just setting the numerical constants that represent each card
const enum Rank : short int
{
    ACE_LOW = 1,
    TWO = 2,
    THREE = 3,
    FOUR = 4,
    FIVE = 5,
    SIX = 6,
    SEVEN = 7,
    EIGHT = 8,
    NINE = 9,
    TEN = 10,
    JACK = 11,
    QUEEN = 12,
    KING = 13,
    ACE_HIGH = 14
};

// Constant values representing the Suits
const enum Suit : short int
{
    SPADE = 0,
    HEART = 1,
    CLUB = 2,
    DIAMOND = 3
};

class Card
{
    public:

        // Constant values representing the total number of suits and ranks
        const short int numRanks{ 13 };
        const short int numSuits{ 4 };

        // Constructors of cards
        Card();
        Card(Rank rank, Suit suit);
        
        // setters for private data members
        void setRank(Rank rank);
        void setSuit(Suit suit);

        // Getters for private data members
        Rank getRank() const;
        Suit getSuit() const;

        // Printing the member variables of a card object
        void printCard(const Card& card);

        // Retrieving the actual names of the enums instead of their consta
        string whatSuit() const;
        string whatRank() const;

    private:
        Rank rank;
        Suit suit;
};

#endif

Here is Card.cpp

#include "Card.h"
#include <iostream>
using namespace std;


// Initializing an empty card for Rank and Suit to be specified later
Card::Card()
{
    suit = SPADE;
    rank = ACE_LOW;
}

// Constructor for creating a card with the specified Rank and Suit
Card::Card(Rank rank, Suit suit)
{
    this->rank = rank;
    this->suit = suit;
}

// Rank setter
void Card::setRank(Rank rank)
{
    this->rank = rank;
}

// Suit setter
void Card::setSuit(Suit suit)
{
    this->suit = suit;
}

// Rank getter
Rank Card::getRank() const
{
    return rank;
}

// Suit getter
Suit Card::getSuit() const
{
    return suit;
}

string Card::whatSuit() const
{
    switch (suit)
    {
        case 0:
            return "Spades";
            break;
        case 1:
            return "Hearts";
            break;
        case 2:
            return "Clubs";
            break;
        case 3:
            return "Diamonds";
            break;
        default:
            return "Invalid";
            break;
    }
}

string Card::whatRank() const
{
    switch (rank)
    {
        case 1:
            return "Ace Low (1)";
            break;
        case 2:
            return "Two";
            break;
        case 3:
            return "Three";
            break;
        case 4:
            return "Four";
            break;
        case 5:
            return "Five";
            break;
        case 6:
            return "Six";
            break;
        case 7:
            return "Seven";
            break;
        case 8:
            return "Eight";
            break;
        case 9:
            return "Nine";
            break;
        case 10:
            return "Ten";
            break;
        case 11:
            return "Jack";
            break;
        case 12:
            return "Queen";
            break;
        case 13:
            return "King";
            break;
        case 14:
            return "Ace High (11)";
            break;
        default:
            return "Invalid";
            break;
    }
}

void Card::printCard(const Card& card)
{
    cout << card.whatRank() << " of " << card.whatSuit() << endl;
}

I have tried making the function return a Deck object instead of void by using the line "return shuffledDeck". I have also tried to change it so that I am instead setting the "cards" data members of both Deck objects to be equal, with the same problem.

I was expecting the function to grab a random index in the original deck.cards vector, adding that to the shuffledDeck vector, and then delete the card with the generated index from the original vector.

It may be something super simple, but I have been banging my head against a wall for hours. Thanks for your help!




Aucun commentaire:

Enregistrer un commentaire