Skip to content

Commit 5836761

Browse files
committed
Added Development Card serialization + tests
1 parent 54b41a1 commit 5836761

File tree

9 files changed

+158
-33
lines changed

9 files changed

+158
-33
lines changed

include/DevelopmentCard.h

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "Util.h"
1414
#include "Player.h"
15+
#include "GameVisitor.h"
1516

1617

1718
enum DevCardType { KNIGHT, VICTORYPOINT, YEAROFPLENTY, MONOPOLY, ROADBUILDING };
@@ -27,9 +28,12 @@ class DevelopmentCard {
2728
DevelopmentCard(Player* player);
2829
virtual ~DevelopmentCard();
2930

30-
virtual DevCardType getType() = 0;
31+
virtual DevCardType getType() const = 0;
3132
virtual void playCard() = 0;
3233

34+
virtual Player* getOwner();
35+
virtual void accept(GameVisitor& visitor);
36+
virtual bool operator==(const DevelopmentCard&);
3337
};
3438

3539

@@ -41,8 +45,8 @@ class KnightCard : public DevelopmentCard {
4145
KnightCard(Player* player);
4246
// virtual ~KnightCard();
4347

44-
DevCardType getType();
45-
void playCard();
48+
virtual DevCardType getType() const;
49+
virtual void playCard();
4650

4751
};
4852

@@ -53,8 +57,8 @@ class VictoryPointCard : public DevelopmentCard {
5357
VictoryPointCard(Player* player);
5458
// virtual ~VictoryPointCard();
5559

56-
DevCardType getType();
57-
void playCard();
60+
virtual DevCardType getType() const;
61+
virtual void playCard();
5862

5963
};
6064

@@ -64,8 +68,8 @@ class YearOfPlentyCard : public DevelopmentCard {
6468
YearOfPlentyCard(Player* player);
6569
// virtual ~YearOfPlentyCard();
6670

67-
DevCardType getType();
68-
void playCard();
71+
virtual DevCardType getType() const;
72+
virtual void playCard();
6973

7074
};
7175

@@ -77,8 +81,8 @@ class MonopolyCard : public DevelopmentCard {
7781
MonopolyCard(Player* player);
7882
// virtual ~MonopolyCard();
7983

80-
DevCardType getType();
81-
void playCard();
84+
virtual DevCardType getType() const;
85+
virtual void playCard();
8286

8387
};
8488

@@ -91,8 +95,8 @@ class RoadBuildingCard : public DevelopmentCard {
9195
RoadBuildingCard(Player* player);
9296
// virtual ~RoadBuildingCard();
9397

94-
DevCardType getType();
95-
void playCard();
98+
virtual DevCardType getType() const;
99+
virtual void playCard();
96100
};
97101

98102

include/GameVisitor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ class Settlement;
77
class Road;
88
class City;
99
class Player;
10+
class DevelopmentCard;
1011

1112
class GameVisitor {
1213
private:
@@ -23,6 +24,7 @@ class GameVisitor {
2324
virtual void visit(City&) = 0;
2425
virtual void visit(Player&) = 0;
2526
virtual void visit(ResourceTile&) = 0;
27+
virtual void visit(DevelopmentCard&) = 0;
2628
};
2729

2830
#endif

include/Player.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212

1313
#include <vector>
1414
#include <string>
15+
#include <memory>
16+
17+
#include "tinyxml2.h"
1518

1619
#include "GameVisitor.h"
1720

@@ -28,7 +31,7 @@ class Player {
2831
private:
2932
std::string name;
3033

31-
std::vector<DevelopmentCard*> developmentCards;
34+
std::vector<std::unique_ptr<DevelopmentCard>> developmentCards;
3235

3336
int armySize;
3437
int longestRoad;
@@ -40,14 +43,15 @@ class Player {
4043
public:
4144

4245
Player(std::string playerName);
46+
Player(tinyxml2::XMLElement*);
4347
~Player();
4448

4549
int getVictoryPoints();
4650
void updateVictoryPoints();
4751

4852
int getDevCardsInHand();
4953

50-
void buyCard(DevelopmentCard* card);
54+
void buyCard(std::unique_ptr<DevelopmentCard> card);
5155
void playCard(DevelopmentCard* card);
5256

5357
int getWood() const;

include/Serialization.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#ifndef SERIALIZATION_H
22
#define SERIALIZATION_H
33

4+
#include <map>
5+
#include <string>
6+
47
#include "GameVisitor.h"
58
#include "Util.h"
69

@@ -9,6 +12,7 @@
912
class XMLVisitor : public GameVisitor {
1013
private:
1114
tinyxml2::XMLDocument xmldoc;
15+
std::map<std::string, tinyxml2::XMLElement*> playerElementMap;
1216

1317
tinyxml2::XMLElement* coordinateElement(const Coordinate& c);
1418
public:
@@ -21,6 +25,7 @@ class XMLVisitor : public GameVisitor {
2125
virtual void visit(City&);
2226
virtual void visit(Player&);
2327
virtual void visit(ResourceTile&);
28+
virtual void visit(DevelopmentCard&);
2429

2530
const tinyxml2::XMLDocument& getXMLDoc() const;
2631
};

src/DevelopmentCard.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,24 @@ DevelopmentCard::~DevelopmentCard() {
2020

2121
}
2222

23+
Player* DevelopmentCard::getOwner() {
24+
return owner;
25+
}
26+
27+
void DevelopmentCard::accept(GameVisitor& visitor) {
28+
visitor.visit(*this);
29+
}
30+
31+
bool DevelopmentCard::operator==(const DevelopmentCard& other) {
32+
return getType() == other.getType();
33+
}
34+
2335
KnightCard::KnightCard(Player* player):DevelopmentCard(player)
2436
{
2537

2638
}
2739

28-
DevCardType KnightCard::getType(){
40+
DevCardType KnightCard::getType() const {
2941
return KNIGHT;
3042
}
3143

@@ -40,7 +52,7 @@ VictoryPointCard::VictoryPointCard(Player* player):DevelopmentCard(player)
4052

4153
}
4254

43-
DevCardType VictoryPointCard::getType(){
55+
DevCardType VictoryPointCard::getType() const {
4456
return VICTORYPOINT;
4557
}
4658

@@ -55,7 +67,7 @@ YearOfPlentyCard::YearOfPlentyCard(Player* player):DevelopmentCard(player)
5567

5668
}
5769

58-
DevCardType YearOfPlentyCard::getType(){
70+
DevCardType YearOfPlentyCard::getType() const {
5971
return YEAROFPLENTY;
6072
}
6173

@@ -71,7 +83,7 @@ MonopolyCard::MonopolyCard(Player* player):DevelopmentCard(player)
7183

7284
}
7385

74-
DevCardType MonopolyCard::getType(){
86+
DevCardType MonopolyCard::getType() const {
7587
return MONOPOLY;
7688
}
7789

@@ -84,7 +96,7 @@ void MonopolyCard::playCard()
8496

8597
RoadBuildingCard::RoadBuildingCard(Player* player):DevelopmentCard(player){};
8698

87-
DevCardType RoadBuildingCard::getType()
99+
DevCardType RoadBuildingCard::getType() const
88100
{
89101
return ROADBUILDING;
90102
}

src/GameBoard.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,7 @@ GameBoard::GameBoard(istream& in) {
5959
auto playerElements = doc.RootElement()->FirstChildElement("players");
6060
if(playerElements) {
6161
for(auto playerElement = playerElements->FirstChildElement(); playerElement; playerElement = playerElement->NextSiblingElement()) {
62-
unique_ptr<Player> player(new Player(playerElement->FirstChildElement("name")->FirstChild()->Value()));
63-
player->setWood(fromString<int>(playerElement->FirstChildElement("wood")->FirstChild()->Value()));
64-
player->setBrick(fromString<int>(playerElement->FirstChildElement("brick")->FirstChild()->Value()));
65-
player->setOre(fromString<int>(playerElement->FirstChildElement("ore")->FirstChild()->Value()));
66-
player->setWheat(fromString<int>(playerElement->FirstChildElement("wheat")->FirstChild()->Value()));
67-
player->setWool(fromString<int>(playerElement->FirstChildElement("wool")->FirstChild()->Value()));
62+
unique_ptr<Player> player(new Player(playerElement));
6863
players.emplace_back(std::move(player));
6964
}
7065
}
@@ -148,6 +143,7 @@ void GameBoard::PlaceSettlement(Coordinate location, Player& Owner){
148143
}
149144

150145
void GameBoard::accept(GameVisitor& visitor) {
146+
visitor.visit(*this);
151147
for(auto& it : corners) {
152148
it.second->accept(visitor);
153149
}
@@ -160,7 +156,6 @@ void GameBoard::accept(GameVisitor& visitor) {
160156
for(auto& it : players) {
161157
it->accept(visitor);
162158
}
163-
visitor.visit(*this);
164159
}
165160

166161
bool GameBoard::operator==(const GameBoard& other) const {

src/Player.cpp

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,18 @@
1010
#include "Player.h"
1111

1212
#include <algorithm>
13+
#include <map>
14+
#include <utility>
15+
#include <stdexcept>
16+
#include <functional>
17+
#include <iostream>
1318

1419
#include "DevelopmentCard.h"
1520

21+
using tinyxml2::XMLElement;
22+
using std::map;
23+
using std::make_pair;
24+
using std::runtime_error;
1625

1726
Player::Player(std::string playerName) : name(playerName)
1827
{
@@ -24,6 +33,31 @@ Player::Player(std::string playerName) : name(playerName)
2433
}
2534
}
2635

36+
Player::Player(XMLElement* elem)
37+
{
38+
name = elem->FirstChildElement("name")->FirstChild()->Value();
39+
setWood(fromString<int>(elem->FirstChildElement("wood")->FirstChild()->Value()));
40+
setBrick(fromString<int>(elem->FirstChildElement("brick")->FirstChild()->Value()));
41+
setOre(fromString<int>(elem->FirstChildElement("ore")->FirstChild()->Value()));
42+
setWheat(fromString<int>(elem->FirstChildElement("wheat")->FirstChild()->Value()));
43+
setWool(fromString<int>(elem->FirstChildElement("wool")->FirstChild()->Value()));
44+
XMLElement* cardsElement = elem->FirstChildElement("cards");
45+
for(auto cardElem = cardsElement->FirstChildElement("card"); cardElem; cardElem = cardElem->NextSiblingElement("card")) {
46+
static const map<std::string, std::function<std::unique_ptr<DevelopmentCard>(void)>> typeToCard = {
47+
std::pair<std::string, std::function<std::unique_ptr<DevelopmentCard>(void)>>("knight", [this]() -> std::unique_ptr<DevelopmentCard> { return std::unique_ptr<DevelopmentCard>(new KnightCard(this)); }),
48+
std::pair<std::string, std::function<std::unique_ptr<DevelopmentCard>(void)>>("victorypoint", [this]() -> std::unique_ptr<DevelopmentCard> { return std::unique_ptr<DevelopmentCard>(new VictoryPointCard(this)); }),
49+
std::pair<std::string, std::function<std::unique_ptr<DevelopmentCard>(void)>>("yearofplenty", [this]() -> std::unique_ptr<DevelopmentCard> { return std::unique_ptr<DevelopmentCard>(new YearOfPlentyCard(this)); }),
50+
std::pair<std::string, std::function<std::unique_ptr<DevelopmentCard>(void)>>("monopoly", [this]() -> std::unique_ptr<DevelopmentCard> { return std::unique_ptr<DevelopmentCard>(new MonopolyCard(this)); }),
51+
std::pair<std::string, std::function<std::unique_ptr<DevelopmentCard>(void)>>("roadbuilding", [this]() -> std::unique_ptr<DevelopmentCard> { return std::unique_ptr<DevelopmentCard>(new RoadBuildingCard(this)); }),
52+
};
53+
auto typeIt = typeToCard.find(std::string(cardElem->FirstChildElement("type")->FirstChild()->Value()));
54+
if(typeIt == typeToCard.end()) {
55+
throw runtime_error("Invalid card type");
56+
}
57+
developmentCards.emplace_back(typeIt->second());
58+
}
59+
}
60+
2761
Player::~Player() {
2862

2963
}
@@ -46,27 +80,27 @@ int Player::getVictoryPoints()
4680
}
4781

4882

49-
void Player::buyCard(DevelopmentCard *card)
83+
void Player::buyCard(std::unique_ptr<DevelopmentCard> card)
5084
{
51-
developmentCards.push_back(card);
85+
developmentCards.push_back(std::move(card));
5286
}
5387

5488
void Player::playCard(DevelopmentCard *card)
5589
{
56-
if(std::find(developmentCards.begin(), developmentCards.end(), card) == developmentCards.end()) {
90+
auto cardTester = [card](std::unique_ptr<DevelopmentCard>& test) -> bool { return card == test.get(); };
91+
if(!std::any_of(developmentCards.begin(), developmentCards.end(), cardTester)) {
5792
return;
5893
}
5994
card->playCard();
60-
if (card->getType() == KNIGHT)
95+
if (card->getType() == KNIGHT) {
6196
armySize++;
97+
}
6298

63-
developmentCards.erase(std::remove(developmentCards.begin(), developmentCards.end(), card), developmentCards.end());
64-
99+
std::remove_if(developmentCards.begin(), developmentCards.end(), cardTester);
65100
}
66101

67102

68103

69-
70104
int Player::getWood() const
71105
{
72106
return resources[0];
@@ -126,9 +160,21 @@ std::string Player::getName() const
126160

127161
void Player::accept(GameVisitor& visitor) {
128162
visitor.visit(*this);
163+
for(auto& card : developmentCards) {
164+
card->accept(visitor);
165+
}
129166
}
130167

131168
bool Player::operator==(const Player& player) const {
169+
if(developmentCards.size() != player.developmentCards.size()) {
170+
return false;
171+
}
172+
for(std::size_t i = 0; i < developmentCards.size(); i++) {
173+
if((*developmentCards[i]) == (*player.developmentCards[i])) {}
174+
else {
175+
return false;
176+
}
177+
}
132178
return getName() == player.getName() &&
133179
getWood() == player.getWood() &&
134180
getBrick() == player.getBrick() &&

0 commit comments

Comments
 (0)