Skip to content

Commit a453dfa

Browse files
committed
Updates road checks to include the check that the road is built off
another road or a settlement. Added buying road functions in Player and GameBoard. Changed the corners variable in GameBoard to use CornerPieces instead of GamePieces. Renamed "setters" in Player class, they are now called adders like their functionality.
1 parent 8305868 commit a453dfa

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)