So, I'm trying to create a deck of cards using Linked List for a class, but I am having an extremely hard time trying to figure out why I have the error: Access violation reading location 0x00000020. I'm still new to coding and dynamic allocation, and I'm sure it's an easy fix, but I cannot for the life of me figure it out. My Deck class is the linked list, and my Card class is the node. The ultimate goal to make the game Crazy Eights. The Game class is supposed to hold four Decks (draw pile, discard pile, my hand, computer hand).
The code is breaking at SIZE++;
in my addCard()
function in deck.cpp
Deck.h
#pragma once
#include "Card.h"
class Deck
{
protected:
int SIZE; //SIZE variable - indicates how many cards in deck
Card *top; //pointer to TOP of linked structure of cards
public:
//CONSTRUCTOR
Deck();
//FILL DECK
void fill(); //initialize the Deck to contain the standard 52 cards
void addCard(int v, string s); //*insert* a new card into the Deck
//DRAW CARD
Card *drawCard(); //*remove* top card from the Deck and return it
//FIND AND REMOVE
void removeCard(int val, string s);//*find* a specific card and remove it from the Deck
//SHUFFLE
void shuffle(); //randomize the order of cards in the Deck
//PRINT
void print(); //displays the contents of the Deck
};
Deck.cpp
#include "Deck.h"
#include "Card.h"
#include <iostream>
using namespace std;
Deck::Deck()
{
top = NULL;
SIZE = 0;
}
void Deck::fill()
{
string suit;
for (int i = 0; i < 13; i++){
for (int j = 0; j < 4; j++){
switch (j){
case 0: suit = "HEART"; break;
case 1: suit = "DIAMOND"; break;
case 2: suit = "CLUB"; break;
case 3: suit = "SPADE"; break;
}//end switch
addCard(i, suit);
}//end for
}//end for
}//end fill
Card *Deck::drawCard()
{
Card *draw = top;
top = top->getNext();
SIZE--;
return draw;
}//end drawCard
void Deck::removeCard(int val, string s)
{
//FINDS CARD
Card *cur = top;
while (cur != NULL && cur->getVALUE() != val && cur->getSUIT() != s)
cur = cur->getNext();
if (cur != NULL)
cout << cur->getVALUE() << cur->getSUIT();
else{
cout << "NOT FOUND";
return;
}//end else
//REMOVES CARD
Card *remove, *prev;
if (top->getVALUE() == val && top->getSUIT() == s){
remove = top;
top = top->getNext();
delete remove;
SIZE--;
removeCard(val, s);
}//end if
else{
prev = top;
while (prev->getNext() != NULL && prev->getNext()->getVALUE() != val && prev->getNext()->getSUIT() != s)
prev = prev->getNext();
if (prev->getNext() != NULL){
remove = prev->getNext();
prev->setNext(remove->getNext());
delete remove;
SIZE--;
removeCard(val, s);
}//end if
}//end else
}//end removeCard
void Deck::addCard(int val, string s)
{
SIZE++;
top = new Card(val, s, top);
}//end addCard
//void Deck::shuffle()
//{
// for (int i = 0; i < 7; i++)
// {
// // first break the deck into two half lists -- like when you
// //split the deck in half to shuffle
// Deck half1;
// Deck half2;
// for (SIZE; SIZE > SIZE/2; SIZE--)
// {
// //draw card off the deck and add card to half1
// SIZE--;
// }//end for
// for (int j = 0; j <= SIZE/2; SIZE++)
// {
// //draw card off the deck and add card to half2
// SIZE++;
// }//end for
//
// // now repeatedly pull one card from either half1 or half2 and
// // place it back on the deck -- like when the cards
// // are falling back in random clumps during shuffling.
// // we don't want to draw with 50-50 probability, instead we're
// // going to skew the probability of selecting from
// // each pile based on the relative size of the two piles.
// while (/*half1 and half2 still have cards in them*/true)
// {
// int probPile1; //= size of half1 / (size of half1 + size of half2) * 100
// int randomNum; //= random number between 1 and 100
// if (randomNum <= probPile1)
// {
// //pull a card off half1 and add it back onto the deck
// }//end if
// else
// {
// //pull a card off half2 and add it back onto the deck
// }//end else
// }//end while
// }//end for
//}//end shuffle
void Deck::print()
{
cout << "Cards in pile: " << SIZE;
}//end print
Card.h
#pragma once
#include <string>
using namespace std;
class Card
{
friend class Deck; //allows Deck class access to Card's private member variables
protected:
int VALUE; //value of card [1,2,3...11,12,13]
string SUIT; //HEART, DIAMOND, CLUB, SPADE
Card *next;
public:
//CONSTRUCTORS/DESTRUCTOR
Card();
Card(int val, string s, Card *n);
~Card();
Card *copy();
//SETTERS: VALUE, SUIT, SYMBOL, next
void setVALUE(int val) {VALUE = val;}
void setSUIT(string s) {SUIT = s;}
void setNext(Card *n) {next = n;}
//GETTERS: VALUE, SUIT, SYMBOL, next
int getVALUE() {return VALUE;}
string getSUIT() {return SUIT;}
Card *getNext() {return next;}
void displayCard();
};
Card.cpp
#include "Card.h"
#include <iostream>
using namespace std;
Card::Card()
{
VALUE = 0; SUIT = " "; next = NULL;
}
Card::Card(int val, string s, Card *n)
{
VALUE = val; SUIT = s; next = n;
}
Card::~Card()
{
if(next) free(next);
}
Card *Card::copy()
{
Card *newCard = new Card(VALUE, SUIT, next);
return newCard;
}
void Card::displayCard()
{
cout << VALUE;
}
//tests whether two cards "match" -- comparison operator overload
bool operator == (Card &c1, Card &c2)
{
return (c1.getVALUE() == c2.getVALUE() || c1.getSUIT() == c2.getSUIT());
}
Game.h
#pragma once
#include "Deck.h"
class Game
{
protected:
Deck *drawPile, *discardPile, *myHand, *compHand;
public:
Game();
};
Game.cpp
#include "Game.h"
#include "Deck.h"
Game::Game()
{
drawPile = NULL; myHand = NULL; compHand = NULL; discardPile = NULL;
drawPile->fill();
for (int i = 0; i < 7; i++){
myHand->drawCard();
compHand->drawCard();
}//end for
discardPile->drawCard();
}
main.cpp
#include "Game.h"
#include <iostream>
using namespace std;
void main()
{
Game crazyEights;
system("PAUSE");
}