I am trying to make a card game (UNO) and am having trouble with my array of objects. I have two. A array vector of Player objects, playerArray
, and an array of Card objects, hand
. I'm having no issue distributing 7 cards from the hand to the player, but once I create a second player object, player 2 inherits the same hand as player 1 and also an additional 7 cards.
I understand the fact that each time I create a Player
object, I need to also be creating a new hand
for each player. I need help turning this logic into code though.
I thought maybe the problem was that I needed to call delete hand;
in the Player.cpp
destructor, but I don't want my hand to be deleted when it goes out of scope because I want it to remain throughout the entire game.
I've also attempted using the debugger but in all honesty, I'm still learning how to use it and can't find the issue if I don't fully understand what's causing my issue.
OUTPUT
Please enter the amount of players: 2
Please enter the names of each player.
Player 1: tyler
Length: 0
Value: 10
Color: Green
Length: 1
Value: 1
Color: Red
Length: 2
Value: 14
Color: Wild
Length: 3
Value: 4
Color: Green
Length: 4
Value: 6
Color: Wild
Length: 5
Value: 8
Color: Wild
Length: 6
Value: 4
Color: Wild
Player 2: travis //lengths 0 - 6 are the same as tyler's. player 2's correct hand should be lengths 7-13
Length: 0
Value: 10
Color: Green
Length: 1
Value: 1
Color: Red
Length: 2
Value: 14
Color: Wild
Length: 3
Value: 4
Color: Green
Length: 4
Value: 6
Color: Wild
Length: 5
Value: 8
Color: Wild
Length: 6
Value: 4
Color: Wild
Length: 7
Value: 3
Color: Wild
Length: 8
Value: 8
Color: Yellow
Length: 9
Value: 10
Color: Red
Length: 10
Value: 4
Color: Yellow
Length: 11
Value: 6
Color: Yellow
Length: 12
Value: 3
Color: Red
Length: 13
Value: 7
Color: Yellow
Game.h / Game.cpp (This is where my Player vector interacts with my hand.)
#pragma once
#include "Player.h"
#include "DevTest.h"
#include <string>
#include <vector>
class Game
{
private:
int amountOfPlayers;
std::vector<Player> playerArray;
public:
Game();
void createPlayerArray();
void menu();
~Game();
};
#include "Game.h"
DevTest devtest;
extern Player player;
extern Deck deck;
Game::Game()
{
}
void Game::createPlayerArray()
{
std::string userName;
std::cout << "Please enter the amount of players: ";
std::cin >> amountOfPlayers;
if (amountOfPlayers < 2 || amountOfPlayers>10)
{
if (amountOfPlayers < 2)
{
std::cout << "Sorry! Not enough players." << std::endl;
}
if (amountOfPlayers > 10)
{
std::cout << "Sorry! Too many players." << std::endl;
}
}
else
{
std::cout << "Please enter the names of each player." << std::endl;
//std::vector<Player> *playerArray = new std::vector<Player>;
for (int i = 0; i < amountOfPlayers; i++)
{
playerArray.push_back(player);
std::cout << "Player " << i+1 << ": ";
std::cin.ignore();
std::getline(std::cin, userName);
this->playerArray[i].setUserName(userName);
this->playerArray[i].setHand(); //player 2 has 14 cards FIX
player.printHand();
}
}
system("PAUSE");
return;
}
Game::~Game()
{
}
Player.h/Player.cpp (This is where my hand of card objects is created)
#pragma once
#include "Deck.h"
#include <iostream>
class Player
{
private:
int length;
std::string username; //can indicate whos turn / wins
static const int HANDSIZE = 7;
Card* hand;
public:
Player();
void pushHand(Card deck);
void popHand();
void printHand();
void setHand();
int getHANDSIZE();
std::string getUserName();
void setUserName(std::string name);
~Player();
};
#include "Player.h"
#include "Card.h"
extern Deck deck;
//extern Game game;
Player::Player()
{
length = 0;
hand = new Card[HANDSIZE];
//game.createPlayerArray();
//new player?
}
void Player::pushHand(Card deck)
{
//push 1 deck object into hand
hand[length] = deck;
length++;
}
void Player::printHand()
{
for (int i = 0; i < length; i++)
{
std::cout << "Length: " << i << std::endl;
std::cout << "Value: " << hand[i].value << std::endl;
std::cout << "Color: ";
deck.toString(hand[i].color);
}
}
void Player::setHand()
{
for (int i = 0; i < HANDSIZE; i++)
{
deck.dealCard();
}
}
int Player::getHANDSIZE()
{
return HANDSIZE;
}
std::string Player::getUserName()
{
return username;
}
void Player::setUserName(std::string name)
{
username = name;
}
Player::~Player()
{
//delete hand;
}
Deck.h/Deck.cpp(I make 107 Card objects (107 cards in UNO) and store all those cards in my deck. It then goes from the deck to the hand.)
#pragma once
#include "Card.h"
#include "Player.h"
#include <iostream>
#include <ctime>
class Deck
{
private:
static const int MAXSIZE = 108; //108 cards in UNO
int length;
public:
Deck();
void createDeck();
void shuffle();
void printDeck();
//void push();
void pop();
int top();
bool isEmpty();
bool isFull();
void toString(Card::Color color); //converts enum to string.
void dealCard();
Card getCard();
Card* deck;
~Deck();
};
#include "Deck.h"
//Deck deck;
extern Player player;
//Card::Color color;
Deck::Deck()
{
deck = new Card[MAXSIZE];
length = 0;
}
void Deck::createDeck()
{
//UNO has 4 zero cards
int num = 0;
for (int col = 1; col <= 4; col++)
{
deck[length].value = num; //sets each to zero
deck[length].color = static_cast<Card::Color>(col); //sets each card to a color, iterates through enum
length++;
}
//card value 1-9 , draw-two (10), skip (11), reverse (12)
for (num = 1; num <= 12; num++)
{
for (int x = 0; x < 2; x++)
{
for (int col = 1; col <= 4; col++)
{
deck[length].value = num;
deck[length].color = static_cast<Card::Color>(col);
length++;
}
}
}
//wild(13) and draw four(14)
for (num = 13; num <= 14; num++)
{
for (int x = 0; x < 4; x++)
{
deck[length].value = num;
deck[length].color = Card::Color::WILD;
length++;
}
}
}
void Deck::shuffle() //fisher-yates algorithm
{
srand(time(NULL));
for (int i = length - 1; i > 0; i--)
{
int j = (rand() % (i + 1));
std::swap(deck[j], deck[i]);
}
}
void Deck::printDeck()
{
for (int i = 0; i < length; i++)
{
std::cout << "Length: " << i << std::endl;
std::cout << "Value: " << deck[i].value << std::endl;
std::cout << "Color: ";
toString(deck[i].color);
}
}
void Deck::pop()
{
if (isEmpty() == false)
{
length--;
}
}
int Deck::top()
{
if (isEmpty() == false)
{
return length - 1;
}
return 0;
}
bool Deck::isEmpty()
{
if (length == 0)
{
return true;
}
return false;
}
bool Deck::isFull()
{
if (length >= MAXSIZE)
{
return true;
}
return false;
}
void Deck::toString(Card::Color color)
{
switch (color)
{
case Card::Color::BLUE:
std::cout << "Blue"<<std::endl;
break;
case Card::Color::GREEN:
std::cout << "Green" << std::endl;
break;
case Card::Color::RED:
std::cout << "Red" << std::endl;
break;
case Card::Color::YELLOW:
std::cout << "Yellow" << std::endl;
break;
case Card::Color::WILD:
std::cout << "Wild" << std::endl;
break;
}
std::cout << std::endl;
return;
}
void Deck::dealCard()
{
player.pushHand(deck[top()]);
pop();
return;
}
Card Deck::getCard()
{
return deck[length-1];
}
Deck::~Deck()
{
}
And this is what my Card object is defined as
#pragma once
class Card
{
private:
public:
enum Color { BLUE, GREEN, RED, YELLOW, WILD };
Card();
Color color;
int value;
Card(Color color, int value);
~Card();
};
#include "Card.h"
Card::Card()
{
}
Card::Card(Color color, int value)
{
color = this->color;
value = this->value;
}
Card::~Card()
{
}