I am trying to create a basic card game of war. Drawing 3 cards and comparing them one at a time, then best out of three wins. To begin I am just starting with making classes for the cards and deck. Later I will be making a Player class which will hold more mechanics of the game.
I am currently having trouble with populating the deck with the cards and drawing the top card. In my main()
I'm trying to do error checking to see if I have implemented things correctly before moving on. It is supposed to then shuffle the deck and draw a card, which is read back. This will ensure that the cards are all made correctly and when I have drawn over 52 it will throw out of range. There is also a special Joker which determines which player will go first, this isn't implemented completely yet but is represented by the non-overloaded Card()
constructor.
What it does so far is throw the out of range without populating the deck and writing out the cards, so the try
I have written is incorrect and I don't really understand how to write the proper cout
in it to show which card was just drawn. The comparison operators are not implemented in main yet either, I have the commented out at the moment.
Here are my following files.
main.cpp
#include <iostream>
#include <string>
#include <stdexcept>
#include "Card.h"
#include "Deck.h"
int main(){
Deck deckA; //create a deck
deckA.shuffle(); //shuffle cards into deck
try{
for(int i = 0; i < 52; i++){ //draw cards till deck is empty
deckA.draw();
std::cout << deckA; //not sure how to properly write out a card's suit and value using the overloaded <<
//comparison operators, not implemented buy my idea for how to go about it.
/** for(int i = 0; i < 51; i++){
if (deckA[i + 1] < deckA[i]){
return std::cout << deckA[i], " is greater than ", deckA[i + 1];
}
if(deckA(i + 1) == deckA(i)){
return std::cout << deckA[i], " is equal to ", deckA[i + 1];
}
} **/
}
}
catch(std::out_of_range&){ //catch for thrown out of range
std::cout << "Empty Deck";
deckA.shuffle(); //shuffle new deck
}
}
Card.h
#ifndef CARD_H_
#define CARD_H_
#include <iostream>
#include <string>
/**
* String constants for the suits. Use these for the << operator. Use the ordinal value
* of the Suit enum as an index to fetch the Card suit name
*/
static const std::string suitNames[] =
{ "Spades", "Hearts", "Diamonds", "Clubs" };
/**
* String constants for the rank. Use these for the << operator. Use the ordinal value
* of the Rank enum as an index to fetch the Card rank name
*/
static const std::string rankNames[] = { "Joker", "Two", "Three", "Four",
"Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King",
"Ace" };
/**
* Card class to represent a single playing card
*/
class Card {
public:
/**
* Suit enumerations
*/
enum Suit {
Spades = 0, Hearts, Diamonds, Clubs
};
/**
* Rank enumerations ordered by value for game of war
*/
enum Rank {
Joker = 0,
Two,
Three,
Four,
Five,
Six,
Seven,
Eight,
Nine,
Ten,
Jack,
Queen,
King,
Ace
};
/**
* Constructor
*
* @param s
* @param r
*/
Card(Suit s, Rank r);
/**
* Constructor. This empty constructor will create a joker card.
* The joker card is a special card given to the player going first.
*/
Card();
/**
* Destructor
*/
virtual ~Card();
/**
* Return true if this card is a joker
*/
bool isJoker() const {
return (cardRank == Joker);
}
/**
* Output the card to an output stream as "rank of suit", except for the joker which is just output as "Joker"
*/
friend std::ostream& operator <<(std::ostream&, const Card&);
/**
* Compare operators. For the game of war we only care about the rank value
*/
friend bool operator ==(const Card &lhs, const Card &rhs);
friend bool operator <(const Card &lhs, const Card &rhs);
private:
Suit cardSuit;
Rank cardRank;
};
#endif /* CARD_H_ */
Card.cpp
#include <string>
#include <iostream>
#include "Card.h"
Card::Card(Suit s, Rank r){
cardSuit = s;
cardRank = r;
}
/**
* Constructor. This empty constructor will create a joker card.
* The joker card is a special card given to the player going first.
*/
Card::Card() {
//joker
}
/**
* Destructor
*/
Card::~Card() {
// empty
}
/**
* Output the card to an output stream as "rank of suit", except for the joker which is just output as "Joker"
*/
std::ostream& operator <<(std::ostream& os, const Card& r){
//if joker cout Joker, else cout rank of suit
if (r == Card() ){
return os << "Joker";
}
else{
return os << r.cardRank << " of " << r.cardSuit;
}
}
/**
* Compare operators. For the game of war we only care about the rank value
*/
bool operator ==(const Card &lhs, const Card &rhs){
return (lhs == rhs);
}
bool operator <(const Card &lhs, const Card &rhs)
{
return (lhs.cardRank < rhs.cardRank);
};
Deck.h
#ifndef DECK_H_
#define DECK_H_
#include <vector>
#include "Card.h"
#define MaxCards 52
/**
* The Deck class holds a deck of 52 cards. Cards are not removed
* from the Deck.
*/
class Deck {
public:
/**
* Constructor and destructor
*/
Deck();
virtual ~Deck();
/**
* Shuffle the deck and reset the next available card to the beginning of the deck
*/
void shuffle();
/**
* Return true if the deck is empty (next available card is past the end of the deck)
*/
bool isEmpty() const;
/**
* Draw a card from the deck. If someone attempts to draw a card when the deck is
* empty then throw an out-of-range exception.
*/
const Card draw();
private:
unsigned nextCard;
std::vector<Card> cardDeck;
};
#endif /* DECK_H_ */
Deck.cpp
#include <iostream>
#include <vector>
#include <exception>
#include <algorithm>
#include <random>
#include "Deck.h"
#include "Card.h"
/**
* Constructor and destructor
*/
Deck::Deck() { //warning due to uninitialized Member nextCard.
unsigned nextCard = 0;
std::vector<Card> cardDeck[nextCard];
}
Deck::~Deck() {
// empty
}
/**
* Shuffle the deck and reset the next available card to the beginning of the deck
*/
void Deck::shuffle() {
std::shuffle(cardDeck.begin(), cardDeck.end(), std::default_random_engine());
nextCard = 0; //set index to top card.
}
/**
* Return true if the deck is empty (next available card is past the end of the deck)
*/
bool Deck::isEmpty() const{
unsigned nextCard;
if( nextCard == 52){
return true;
}
}
/**
* Draw a card from the deck. If someone attempts to draw a card when the deck is
* empty then throw an out-of-range exception.
*/
const Card Deck::draw(){
if (isEmpty() == true){
throw std::out_of_range("Out of range");
}
else{
cardDeck[nextCard++]; //draw card
return cardDeck[0]; //return top card
}
}
Aucun commentaire:
Enregistrer un commentaire