@@ -21,7 +21,46 @@ GameBoard::GameBoard() {
2121}
2222
2323GameBoard::~GameBoard () {
24+ freeRoads ();
25+ }
26+
27+ /*
28+ * Frees the roads data structure to prevent memory leaks
29+ */
2430
31+ void GameBoard::freeRoads (){
32+ // Iterate over all the points in the roads map
33+ for (auto roadVector = roads.begin (); roadVector != roads.end (); ++roadVector)
34+ {
35+ // Iterate all the roads at a given point
36+ for (std::vector<Road*>::iterator road = roadVector->second .begin (); road != roadVector->second .end (); ++road) {
37+ Road * roadPtr = *road;
38+
39+ // If this is the start of the road we want to remove it, but we must first erase it the list at the other end of the road
40+ // If we don't then we may try to access a road which has already been freed
41+ if (roadPtr != NULL && roadPtr->getStart () == roadVector->first ){
42+ removeRoadEnd (roadPtr);
43+ roadVector->second .erase (road);
44+ // Need to decrement the iterator to account for the lost item
45+ road--;
46+ delete roadPtr;
47+ }
48+ }
49+ }
50+ }
51+
52+ /* *
53+ * Find and remove the road that matches startRoad
54+ */
55+ void GameBoard::removeRoadEnd (Road * startRoad){
56+ std::vector<Road*> endRoadVector = roads[startRoad->getEnd ()];
57+ for (std::vector<Road*>::iterator endRoad = endRoadVector.begin (); endRoad != endRoadVector.end (); ++endRoad){
58+ if ((*endRoad) == startRoad){
59+ endRoadVector.erase (endRoad);
60+ // Need to decrement the iterator to account for the lost item
61+ endRoad--;
62+ }
63+ }
2564}
2665
2766int GameBoard::save_Board (std::string filename) {
@@ -142,51 +181,57 @@ bool GameBoard::outOfBounds(const Coordinate& coord) {
142181 /* *
143182 * This code is embarrassing, but I couldn't really figure out how to easily check for out of bounds
144183 * I'm sure there is a simple algebraic function that does it, but I went for the hacky way.
184+ *
185+ * Discussed that we can just do a find in the map, and if it's not found then it's out of bounds
145186 */
187+
146188 switch (coord.second ) {
147189 case 0 :
148- return (coord.first >= 0 && coord.first <= 4 );
190+ return ! (coord.first >= 0 && coord.first <= 4 );
149191 break ;
150192 case 1 :
151- return (coord.first >= -2 && coord.first <= 5 );
193+ return ! (coord.first >= -2 && coord.first <= 5 );
152194 break ;
153195 case 2 :
154- return (coord.first >= -3 && coord.first <= 5 );
196+ return ! (coord.first >= -3 && coord.first <= 5 );
155197 break ;
156198 case 3 :
157- return (coord.first >= -3 && coord.first <= 4 );
199+ return ! (coord.first >= -3 && coord.first <= 4 );
158200 break ;
159201 case 4 :
160- return (coord.first >= -4 && coord.first <= 4 );
202+ return ! (coord.first >= -4 && coord.first <= 4 );
161203 break ;
162204 case 5 :
163- return (coord.first >= -4 && coord.first <= 3 );
205+ return ! (coord.first >= -4 && coord.first <= 3 );
164206 break ;
165207 case 6 :
166- return (coord.first >= -5 && coord.first <= 3 );
208+ return ! (coord.first >= -5 && coord.first <= 3 );
167209 break ;
168210 case 7 :
169- return (coord.first >= -5 && coord.first <= 2 );
211+ return ! (coord.first >= -5 && coord.first <= 2 );
170212 break ;
171213 case 8 :
172- return (coord.first >= -4 && coord.first <= 0 );
214+ return ! (coord.first >= -4 && coord.first <= 0 );
173215 break ;
174216 default :
175217 break ;
176218 }
177- return false ;
219+ return true ;
178220}
179221
222+ /* *
223+ * Checks to make sure the road doesn't already exist. If it does, then we don't want to add it again
224+ */
180225bool GameBoard::roadExists (Coordinate start, Coordinate end) {
181- std::vector<Road*> roadVector = roads[start];
182- for (std::vector<Road*>::iterator road = roadVector.begin ();
183- road != roadVector.end (); ++road) {
184- if ((*road)->equals (start, end))
185- return true ;
186- }
187- return false ;
226+ Road * isRoad = getRoad (start, end);
227+ if (isRoad == NULL )
228+ return false ;
229+ return true ;
188230}
189231
232+ /* *
233+ * Checks to make sure the road being placed at a valid point according to the rules
234+ */
190235bool GameBoard::isRoadConnectionPoint (Coordinate start, Coordinate end, Player& Owner){
191236 /* * Need to figure out the CornerPiece/GamePiece predicament
192237 CornerPiece * corner = corners[start];
@@ -199,6 +244,9 @@ bool GameBoard::isRoadConnectionPoint(Coordinate start, Coordinate end, Player&
199244 return true ;
200245}
201246
247+ /* *
248+ * Runs a series of checks to make sure the road can be placed
249+ */
202250bool GameBoard::verifyRoadPlacement (Coordinate start, Coordinate end, Player& Owner) {
203251 if (outOfBounds (start) || outOfBounds (end))
204252 return false ;
@@ -208,23 +256,112 @@ bool GameBoard::verifyRoadPlacement(Coordinate start, Coordinate end, Player& Ow
208256
209257 if (!isRoadConnectionPoint (start, end, Owner))
210258 return false ;
259+
211260 return true ;
212261}
213262
263+ /* *
264+ * Places a road at the specified coordinates that will be owned by the given player
265+ */
214266void GameBoard::PlaceRoad (Coordinate start, Coordinate end, Player& Owner) {
215- verifyRoadPlacement (start, end, Owner);
267+ if (!verifyRoadPlacement (start, end, Owner))
268+ return ;
269+
216270 Road * newRoad;
217271 try {
218272 newRoad = new Road (start, end, Owner);
219273 } catch (int n) {
220274 // Coordinates did not meet the criteria for a valid road
221275 return ;
222276 }
223-
224277 std::vector<Road*> roadVector = roads[start];
225278 roadVector.push_back (newRoad);
279+ roads[start] = roadVector;
226280
227281 roadVector = roads[end];
228282 roadVector.push_back (newRoad);
283+ roads[end] = roadVector;
284+ }
285+
286+ /* *
287+ * returns a pointer to the road located at the specified coordinates. Will return NULL if the road is not found
288+ */
289+ Road * GameBoard::getRoad (Coordinate start, Coordinate end){
290+ std::vector<Road*> roadVector = roads[start];
291+ for (std::vector<Road*>::iterator road = roadVector.begin (); road != roadVector.end (); ++road) {
292+ if ((*road)->equals (start, end))
293+ return *road;
294+ }
295+ return NULL ;
296+ }
297+
298+ /* *
299+ * Parent function for the find longest road traversal. Note that longest path is NP-Hard, so there is no simple algorithm for this.
300+ */
301+ int GameBoard::FindLongestRoad (Player & owner){
302+ int longest_path = 0 ;
303+ // for each road vertex v on the board
304+ for (auto roadVector = roads.begin (); roadVector != roads.end (); ++roadVector){
305+ // find the longest path from v
306+ std::map<Coordinate, bool > marked;
307+ Coordinate start = roadVector->first ;
308+ int temp_longest_path = FindLongestRoad_FromPoint (start, owner, marked, 0 );
309+
310+ std::cout << " LONGEST PATH: " << start.first << " , " << start.second << " : " << temp_longest_path << " \n " ;
311+
312+ // if that path is longer than the current longest, set to the longest
313+ if (temp_longest_path > longest_path)
314+ longest_path = temp_longest_path;
315+ }
316+
317+ return longest_path;
318+ }
319+
320+
321+ int GameBoard::FindLongestRoad_FromPoint (Coordinate curr, Player & owner, std::map<Coordinate, bool >& marked, int length){
322+
323+ std::cout << " " << curr.first << " , " << curr.second << " : " << length << " \n " ;
324+
325+ marked[curr] = true ;
326+ int longest_path = length;
327+ // traverse all the surrounding edges and vertices
328+ std::vector<Road*> roadVector = roads[curr];
329+ for (std::vector<Road*>::iterator road = roadVector.begin (); road != roadVector.end (); ++road) {
330+
331+ int temp_longest_path = length;
332+
333+ // if the owner is correct and the road is unmarked
334+ if ( !(*road)->isMarked () && (*road)->owner ->getName ().compare (owner.getName ()) == 0 ){
335+
336+ temp_longest_path++;
337+ (*road)->mark ();
338+ // Check if you can traverse to the next vertex and make that step if you can
339+ if (curr != (*road)->getStart () && !marked[(*road)->getStart ()]){
340+ temp_longest_path = FindLongestRoad_FromPoint ((*road)->getStart (), owner, marked, temp_longest_path);
341+ }else if (curr != (*road)->getEnd () && !marked[(*road)->getEnd ()]){
342+ temp_longest_path = FindLongestRoad_FromPoint ((*road)->getEnd (), owner, marked, temp_longest_path);
343+ }
344+ (*road)->unmark ();
345+ }
346+
347+ if (temp_longest_path > longest_path)
348+ longest_path = temp_longest_path;
349+ }
350+ marked[curr] = false ;
351+ return longest_path;
229352}
230353
354+
355+
356+
357+
358+
359+
360+
361+
362+
363+
364+
365+
366+
367+
0 commit comments