Skip to content

Commit 243716f

Browse files
committed
Merge pull request #5 from Databean/road_implementation
Updates road checks to include the check that the road is built off
2 parents 8305868 + a453dfa commit 243716f

File tree

9 files changed

+168
-49
lines changed

9 files changed

+168
-49
lines changed

include/GameBoard.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class GameVisitor;
2020

2121
class GameBoard {
2222
private:
23-
std::map<Coordinate, std::unique_ptr<GamePiece>> corners;
23+
std::map<Coordinate, std::unique_ptr<CornerPiece>> corners;
2424
std::map<Coordinate, std::unique_ptr<GamePiece>> resources;
2525
std::map<Coordinate, std::vector<std::shared_ptr<Road>>> roads;
2626
std::vector<std::unique_ptr<Player>> players;
@@ -33,7 +33,7 @@ class GameBoard {
3333
bool verifyRoadPlacement(Coordinate start, Coordinate end, Player& Owner);
3434
bool outOfBounds(const Coordinate& coord);
3535
bool roadExists(Coordinate start, Coordinate end);
36-
bool isRoadConnectionPoint(Coordinate start, Coordinate end, Player& Owner);
36+
bool isRoadConnectionPoint(Coordinate point, Player& Owner);
3737

3838
int constructBoardFromFile(std::ifstream &file);
3939
int constructFileFromBoard(std::ofstream &file);
@@ -58,9 +58,11 @@ class GameBoard {
5858

5959
std::vector<Settlement*> GetNeighboringSettlements(Coordinate location);
6060

61+
bool buyRoad(Coordinate start, Coordinate end, Player& Owner);
62+
6163
void PlaceSettlement(Coordinate location, Player& Owner);
6264
void PlaceCity(Coordinate location, Player& Owner);
63-
void PlaceRoad(Coordinate start, Coordinate end, Player& Owner);
65+
bool PlaceRoad(Coordinate start, Coordinate end, Player& Owner);
6466

6567
void accept(GameVisitor& visitor);
6668

include/GamePiece.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class GamePiece {
2222
Coordinate getCoordinates() const;
2323
GameBoard& getBoard();
2424
const GameBoard& getBoard() const;
25-
25+
2626
Coordinate location;
2727

2828
virtual void accept(GameVisitor&) = 0;

include/Player.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,24 +65,26 @@ class Player {
6565

6666
void playCard(DevelopmentCard* card);
6767

68+
bool canBuyRoad();
69+
bool buyRoad();
70+
6871
bool offerTrade(Player* p, int offer[], int demand[]);
6972
bool recieveOffer(Player* p, int offer[], int demand[]);
7073
bool acceptOffer(Player* p, int offer[], int demand[]);
7174

7275
bool checkResources(int resourceList[]);
7376

74-
7577
int getWood() const;
7678
int getBrick() const;
7779
int getOre() const;
7880
int getWheat() const;
7981
int getWool() const;
8082

81-
void setWood(int resource);
82-
void setBrick(int resource);
83-
void setOre(int resource);
84-
void setWheat(int resource);
85-
void setWool(int resource);
83+
void addWood(int resource);
84+
void addBrick(int resource);
85+
void addOre(int resource);
86+
void addWheat(int resource);
87+
void addWool(int resource);
8688

8789
void accept(GameVisitor& visitor);
8890
bool operator==(const Player& player) const;

include/Road.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class Road {
3535
void unmark();
3636

3737
Player& getOwner();
38-
const Player& getOwner() const;
38+
Player& getOwner() const;
3939

4040
Player* owner;
4141

src/GameBoard.cpp

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,8 @@ bool GameBoard::outOfBounds(const Coordinate& coord) {
233233
* Discussed that we can just do a find in the map, and if it's not found then it's out of bounds
234234
*/
235235

236+
237+
236238
switch (coord.second) {
237239
case 0:
238240
return !(coord.first >= 0 && coord.first <= 4);
@@ -277,23 +279,34 @@ bool GameBoard::roadExists(Coordinate start, Coordinate end) {
277279
return true;
278280
}
279281

282+
280283
/**
281284
* Checks to make sure the road being placed at a valid point according to the rules
282285
*/
283-
bool GameBoard::isRoadConnectionPoint(Coordinate start, Coordinate end, Player& Owner){
284-
/** Need to figure out the CornerPiece/GamePiece predicament
285-
CornerPiece * corner = corners[start];
286-
if(corner != NULL){
287-
if (corner->getOwner() == Owner)
286+
bool GameBoard::isRoadConnectionPoint(Coordinate point, Player& Owner){
287+
//is there a settlement we can build off of
288+
if(corners.count(point) > 0){
289+
CornerPiece * corner = corners[point].get();
290+
if(corner != NULL){
291+
if (corner->getOwner() == Owner)
292+
return true;
293+
}
294+
}
295+
296+
//is there a road we can build off of
297+
std::vector<shared_ptr<Road>> roadVector = roads[point];
298+
for (std::vector<shared_ptr<Road>>::iterator road = roadVector.begin(); road != roadVector.end(); ++road) {
299+
if ((*road)->getOwner() == Owner)
288300
return true;
289301
}
302+
290303
return false;
291-
**/
292-
return true;
304+
293305
}
294306

295307
/**
296308
* Runs a series of checks to make sure the road can be placed
309+
* new Roads must be in bounds, unique, and connected to an existing road or settlement
297310
*/
298311
bool GameBoard::verifyRoadPlacement(Coordinate start, Coordinate end, Player& Owner) {
299312
if (outOfBounds(start) || outOfBounds(end))
@@ -302,35 +315,52 @@ bool GameBoard::verifyRoadPlacement(Coordinate start, Coordinate end, Player& Ow
302315
if (roadExists(start, end))
303316
return false;
304317

305-
if (!isRoadConnectionPoint(start, end, Owner))
318+
if (!isRoadConnectionPoint(start, Owner) && !isRoadConnectionPoint(end, Owner)) //need to XOR
306319
return false;
307320

308321
return true;
309322
}
310323

311324
/**
312325
* Places a road at the specified coordinates that will be owned by the given player
326+
* returns true if the road was placed, false otherwise
313327
*/
314-
void GameBoard::PlaceRoad(Coordinate start, Coordinate end, Player& Owner) {
328+
bool GameBoard::PlaceRoad(Coordinate start, Coordinate end, Player& Owner) {
315329
if (!verifyRoadPlacement(start, end, Owner))
316-
return;
330+
return false;
317331

318332
std::shared_ptr<Road> newRoad;
319333
try {
320334
newRoad = std::shared_ptr<Road>(new Road(start, end, Owner));
321335
} catch (int n) {
322336
//Coordinates did not meet the criteria for a valid road
323-
return;
337+
return false;
324338
}
339+
325340
std::vector<shared_ptr<Road>> roadVector = roads[start];
326341
roadVector.push_back(newRoad);
327342
roads[start] = roadVector;
328-
329343
roadVector = roads[end];
330344
roadVector.push_back(newRoad);
331345
roads[end] = roadVector;
346+
return true;
347+
348+
349+
}
350+
351+
/**
352+
* Will purchase a road for the given Player if it is possible.
353+
* returns true if the road was purchased and placed, false otherwise
354+
*/
355+
bool GameBoard::buyRoad(Coordinate start, Coordinate end, Player& Owner){
356+
if(Owner.canBuyRoad() && PlaceRoad(start, end, Owner)){
357+
Owner.buyRoad();
358+
return true;
359+
}
360+
return false;
332361
}
333362

363+
334364
/**
335365
* returns a pointer to the road located at the specified coordinates. Will return NULL if the road is not found
336366
*/
@@ -394,11 +424,11 @@ int GameBoard::FindLongestRoad_FromPoint(Coordinate curr, Player & owner, std::m
394424
}
395425

396426
void GameBoard::PlaceSettlement(Coordinate location, Player& Owner){
397-
corners[location] = std::unique_ptr<GamePiece>(new Settlement(*this, location, Owner));
427+
corners[location] = std::unique_ptr<CornerPiece>(new Settlement(*this, location, Owner));
398428
}
399429

400430
void GameBoard::PlaceCity(Coordinate location, Player& Owner){
401-
corners[location] = std::unique_ptr<GamePiece>(new City(*this, location, Owner));
431+
corners[location] = std::unique_ptr<CornerPiece>(new City(*this, location, Owner));
402432
}
403433

404434
void GameBoard::accept(GameVisitor& visitor) {

src/Player.cpp

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ Player::Player(XMLElement* elem)
3939
r = 0;
4040
}
4141
name = elem->FirstChildElement("name")->FirstChild()->Value();
42-
setWood(fromString<int>(elem->FirstChildElement("wood")->FirstChild()->Value()));
43-
setBrick(fromString<int>(elem->FirstChildElement("brick")->FirstChild()->Value()));
44-
setOre(fromString<int>(elem->FirstChildElement("ore")->FirstChild()->Value()));
45-
setWheat(fromString<int>(elem->FirstChildElement("wheat")->FirstChild()->Value()));
46-
setWool(fromString<int>(elem->FirstChildElement("wool")->FirstChild()->Value()));
42+
addWood(fromString<int>(elem->FirstChildElement("wood")->FirstChild()->Value()));
43+
addBrick(fromString<int>(elem->FirstChildElement("brick")->FirstChild()->Value()));
44+
addOre(fromString<int>(elem->FirstChildElement("ore")->FirstChild()->Value()));
45+
addWheat(fromString<int>(elem->FirstChildElement("wheat")->FirstChild()->Value()));
46+
addWool(fromString<int>(elem->FirstChildElement("wool")->FirstChild()->Value()));
4747
XMLElement* cardsElement = elem->FirstChildElement("cards");
4848
for(auto cardElem = cardsElement->FirstChildElement("card"); cardElem; cardElem = cardElem->NextSiblingElement("card")) {
4949
static const map<std::string, std::function<std::unique_ptr<DevelopmentCard>(void)>> typeToCard = {
@@ -73,6 +73,27 @@ int Player::getDevCardsInHand()
7373
return developmentCards.size();
7474
}
7575

76+
/**
77+
* Returns true if the player has enough resources to buy a road, false otherwise
78+
*/
79+
bool Player::canBuyRoad(){
80+
return getWood() > 0 && getBrick() > 0;
81+
}
82+
83+
/**
84+
* Subtracts the cost of a road from a player's resources if they have enough
85+
* returns true if the resources were subtracted, false otherwise
86+
*/
87+
bool Player::buyRoad(){
88+
if(canBuyRoad()){
89+
addWood(-1);
90+
addBrick(-1);
91+
return true;
92+
}
93+
//insufficient funds
94+
return false;
95+
}
96+
7697

7798
void Player::updateVictoryPoints()
7899
{
@@ -150,17 +171,17 @@ bool Player::recieveOffer(Player* p, int offer[], int demand[])
150171

151172
bool Player::acceptOffer(Player* p, int offer[], int demand[])
152173
{
153-
p->setWood(demand[WOOD_INDEX] - offer[WOOD_INDEX]);
154-
p->setBrick(demand[BRICK_INDEX] - offer[BRICK_INDEX]);
155-
p->setOre(demand[ORE_INDEX] - offer[ORE_INDEX]);
156-
p->setWheat(demand[WHEAT_INDEX] - offer[WHEAT_INDEX]);
157-
p->setWool(demand[WOOL_INDEX] - offer[WOOL_INDEX]);
158-
159-
this->setWood(offer[WOOD_INDEX] - demand[WOOD_INDEX]);
160-
this->setBrick(offer[BRICK_INDEX] - demand[BRICK_INDEX]);
161-
this->setOre(offer[ORE_INDEX] - demand[ORE_INDEX]);
162-
this->setWheat(offer[WHEAT_INDEX] - demand[WHEAT_INDEX]);
163-
this->setWool(offer[WOOL_INDEX] - demand[WOOL_INDEX]);
174+
p->addWood(demand[WOOD_INDEX] - offer[WOOD_INDEX]);
175+
p->addBrick(demand[BRICK_INDEX] - offer[BRICK_INDEX]);
176+
p->addOre(demand[ORE_INDEX] - offer[ORE_INDEX]);
177+
p->addWheat(demand[WHEAT_INDEX] - offer[WHEAT_INDEX]);
178+
p->addWool(demand[WOOL_INDEX] - offer[WOOL_INDEX]);
179+
180+
this->addWood(offer[WOOD_INDEX] - demand[WOOD_INDEX]);
181+
this->addBrick(offer[BRICK_INDEX] - demand[BRICK_INDEX]);
182+
this->addOre(offer[ORE_INDEX] - demand[ORE_INDEX]);
183+
this->addWheat(offer[WHEAT_INDEX] - demand[WHEAT_INDEX]);
184+
this->addWool(offer[WOOL_INDEX] - demand[WOOL_INDEX]);
164185

165186
return true;
166187
}
@@ -207,39 +228,39 @@ int Player::getWool() const
207228

208229

209230

210-
void Player::setWood(int resource)
231+
void Player::addWood(int resource)
211232
{
212233
if(resources[WOOD_INDEX] < (0-resource))
213234
resources[WOOD_INDEX] = 0;
214235
else
215236
resources[WOOD_INDEX] += resource;
216237
}
217238

218-
void Player::setBrick(int resource)
239+
void Player::addBrick(int resource)
219240
{
220241
if(resources[BRICK_INDEX] < (0-resource))
221242
resources[BRICK_INDEX] = 0;
222243
else
223244
resources[BRICK_INDEX] += resource;
224245
}
225246

226-
void Player::setOre(int resource)
247+
void Player::addOre(int resource)
227248
{
228249
if(resources[ORE_INDEX] < (0-resource))
229250
resources[ORE_INDEX] = 0;
230251
else
231252
resources[ORE_INDEX] += resource;
232253
}
233254

234-
void Player::setWheat(int resource)
255+
void Player::addWheat(int resource)
235256
{
236257
if(resources[WHEAT_INDEX] < (0-resource))
237258
resources[WHEAT_INDEX] = 0;
238259
else
239260
resources[WHEAT_INDEX] += resource;
240261
}
241262

242-
void Player::setWool(int resource)
263+
void Player::addWool(int resource)
243264
{
244265
if(resources[WOOL_INDEX] < (0-resource))
245266
resources[WOOL_INDEX] = 0;

src/Road.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,6 @@ Player& Road::getOwner() {
104104
return *owner;
105105
}
106106

107-
const Player& Road::getOwner() const {
107+
Player& Road::getOwner() const {
108108
return *owner;
109109
}

tests/testSerialization.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ TEST(roadSerialization) {
7373

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

76+
testBoard.PlaceSettlement(Coordinate(0,0), firstPlayer);
77+
testBoard.PlaceSettlement(Coordinate(-1,1), secondPlayer);
7678
testBoard.PlaceRoad(Coordinate(0,0), Coordinate(-1,1), firstPlayer);
7779
testBoard.PlaceRoad(Coordinate(-1,1), Coordinate(-1,2), secondPlayer);
7880

0 commit comments

Comments
 (0)