Skip to content

Commit

Permalink
Added road serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
Databean committed Mar 8, 2014
1 parent fc2f059 commit 15df2d0
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 22 deletions.
2 changes: 2 additions & 0 deletions include/Serialization.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <map>
#include <string>
#include <set>

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

tinyxml2::XMLElement* coordinateElement(const Coordinate& c);
public:
Expand Down
50 changes: 46 additions & 4 deletions src/GameBoard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,27 @@ GameBoard::GameBoard(istream& in) {
players.emplace_back(std::move(player));
}
}

auto roadElements = doc.RootElement()->FirstChildElement("roads");
if(roadElements) {
for(auto roadElement = roadElements->FirstChildElement(); roadElement; roadElement = roadElement->NextSiblingElement()) {
Coordinate start = xmlElementToCoord(*(roadElement->FirstChildElement("start")->FirstChildElement("coordinate")));
Coordinate end = xmlElementToCoord(*(roadElement->FirstChildElement("end")->FirstChildElement("coordinate")));
std::string ownerName = roadElement->FirstChildElement("owner")->FirstChild()->Value();
Player* owner = nullptr;
for(auto& playerUnique : players) {
if(playerUnique->getName() == ownerName) {
owner = playerUnique.get();
}
}
if(owner == nullptr) {
throw std::runtime_error("Road is owned by a nonexistant player.");
}
Road* newRoad = new Road(start, end, *owner);
roads[start].push_back(newRoad);
roads[end].push_back(newRoad);
}
}
}

GameBoard::~GameBoard() {
Expand Down Expand Up @@ -99,11 +120,9 @@ void GameBoard::freeRoads(){
*/
void GameBoard::removeRoadEnd(Road * startRoad){
std::vector<Road*> endRoadVector = roads[startRoad->getEnd()];
for(std::vector<Road*>::iterator endRoad = endRoadVector.begin(); endRoad != endRoadVector.end(); ++endRoad){
for(std::vector<Road*>::iterator endRoad = endRoadVector.begin(); endRoad != endRoadVector.end(); endRoad++){
if((*endRoad) == startRoad){
endRoadVector.erase(endRoad);
//Need to decrement the iterator to account for the lost item
endRoad--;
(*endRoad) = nullptr;
}
}
}
Expand Down Expand Up @@ -363,6 +382,11 @@ void GameBoard::accept(GameVisitor& visitor) {
for(auto& it : resources) {
it.second->accept(visitor);
}
for(auto& roadCoordVec : roads) {
for(auto& road : roadCoordVec.second) {
road->accept(visitor);
}
}
for(auto& it : players) {
it->accept(visitor);
}
Expand Down Expand Up @@ -390,6 +414,24 @@ bool GameBoard::operator==(const GameBoard& other) const {
return false;
}
}
for(auto& roadCoordVec : roads) {
const auto& otherVecIt = other.roads.find(roadCoordVec.first);
if(otherVecIt == other.roads.end()) {
return false;
}
auto& otherCoordVec = *otherVecIt;
if(roadCoordVec.second.size() != otherCoordVec.second.size()) {
return false;
}
for(size_t i = 0; i < roadCoordVec.second.size(); i++) {
const Road& myRoad = *(roadCoordVec.second[i]);
const Road& otherRoad = *(otherCoordVec.second[i]);
if(myRoad == otherRoad) {}
else {
return false;
}
}
}
if(players.size() != other.players.size()) {
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Road.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void Road::accept(GameVisitor& visitor) {
bool Road::operator==(const Road& other) const {
return getStart() == other.getStart() &&
getEnd() == other.getEnd() &&
owner == other.owner;
owner->getName() == other.owner->getName();
}

/**
Expand Down
37 changes: 20 additions & 17 deletions src/Serialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,26 @@ void XMLVisitor::visit(Road& road) {
if(!xmldoc.RootElement()->FirstChildElement("roads")) {
xmldoc.RootElement()->InsertEndChild(xmldoc.NewElement("roads"));
}
XMLElement* roadsElement = xmldoc.RootElement()->FirstChildElement("roads");
XMLElement* newRoadElement = xmldoc.NewElement("road");

XMLElement* ownerElement = xmldoc.NewElement("owner");
XMLText* ownerText = xmldoc.NewText(road.getOwner().getName().c_str());
ownerElement->InsertEndChild(ownerText);
newRoadElement->InsertEndChild(ownerElement);

XMLElement* startElement = xmldoc.NewElement("start");
startElement->InsertEndChild(coordinateElement(road.getStart()));
newRoadElement->InsertEndChild(startElement);

XMLElement* endElement = xmldoc.NewElement("end");
endElement->InsertEndChild(coordinateElement(road.getEnd()));
newRoadElement->InsertEndChild(endElement);

roadsElement->InsertEndChild(newRoadElement);
if(serializedRoads.find(&road) == serializedRoads.end()) {
XMLElement* roadsElement = xmldoc.RootElement()->FirstChildElement("roads");
XMLElement* newRoadElement = xmldoc.NewElement("road");

XMLElement* ownerElement = xmldoc.NewElement("owner");
XMLText* ownerText = xmldoc.NewText(road.getOwner().getName().c_str());
ownerElement->InsertEndChild(ownerText);
newRoadElement->InsertEndChild(ownerElement);

XMLElement* startElement = xmldoc.NewElement("start");
startElement->InsertEndChild(coordinateElement(road.getStart()));
newRoadElement->InsertEndChild(startElement);

XMLElement* endElement = xmldoc.NewElement("end");
endElement->InsertEndChild(coordinateElement(road.getEnd()));
newRoadElement->InsertEndChild(endElement);

roadsElement->InsertEndChild(newRoadElement);
serializedRoads.insert(&road);
}
}

void XMLVisitor::visit(Settlement& settlement) {
Expand Down
21 changes: 21 additions & 0 deletions tests/testSerialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,24 @@ TEST(testCardSerialization) {

CHECK(testBoard == copyBoard);
}

TEST(roadSerialization) {
vector<unique_ptr<Player>> players;
players.emplace_back(unique_ptr<Player>(new Player("test")));
players.emplace_back(unique_ptr<Player>(new Player("test2")));

Player& firstPlayer = *players[0];
Player& secondPlayer = *players[1];

GameBoard testBoard(std::move(players));

testBoard.PlaceRoad(Coordinate(0,0), Coordinate(-1,1), firstPlayer);
testBoard.PlaceRoad(Coordinate(-1,1), Coordinate(-1,2), secondPlayer);

stringstream stream;
testBoard.save(stream);

GameBoard copyBoard(stream);

CHECK(testBoard == copyBoard);
}

0 comments on commit 15df2d0

Please sign in to comment.