Skip to content

Commit 15df2d0

Browse files
committed
Added road serialization
1 parent fc2f059 commit 15df2d0

File tree

5 files changed

+90
-22
lines changed

5 files changed

+90
-22
lines changed

include/Serialization.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include <map>
55
#include <string>
6+
#include <set>
67

78
#include "GameVisitor.h"
89
#include "Util.h"
@@ -13,6 +14,7 @@ class XMLVisitor : public GameVisitor {
1314
private:
1415
tinyxml2::XMLDocument xmldoc;
1516
std::map<std::string, tinyxml2::XMLElement*> playerElementMap;
17+
std::set<Road*> serializedRoads;
1618

1719
tinyxml2::XMLElement* coordinateElement(const Coordinate& c);
1820
public:

src/GameBoard.cpp

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,27 @@ GameBoard::GameBoard(istream& in) {
6363
players.emplace_back(std::move(player));
6464
}
6565
}
66+
67+
auto roadElements = doc.RootElement()->FirstChildElement("roads");
68+
if(roadElements) {
69+
for(auto roadElement = roadElements->FirstChildElement(); roadElement; roadElement = roadElement->NextSiblingElement()) {
70+
Coordinate start = xmlElementToCoord(*(roadElement->FirstChildElement("start")->FirstChildElement("coordinate")));
71+
Coordinate end = xmlElementToCoord(*(roadElement->FirstChildElement("end")->FirstChildElement("coordinate")));
72+
std::string ownerName = roadElement->FirstChildElement("owner")->FirstChild()->Value();
73+
Player* owner = nullptr;
74+
for(auto& playerUnique : players) {
75+
if(playerUnique->getName() == ownerName) {
76+
owner = playerUnique.get();
77+
}
78+
}
79+
if(owner == nullptr) {
80+
throw std::runtime_error("Road is owned by a nonexistant player.");
81+
}
82+
Road* newRoad = new Road(start, end, *owner);
83+
roads[start].push_back(newRoad);
84+
roads[end].push_back(newRoad);
85+
}
86+
}
6687
}
6788

6889
GameBoard::~GameBoard() {
@@ -99,11 +120,9 @@ void GameBoard::freeRoads(){
99120
*/
100121
void GameBoard::removeRoadEnd(Road * startRoad){
101122
std::vector<Road*> endRoadVector = roads[startRoad->getEnd()];
102-
for(std::vector<Road*>::iterator endRoad = endRoadVector.begin(); endRoad != endRoadVector.end(); ++endRoad){
123+
for(std::vector<Road*>::iterator endRoad = endRoadVector.begin(); endRoad != endRoadVector.end(); endRoad++){
103124
if((*endRoad) == startRoad){
104-
endRoadVector.erase(endRoad);
105-
//Need to decrement the iterator to account for the lost item
106-
endRoad--;
125+
(*endRoad) = nullptr;
107126
}
108127
}
109128
}
@@ -363,6 +382,11 @@ void GameBoard::accept(GameVisitor& visitor) {
363382
for(auto& it : resources) {
364383
it.second->accept(visitor);
365384
}
385+
for(auto& roadCoordVec : roads) {
386+
for(auto& road : roadCoordVec.second) {
387+
road->accept(visitor);
388+
}
389+
}
366390
for(auto& it : players) {
367391
it->accept(visitor);
368392
}
@@ -390,6 +414,24 @@ bool GameBoard::operator==(const GameBoard& other) const {
390414
return false;
391415
}
392416
}
417+
for(auto& roadCoordVec : roads) {
418+
const auto& otherVecIt = other.roads.find(roadCoordVec.first);
419+
if(otherVecIt == other.roads.end()) {
420+
return false;
421+
}
422+
auto& otherCoordVec = *otherVecIt;
423+
if(roadCoordVec.second.size() != otherCoordVec.second.size()) {
424+
return false;
425+
}
426+
for(size_t i = 0; i < roadCoordVec.second.size(); i++) {
427+
const Road& myRoad = *(roadCoordVec.second[i]);
428+
const Road& otherRoad = *(otherCoordVec.second[i]);
429+
if(myRoad == otherRoad) {}
430+
else {
431+
return false;
432+
}
433+
}
434+
}
393435
if(players.size() != other.players.size()) {
394436
return false;
395437
}

src/Road.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ void Road::accept(GameVisitor& visitor) {
4444
bool Road::operator==(const Road& other) const {
4545
return getStart() == other.getStart() &&
4646
getEnd() == other.getEnd() &&
47-
owner == other.owner;
47+
owner->getName() == other.owner->getName();
4848
}
4949

5050
/**

src/Serialization.cpp

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,23 +35,26 @@ void XMLVisitor::visit(Road& road) {
3535
if(!xmldoc.RootElement()->FirstChildElement("roads")) {
3636
xmldoc.RootElement()->InsertEndChild(xmldoc.NewElement("roads"));
3737
}
38-
XMLElement* roadsElement = xmldoc.RootElement()->FirstChildElement("roads");
39-
XMLElement* newRoadElement = xmldoc.NewElement("road");
40-
41-
XMLElement* ownerElement = xmldoc.NewElement("owner");
42-
XMLText* ownerText = xmldoc.NewText(road.getOwner().getName().c_str());
43-
ownerElement->InsertEndChild(ownerText);
44-
newRoadElement->InsertEndChild(ownerElement);
45-
46-
XMLElement* startElement = xmldoc.NewElement("start");
47-
startElement->InsertEndChild(coordinateElement(road.getStart()));
48-
newRoadElement->InsertEndChild(startElement);
49-
50-
XMLElement* endElement = xmldoc.NewElement("end");
51-
endElement->InsertEndChild(coordinateElement(road.getEnd()));
52-
newRoadElement->InsertEndChild(endElement);
53-
54-
roadsElement->InsertEndChild(newRoadElement);
38+
if(serializedRoads.find(&road) == serializedRoads.end()) {
39+
XMLElement* roadsElement = xmldoc.RootElement()->FirstChildElement("roads");
40+
XMLElement* newRoadElement = xmldoc.NewElement("road");
41+
42+
XMLElement* ownerElement = xmldoc.NewElement("owner");
43+
XMLText* ownerText = xmldoc.NewText(road.getOwner().getName().c_str());
44+
ownerElement->InsertEndChild(ownerText);
45+
newRoadElement->InsertEndChild(ownerElement);
46+
47+
XMLElement* startElement = xmldoc.NewElement("start");
48+
startElement->InsertEndChild(coordinateElement(road.getStart()));
49+
newRoadElement->InsertEndChild(startElement);
50+
51+
XMLElement* endElement = xmldoc.NewElement("end");
52+
endElement->InsertEndChild(coordinateElement(road.getEnd()));
53+
newRoadElement->InsertEndChild(endElement);
54+
55+
roadsElement->InsertEndChild(newRoadElement);
56+
serializedRoads.insert(&road);
57+
}
5558
}
5659

5760
void XMLVisitor::visit(Settlement& settlement) {

tests/testSerialization.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,24 @@ TEST(testCardSerialization) {
6262

6363
CHECK(testBoard == copyBoard);
6464
}
65+
66+
TEST(roadSerialization) {
67+
vector<unique_ptr<Player>> players;
68+
players.emplace_back(unique_ptr<Player>(new Player("test")));
69+
players.emplace_back(unique_ptr<Player>(new Player("test2")));
70+
71+
Player& firstPlayer = *players[0];
72+
Player& secondPlayer = *players[1];
73+
74+
GameBoard testBoard(std::move(players));
75+
76+
testBoard.PlaceRoad(Coordinate(0,0), Coordinate(-1,1), firstPlayer);
77+
testBoard.PlaceRoad(Coordinate(-1,1), Coordinate(-1,2), secondPlayer);
78+
79+
stringstream stream;
80+
testBoard.save(stream);
81+
82+
GameBoard copyBoard(stream);
83+
84+
CHECK(testBoard == copyBoard);
85+
}

0 commit comments

Comments
 (0)