@@ -243,81 +243,49 @@ std::vector<Settlement*> GameBoard::GetNeighboringSettlements(
243243}
244244
245245/* *
246- * Checks to make sure the coordinate is within bounds of the board
246+ * Checks to make sure the coordinate is within bounds of the board and not a resource tile.
247247 */
248- bool GameBoard::outOfBounds (const Coordinate& coord) {
249- /* *
250- * This code is embarrassing, but I couldn't really figure out how to easily check for out of bounds
251- * I'm sure there is a simple algebraic function that does it, but I went for the hacky way.
252- *
253- * Discussed that we can just do a find in the map, and if it's not found then it's out of bounds
254- */
255-
256-
257-
258- switch (coord.second ) {
259- case 0 :
260- return !(coord.first >= 0 && coord.first <= 4 );
261- break ;
262- case 1 :
263- return !(coord.first >= -2 && coord.first <= 5 );
264- break ;
265- case 2 :
266- return !(coord.first >= -3 && coord.first <= 5 );
267- break ;
268- case 3 :
269- return !(coord.first >= -3 && coord.first <= 4 );
270- break ;
271- case 4 :
272- return !(coord.first >= -4 && coord.first <= 4 );
273- break ;
274- case 5 :
275- return !(coord.first >= -4 && coord.first <= 3 );
276- break ;
277- case 6 :
278- return !(coord.first >= -5 && coord.first <= 3 );
279- break ;
280- case 7 :
281- return !(coord.first >= -5 && coord.first <= 2 );
282- break ;
283- case 8 :
284- return !(coord.first >= -4 && coord.first <= 0 );
285- break ;
286- default :
287- break ;
248+ bool GameBoard::outOfBounds (const Coordinate& coord) const {
249+ // All valid coordinates are adjacent to resource tiles.
250+ static Coordinate adjacentCoordDiffs[] = {Coordinate (0 , 1 ), Coordinate (1 , 0 ), Coordinate (1 , -1 ), Coordinate (0 , -1 ), Coordinate (-1 , 0 ), Coordinate (-1 , 1 )};
251+ for (auto & diff : adjacentCoordDiffs) {
252+ if (resources.find (Coordinate{coord.first + diff.first , coord.second + diff.second }) != resources.end ()) {
253+ return false ;
254+ }
288255 }
289256 return true ;
290257}
291258
292259/* *
293260 * Checks to make sure the road doesn't already exist. If it does, then we don't want to add it again
294261 */
295- bool GameBoard::roadExists (Coordinate start, Coordinate end) {
296- std::shared_ptr<Road> isRoad = getRoad (start, end);
297- if (isRoad == NULL )
298- return false ;
299- return true ;
262+ bool GameBoard::roadExists (Coordinate start, Coordinate end) const {
263+ return bool (getRoad (start, end)); // shared_ptr can convert to bool
300264}
301265
302266
303267/* *
304268 * Checks to make sure the road being placed at a valid point according to the rules
305269 */
306- bool GameBoard::isRoadConnectionPoint (Coordinate point, Player& Owner){
270+ bool GameBoard::isRoadConnectionPoint (Coordinate point, Player& Owner) const {
307271 // is there a settlement we can build off of
308- if (corners.count (point) > 0 ){
309- CornerPiece * corner = corners[point].get ();
272+ auto cornerIt = corners.find (point);
273+ if (cornerIt != corners.end ()){
274+ const CornerPiece * corner = cornerIt->second .get ();
310275 if (corner != NULL ){
311276 if (corner->getOwner () == Owner)
312277 return true ;
313278 }
314279 }
315-
280+
316281 // is there a road we can build off of
317- std::vector<shared_ptr<Road>> roadVector = roads[point];
318- for (std::vector<shared_ptr<Road>>::iterator road = roadVector.begin (); road != roadVector.end (); ++road) {
319- if ((*road)->getOwner () == Owner)
320- return true ;
282+ auto roadIt = roads.find (point);
283+ if (roadIt != roads.end ()) {
284+ const std::vector<shared_ptr<Road>>& roadVector = roadIt->second ;
285+ for (auto road = roadVector.begin (); road != roadVector.end (); ++road) {
286+ if ((*road)->getOwner () == Owner)
287+ return true ;
288+ }
321289 }
322290
323291 return false ;
@@ -328,7 +296,7 @@ bool GameBoard::isRoadConnectionPoint(Coordinate point, Player& Owner){
328296 * Runs a series of checks to make sure the road can be placed
329297 * new Roads must be in bounds, unique, and connected to an existing road or settlement
330298 */
331- bool GameBoard::verifyRoadPlacement (Coordinate start, Coordinate end, Player& Owner) {
299+ bool GameBoard::verifyRoadPlacement (Coordinate start, Coordinate end, Player& Owner) const {
332300 if (outOfBounds (start) || outOfBounds (end))
333301 return false ;
334302
@@ -356,16 +324,11 @@ bool GameBoard::PlaceRoad(Coordinate start, Coordinate end, Player& Owner) {
356324 // Coordinates did not meet the criteria for a valid road
357325 return false ;
358326 }
359-
360- std::vector<shared_ptr<Road>> roadVector = roads[start];
361- roadVector.push_back (newRoad);
362- roads[start] = roadVector;
363- roadVector = roads[end];
364- roadVector.push_back (newRoad);
365- roads[end] = roadVector;
327+
328+ roads[start].push_back (newRoad);
329+ roads[end].push_back (newRoad);
330+
366331 return true ;
367-
368-
369332}
370333
371334/* *
@@ -384,26 +347,29 @@ bool GameBoard::buyRoad(Coordinate start, Coordinate end, Player& Owner){
384347/* *
385348 * returns a pointer to the road located at the specified coordinates. Will return NULL if the road is not found
386349 */
387- std::shared_ptr<Road> GameBoard::getRoad (Coordinate start, Coordinate end){
388- std::vector<shared_ptr<Road>> roadVector = roads[start];
389- for (std::vector<shared_ptr<Road>>::iterator road = roadVector.begin (); road != roadVector.end (); ++road) {
390- if ((*road)->equals (start, end))
391- return *road;
350+ const std::shared_ptr<Road> GameBoard::getRoad (Coordinate start, Coordinate end) const {
351+ auto roadVecIt = roads.find (start);
352+ if (roadVecIt != roads.end ()) {
353+ for (auto road = roadVecIt->second .begin (); road != roadVecIt->second .end (); road++) {
354+ if ((*road)->equals (start, end))
355+ return *road;
356+ }
392357 }
393358 return NULL ;
394359}
395360
396361/* *
397362 * Parent function for the find longest road traversal. Note that longest path is NP-Hard, so there is no simple algorithm for this.
398363 */
399- int GameBoard::FindLongestRoad (Player & owner){
364+ int GameBoard::FindLongestRoad (const Player & owner) const {
400365 int longest_path = 0 ;
401366 // for each road vertex v on the board
402367 for (auto roadVector = roads.begin (); roadVector != roads.end (); ++roadVector){
403368 // find the longest path from v
404369 std::map<Coordinate, bool > marked;
370+ std::map<Road*, bool > markedRoads;
405371 Coordinate start = roadVector->first ;
406- int temp_longest_path = FindLongestRoad_FromPoint (start, owner, marked, 0 );
372+ int temp_longest_path = FindLongestRoad_FromPoint (start, owner, marked, markedRoads, 0 );
407373
408374 // if that path is longer than the current longest, set to the longest
409375 if (temp_longest_path > longest_path)
@@ -414,30 +380,33 @@ int GameBoard::FindLongestRoad(Player & owner){
414380}
415381
416382
417- int GameBoard::FindLongestRoad_FromPoint (Coordinate curr, Player & owner, std::map<Coordinate, bool >& marked, int length){
383+ int GameBoard::FindLongestRoad_FromPoint (Coordinate curr, const Player & owner, std::map<Coordinate, bool >& marked, std::map<Road*, bool >& markedRoads, int length) const {
418384 marked[curr] = true ;
419385 int longest_path = length;
420386 // traverse all the surrounding edges and vertices
421- std::vector<shared_ptr<Road>> roadVector = roads[curr];
422- for (std::vector<shared_ptr<Road>>::iterator road = roadVector.begin (); road != roadVector.end (); ++road) {
387+ auto roadVectorIt = roads.find (curr);
388+ if (roadVectorIt != roads.end ()) {
389+ auto & roadVector = roadVectorIt->second ;
390+ for (auto road = roadVector.begin (); road != roadVector.end (); ++road) {
423391 int temp_longest_path = length;
424392
425393 // if the owner is correct and the road is unmarked
426- if ( !(* road)-> isMarked () && (*road)->owner -> getName ().compare (owner. getName ()) == 0 ){
394+ if ( !markedRoads[ road-> get ()] && (*road)->getOwner ().getName () == owner. getName () ){
427395
428396 temp_longest_path++;
429- (* road)-> mark () ;
397+ markedRoads[ road-> get ()] = true ;
430398 // Check if you can traverse to the next vertex and make that step if you can
431399 if (curr != (*road)->getStart () && !marked[(*road)->getStart ()]){
432- temp_longest_path = FindLongestRoad_FromPoint ((*road)->getStart (), owner, marked, temp_longest_path);
400+ temp_longest_path = FindLongestRoad_FromPoint ((*road)->getStart (), owner, marked, markedRoads, temp_longest_path);
433401 }else if (curr != (*road)->getEnd () && !marked[(*road)->getEnd ()]){
434- temp_longest_path = FindLongestRoad_FromPoint ((*road)->getEnd (), owner, marked, temp_longest_path);
402+ temp_longest_path = FindLongestRoad_FromPoint ((*road)->getEnd (), owner, marked, markedRoads, temp_longest_path);
435403 }
436- (* road)-> unmark () ;
404+ markedRoads[ road-> get ()] = false ;
437405 }
438406
439407 if (temp_longest_path > longest_path)
440408 longest_path = temp_longest_path;
409+ }
441410 }
442411 marked[curr] = false ;
443412 return longest_path;
0 commit comments