// What are my possible next moves (locations) LocationID *whereCanIgo(HunterView currentView, int *numLocations, int road, int rail, int sea) { assert(currentView != NULL); assert(numLocations != NULL); // return value LocationID *ret; // check if first round if(getRound(currentView->g) == FIRST_ROUND) { // everywhere! ret = (LocationID *)(malloc(sizeof(LocationID)*NUM_MAP_LOCATIONS)); (*numLocations) = 0; int i; for(i=0;i<NUM_MAP_LOCATIONS;i++) { ret[(*numLocations)] = i; (*numLocations)++; } } else { ret = connectedLocations(currentView->g, numLocations, getLocation(currentView->g, getCurrentPlayer(currentView->g)), getCurrentPlayer(currentView->g), getRound(currentView->g), road ,rail, sea); } return ret; }
void testGraph(void) { printf("Testing graph 1...\n"); Location path[NUM_MAP_LOCATIONS]; int a = findShortestPath(NANTES, MARSEILLES, path, ANY,0); assert(a == 3); assert(path[0] == NANTES); assert(path[1] == CLERMONT_FERRAND); assert(path[2] == MARSEILLES); printf("Test passed!\n"); printf("Testing graph 2...\n"); a = findShortestPath(NANTES, MARSEILLES, path, ANY,0); assert(a == 3); assert(path[0] == NANTES); assert(path[1] == CLERMONT_FERRAND); assert(path[2] == MARSEILLES); printf("Test passed!\n"); printf("Testing graph by rail...\n"); a = findShortestPath(MADRID, BARCELONA, path, ANY,2); assert(a == 2); assert(path[0] == MADRID); assert(path[1] == BARCELONA); printf("Passed by rail test\n"); a = findShortestPath(MARSEILLES, COLOGNE, path, ANY,3); assert(a == 2); assert(path[0] == MARSEILLES); assert(path[1] == COLOGNE); printf("Passed second rail test\n"); a = findShortestPath(MARSEILLES, AMSTERDAM, path, ANY,3); assert(a == 3); assert(path[0] == MARSEILLES); assert(path[1] == COLOGNE); assert(path[2] == AMSTERDAM); printf("Passed final rail test\n"); printf("Testing fail cases\n"); printf("Testing Strassburg to CD\n"); a = findShortestPath(STRASBOURG, CASTLE_DRACULA, path, ANY, 3); int i = 0; int correct[5] = {51,6,10,21,13}; for (i = 0; i < a; i++) { assert(path[i] == correct[i]); } printf("Passed\nNow testing same path but without rail (ie round rem 4 equal to 0 )"); printf("Passed\nNow testing same path but without rail"); a = findShortestPath(STRASBOURG, CASTLE_DRACULA, path, ANY, 0); int correct2[6] = {51,38,58,10,28,13}; for (i = 0; i < a; i++) { assert(path[i] == correct2[i]); } printf("\nTest Passed\nNow to test the results of connected locs Klaus (expecting CD to be there)\n"); Graph g = newGraph(); LocationID *b = connectedLocations(&a, KLAUSENBURG, 0, 0, ANY, g); for (i=0; i<a; i++) { printf("[%d]",b[i]); } free(b); destroyGraph(g); printf("\nDone\n"); }
int isLegalMove(HunterView gameState, PlayerID id, LocationID move, int round, Graph g) { LocationID currLoc = getLocation(gameState, id); int amtLocs = 0, legal = 0, i; if (currLoc >= 0 && currLoc < NUM_MAP_LOCATIONS) { LocationID * adj = connectedLocations(&amtLocs, currLoc, id, round, ANY, g); for (i = 0; i < amtLocs; i++) { if (adj[i] == move) legal = 1; } free(adj); } return legal; }
// What are the specified player's next possible moves // FREE THIS ARRAY IN THE AI LocationID *whereCanTheyGo(DracView currentView, int *numLocations, PlayerID player, int road, int rail, int sea) { LocationID *locations; // Remember to free the array retured from connectedLocations // if you use it in the AI if (player == PLAYER_DRACULA) { locations = whereCanIgo(currentView, numLocations, road, sea); } else { locations = connectedLocations(currentView->gv, numLocations, \ whereIs(currentView, player), \ player, (giveMeTheRound(currentView)+1), \ road, rail, sea); } return locations; }
LocationID *returnConLocs(DracView currentView, int *numLocations) { LocationID *locations; LocationID myLocation; int road; int rail; int sea; myLocation = whereIs(currentView, PLAYER_DRACULA); road = 1; rail = 0; sea = 0; locations = connectedLocations(currentView->gv, numLocations, myLocation, PLAYER_DRACULA, giveMeTheRound(currentView), road, rail, sea); return locations; }
// What are the specified player's next possible moves LocationID *whereCanTheyGo(HunterView currentView, int *numLocations, PlayerID player, int road, int rail, int sea) { int i, numValidLocations, index; LocationID forbidden; LocationID *validLocations; fprintf(stderr,"From:%d , player:%d\n",getLocation(currentView->g, player),player); LocationID *locations = connectedLocations(currentView->g, numLocations, getLocation(currentView->g, player), player, getRound(currentView->g), road, rail, sea); if(player == PLAYER_DRACULA){ forbidden = ST_JOSEPH_AND_ST_MARYS; } numValidLocations = 0; for(i = 0; i < (*numLocations); i++){ if(locations[i] != forbidden){ numValidLocations++; } } index = 0; validLocations = malloc(sizeof(LocationID) * numValidLocations); for(i = 0; i < numValidLocations; i++){ if(locations[i] != forbidden){ validLocations[index] = locations[i]; index++; } } free(locations); *numLocations = numValidLocations; return validLocations; }
// What are the specified player's next possible moves LocationID *whereCanTheyGo(DracView currentView, int *numLocations, PlayerID player, int road, int rail, int sea) { // This will get ALL the connected locations. LocationID *arrConnected = connectedLocations(currentView->g, numLocations, getLocation(currentView->g, player), player, getRound(currentView->g), road, rail, sea); // The only trick is that Dracula must remove his trail. if (player == PLAYER_DRACULA) { Set setConnected = copyArrayToSet(arrConnected, *numLocations); LocationID pastSix[TRAIL_SIZE] = {0}; giveMeTheTrail(currentView, player, pastSix); for (int i = 0; i < TRAIL_SIZE; i++) { if (isElem(setConnected, pastSix[i])) { setRemove(setConnected, pastSix[i]); *numLocations -= 1; } } free(arrConnected); arrConnected = copySetToArray(setConnected); } return arrConnected; }
// find a path between two vertices using breadth-first traversal int findPath(HunterView h, LocationID src, LocationID dest, int *path, int road, int rail, int sea) { printf("finding path from %d to %d\n",src,dest); if(src==dest) { printf("trying to get to where you are\n"); path[1] = dest; return 1; } int tmp_city = src; // Temporary store of path_distance for calculations int tmp_distance = 0; int path_distance = 0; // Array of visited cities, if not visited 0, else 1 int visited[NUM_MAP_LOCATIONS] = {0}; // Stores index of the previous city, default value -1 int prev[NUM_MAP_LOCATIONS] = {[0 ... (NUM_MAP_LOCATIONS-1)] = -1}; Queue cityQ = newQueue(); QueueJoin(cityQ, src); // While Queue is not empty and the tmp_city is not the destination city (e.g. when path to destination city from src is found) while (QueueIsEmpty(cityQ) == 0 && tmp_city != dest) { tmp_city = QueueLeave(cityQ); int num_locs; int *locs = connectedLocations(h->g, &num_locs,tmp_city, whoAmI(h), giveMeTheRound(h),road,rail,sea); int i; for (i=0;i<num_locs;i++) { if (!visited[locs[i]]) { QueueJoin(cityQ, locs[i]); prev[locs[i]] = tmp_city; visited[locs[i]] = 1; } } if (tmp_city == dest) { prev[locs[i]] = tmp_city; // Calculating size of path int index = locs[i]; while (index != src) { index = prev[index]; path_distance++; } // Building path array, storing destination first tmp_distance = path_distance-1; path[tmp_distance] = dest; tmp_distance--; // Storing rest of array index = prev[dest]; while (tmp_distance >= 0) { path[tmp_distance] = index; index = prev[index]; tmp_distance--; } break; } } printf("path->"); int j; for(j=0;j<path_distance;j++) { printf("%d->",path[j]); } printf("x\n"); return path_distance; }
int main() { int i; GameView gv; printf("Test basic empty initialisation\n"); PlayerMessage messages1[] = {}; gv = newGameView("", messages1); assert(getCurrentPlayer(gv) == PLAYER_LORD_GODALMING); assert(getRound(gv) == 0); assert(getHealth(gv,PLAYER_DR_SEWARD) == GAME_START_HUNTER_LIFE_POINTS); assert(getHealth(gv,PLAYER_DRACULA) == GAME_START_BLOOD_POINTS); assert(getScore(gv) == GAME_START_SCORE); assert(getLocation(gv,PLAYER_LORD_GODALMING) == UNKNOWN_LOCATION); printf("passed\n"); disposeGameView(gv); printf("Test for Dracula trail and basic functions\n"); PlayerMessage messages2[] = {"Hello","Rubbish","Stuff","","Mwahahah"}; gv = newGameView("GST.... SAO.... HZU.... MBB.... DC?....", messages2); assert(getCurrentPlayer(gv) == PLAYER_LORD_GODALMING); assert(getRound(gv) == 1); assert(getLocation(gv,PLAYER_LORD_GODALMING) == STRASBOURG); assert(getLocation(gv,PLAYER_DR_SEWARD) == ATLANTIC_OCEAN); assert(getLocation(gv,PLAYER_VAN_HELSING) == ZURICH); assert(getLocation(gv,PLAYER_MINA_HARKER) == BAY_OF_BISCAY); assert(getLocation(gv,PLAYER_DRACULA) == CITY_UNKNOWN); assert(getHealth(gv,PLAYER_DRACULA) == GAME_START_BLOOD_POINTS); printf("passed\n"); disposeGameView(gv); printf("Test for encountering Dracula and hunter history\n"); PlayerMessage messages3[] = {"Hello","Rubbish","Stuff","","Mwahahah","Aha!"}; gv = newGameView("GST.... SAO.... HCD.... MAO.... DGE.... GGED...", messages3); assert(getLocation(gv,PLAYER_DRACULA) == GENEVA); assert(getHealth(gv,PLAYER_LORD_GODALMING) == 5); assert(getHealth(gv,PLAYER_DRACULA) == 30); assert(getLocation(gv,PLAYER_LORD_GODALMING) == GENEVA); LocationID history[TRAIL_SIZE]; getHistory(gv,PLAYER_DRACULA,history); assert(history[0] == GENEVA); assert(history[1] == UNKNOWN_LOCATION); getHistory(gv,PLAYER_LORD_GODALMING,history); assert(history[0] == GENEVA); assert(history[1] == STRASBOURG); assert(history[2] == UNKNOWN_LOCATION); getHistory(gv,PLAYER_DR_SEWARD,history); assert(history[0] == ATLANTIC_OCEAN); assert(history[1] == UNKNOWN_LOCATION); printf("passed\n"); disposeGameView(gv); printf("Test for Dracula doubling back at sea, and losing blood points (Hunter View)\n"); PlayerMessage messages4[] = {"Hello","Rubbish","Stuff","","Mwahahah","Aha!","","","","Back I go"}; gv = newGameView("GGE.... SGE.... HGE.... MGE.... DS?.... " "GST.... SST.... HST.... MST.... DD1....", messages4); assert(getLocation(gv,PLAYER_DRACULA) == DOUBLE_BACK_1); getHistory(gv,PLAYER_DRACULA,history); assert(history[0] == DOUBLE_BACK_1); assert(history[1] == SEA_UNKNOWN); assert(getHealth(gv,PLAYER_DRACULA) == GAME_START_BLOOD_POINTS - 4); assert(getCurrentPlayer(gv) == 0); printf("passed\n"); disposeGameView(gv); printf("Test for Dracula doubling back at sea, and losing blood points (Drac View)\n"); PlayerMessage messages5[] = {"Hello","Rubbish","Stuff","","Mwahahah","Aha!","","","","Back I go"}; gv = newGameView("GGE.... SGE.... HGE.... MGE.... DEC.... " "GST.... SST.... HST.... MST.... DD1....", messages5); assert(getLocation(gv,PLAYER_DRACULA) == DOUBLE_BACK_1); getHistory(gv,PLAYER_DRACULA,history); assert(history[0] == DOUBLE_BACK_1); assert(history[1] == ENGLISH_CHANNEL); assert(getHealth(gv,PLAYER_DRACULA) == GAME_START_BLOOD_POINTS - 4); assert(getCurrentPlayer(gv) == 0); printf("passed\n"); disposeGameView(gv); printf("Test for connections\n"); int size, seen[NUM_MAP_LOCATIONS], *edges; gv = newGameView("", messages1); printf("Checking Galatz road connections\n"); edges = connectedLocations(gv,&size,GALATZ,PLAYER_LORD_GODALMING,0,1,0,0); memset(seen, 0, NUM_MAP_LOCATIONS*sizeof(int)); for (i = 0; i< size ; i++) seen[edges[i]] = 1; assert(size == 5); assert(seen[GALATZ]); assert(seen[CONSTANTA]); assert(seen[BUCHAREST]); assert(seen[KLAUSENBURG]); assert(seen[CASTLE_DRACULA]); free(edges); printf("Checking Ionian Sea sea connections\n"); edges = connectedLocations(gv,&size,IONIAN_SEA,PLAYER_LORD_GODALMING,0,0,0,1); memset(seen, 0, NUM_MAP_LOCATIONS*sizeof(int)); for (i = 0; i < size; i++) seen[edges[i]] = 1; assert(size == 7); assert(seen[IONIAN_SEA]); assert(seen[BLACK_SEA]); assert(seen[ADRIATIC_SEA]); assert(seen[TYRRHENIAN_SEA]); assert(seen[ATHENS]); assert(seen[VALONA]); assert(seen[SALONICA]); free(edges); printf("Checking Athens rail connections (none)\n"); edges = connectedLocations(gv,&size,ATHENS,PLAYER_LORD_GODALMING,0,0,1,0); assert(size == 1); assert(edges[0] == ATHENS); free(edges); printf("passed\n"); disposeGameView(gv); return 0; }
// What are the specified player's next possible moves LocationID *whereCanTheyGo(HunterView currentView, int *numLocations, PlayerID player, int road, int rail, int sea) { assert(currentView != NULL); assert(0 <= player && player < NUM_PLAYERS); assert(numLocations != NULL); Round theirNextRound; // check if they're before or after me if(player >= getCurrentPlayer(currentView->g)) { theirNextRound = getRound(currentView->g); } else { theirNextRound = getRound(currentView->g) + 1; } // return value LocationID *ret; // check if first round if(theirNextRound == FIRST_ROUND) { ret = (LocationID *)(malloc(sizeof(LocationID)*NUM_MAP_LOCATIONS)); (*numLocations) = 0; // everywhere! int i; for(i=0;i<NUM_MAP_LOCATIONS;i++) { // dracula can go everywhere except ST_JOSEPH_AND_ST_MARYS if(player != PLAYER_DRACULA || i != ST_JOSEPH_AND_ST_MARYS) { ret[(*numLocations)] = i; (*numLocations)++; } } } else { if(player == PLAYER_DRACULA) { // dracula // dracula's current location LocationID dracLoc = whereIs(currentView, PLAYER_DRACULA); // see if we can infer dracula's location // if valid, do the usual if(validPlace(dracLoc)) { // dracula can't travel by rail even if he wants to ret = connectedLocations(currentView->g, numLocations, whereIs(currentView, PLAYER_DRACULA), theirNextRound, player, road, FALSE, sea); } else { (*numLocations) = 0; // FIXME not sure what to return; probably doesn't matter ret = NULL; } } else { // a hunter ret = connectedLocations(currentView->g, numLocations, getLocation(currentView->g, player), theirNextRound, player, road, rail, sea); } } return ret; }
// What are my (Dracula's) possible next moves (locations) // // * connectedLocations Conditions: // // connectedLocations() returns an array of LocationID that represent // all locations that are connected to the given LocationID. // road, rail and sea are connections should only be considered // if the road, rail, sea parameters are TRUE. // The size of the array is stored in the variable pointed to by numLocations // The array can be in any order but must contain unique entries // Your function must take into account the round and player id for rail travel // Your function must take into account that Dracula can't move to // the hospital or travel by rail but need not take into account Dracula's trail // The destination 'from' should be included in the array // // FREE THIS ARRAY IN THE AI // // This function only returns a list of locations where duckula can go // This does not include HIDE or DOUBLE_BACK. Will need to account for // this somewhere.. somehow LocationID *whereCanIgo(DracView currentView, int *numLocations, int road, int sea) { // whereCanIgo() returns an array of LocationIDs giving // all locations that Dracula could reach in his next move // road and/or sea connections should only be considered // if the road and/or sea parameters are TRUE. // The size of the array is stored in the variable pointed to by numLocations // The array can be in any order but must contain unique entries // Should not include the hospital nor any locations only reachable by rail // The current location should be included in the array // The set of possible locations must be consistent with the rules on Dracula's // movement (e.g. can't MOVE to a location currently in his trail) LocationID *locations; LocationID trail[TRAIL_SIZE]; LocationID myLocation; int i; int j; int rail; rail = 0; myLocation = whereIs(currentView, PLAYER_DRACULA); // printf("in DV.c; whereCanIGo: myLocation: %d (%s)\n", myLocation, idToAbbrev(myLocation)); // printf("here0 connectedLocations(%p, %d, %d, %d, %d, %d, %d, %d)\n", currentView->gv, *numLocations, whereIs(currentView, PLAYER_DRACULA), PLAYER_DRACULA, giveMeTheRound(currentView), road, rail, sea); // fprintf(stderr,"from %d, round %d\n", whereIs(currentView,PLAYER_DRACULA),giveMeTheRound(currentView)); locations = connectedLocations(currentView->gv, numLocations, myLocation, PLAYER_DRACULA, giveMeTheRound(currentView), road, rail, sea); //fprintf(stderr, "in DV.c: connLocs: \n"); //for (i = 0; i < *numLocations; i++) { // fprintf(stderr, "\tlocations[%d]: %d (%s)\n", i, locations[i], idToAbbrev(locations[i])); //} getHistory(currentView->gv, PLAYER_DRACULA, trail); // check locations aren't in the trail except for trail[0] (current location) for (i = 0; i < *numLocations; i++) { // printf("in DV.c: locations[%d] = %d (%s)\n", i, locations[i], idToAbbrev(locations[i])); for (j = 0; j < TRAIL_SIZE; j++) { if (locations[i] == myLocation && idToType(myLocation) == SEA) { // I'm currently at sea. Remove currently location locations[i] = -1; int h; // shuffle the locations one index to the 'left' for (h = i; h < *numLocations; h++) { if ((h+1) < *numLocations) { locations[h] = locations[h+1]; } } *numLocations -= 1; } else if (locations[i] == trail[j] && locations[i] != UNKNOWN_LOCATION && j != 0) { // this location is in the trail, remove it // printf("in DV.c: locations[%d] (%d : %s) == trail[%d] (%d : %s)\n", i, locations[i], idToAbbrev(locations[i]), j, trail[j], idToAbbrev(trail[j])); locations[i] = -1; // printf("\tupdated locations[%d] -> %d\n", i, locations[i]); int h; // shuffle the locations one index to the 'left' for (h = i; h < *numLocations; h++) { if ((h+1) < *numLocations) { locations[h] = locations[h+1]; } } *numLocations -= 1; } } } //fprintf(stderr, "new locs: \n"); //for (i = 0; i < *numLocations; i++) { // fprintf(stderr, "\tin DV.c: locations[%d] (%d : %s)\n", i, locations[i], idToAbbrev(locations[i])); //} return locations; }
void decideMove (HunterView gameState) { printf("at start of code\n"); fflush(stdout); Graph g = newGraph(); char *locations[] = { "AL", "AM", "AT", "BA", "BI", "BE", "BR", "BO", "BU", "BC", "BD", "CA", "CG", "CD", "CF", "CO", "CN", "DU", "ED", "FL", "FR", "GA", "GW", "GE", "GO", "GR", "HA", "JM", "KL", "LE", "LI", "LS", "LV", "LO", "MA", "MN", "MR", "MI", "MU", "NA", "NP", "NU", "PA", "PL", "PR", "RO", "SA", "SN", "SR", "SJ", "SO", "ST", "SW", "SZ", "TO", "VA", "VR", "VE", "VI", "ZA", "ZU", "NS", "EC", "IS", "AO", "BB", "MS", "TS", "IO", "AS", "BS", "C?", "S?", "HI", "D1", "D2", "D3", "D4", "D5", "TP" }; int round = getRound(gameState); PlayerID id = getCurrentPlayer(gameState); LocationID move = getLocation(gameState, id); printf("the original loc is %d and health %d\n",move,getHealth(gameState,id)); char * msg = ""; printf("initialised all variables\n"); fflush(stdout); //set initial locations if (round - id == 0) { if (id == PLAYER_LORD_GODALMING) {move = CASTLE_DRACULA; msg = "camping";} else if (id == PLAYER_DR_SEWARD) move = BELGRADE; else if (id == PLAYER_VAN_HELSING) move = STRASBOURG; else if (id == PLAYER_MINA_HARKER) move = MADRID; registerBestPlay(locations[move], msg); destroyGraph(g); return; } printf("done initial moves\n"); fflush(stdout); //below code will throw errors if LG is killed //if (id == PLAYER_LORD_GODALMING) { registerBestPlay("CD","I'm camping MAN!!!"); return; } srand (time(NULL)); int path[NUM_MAP_LOCATIONS]; int amtLocs = 0; LocationID * adj = connectedLocations(&amtLocs, getLocation(gameState, id), id, round, ANY, g); LocationID target = UNKNOWN_LOCATION; int camper = 0, i, j; printf("setting up connected locs etc\n"); fflush(stdout); // check for campers // if the current player is camping, then the player // will stay camping and ai will return for (i = 0; i < NUM_HUNTERS; i++) { if (getLocation(gameState, i) == CASTLE_DRACULA) { camper = 1; if (id == i) { registerBestPlay("CD", "Staying camping"); destroyGraph(g); free(adj); return; } } } if (!camper) { //if no camper and hunter is shortest dist to castle dracula, move towards castle dracula int hunterDist[NUM_HUNTERS] = {UNKNOWN_LOCATION,UNKNOWN_LOCATION,UNKNOWN_LOCATION,UNKNOWN_LOCATION}; int closestHunter = PLAYER_LORD_GODALMING; for (i = PLAYER_LORD_GODALMING; i < NUM_HUNTERS; i++) { hunterDist[i] = findShortestPath(getLocation(gameState, i), CASTLE_DRACULA, path, ANY, round); if (hunterDist[i] == -1) hunterDist[i] = 1000; //-1 is when there is no path, so don't want him to be shortest if ((hunterDist[closestHunter] > hunterDist[i]) || (hunterDist[closestHunter] == UNKNOWN_LOCATION)) closestHunter = i; } if (closestHunter == id) move = path[1]; } else { LocationID draculaLoc[TRAIL_SIZE]; getHistory (gameState, PLAYER_DRACULA, draculaLoc); //updates Dracula trail for (i = TRAIL_SIZE - 1; i >= 0 ; i--) //locations newer in trail will override older ones target = dracTarget(draculaLoc, i); //we have any useful info on his location... if (target != UNKNOWN_LOCATION) { //Note: Dracula cannot visit any location currently in his trail - hunters should not visit target itself! int pathLen = findShortestPath(getLocation(gameState, id), target, path, ANY, round); //success is any number not -1 if (getLocation(gameState, id) != target && pathLen != -1) { //path found, and not at rest on target (Drac's trail) if (path[1] != target) move = path[1]; //don't move into Dracula's trail (see note above) else move = adj[rand() % amtLocs]; for (i = 0; i < TRAIL_SIZE ; i++) if (path[1] == dracTarget(draculaLoc, i)) move = adj[rand() % amtLocs]; } else move = adj[rand() % amtLocs]; } else { //prevents doubling up of hunters when making a random move, since Dracula 404 int occupied = 0, newLoc = UNKNOWN_LOCATION; move = adj[rand() % amtLocs]; for (j = 0; j < NUM_HUNTERS; j++) if (move == getLocation(gameState, j)) occupied = 1; if (occupied) { for (i = 0; i < amtLocs; i++) { occupied = 0; for (j = 0; j < NUM_HUNTERS; j++) if (adj[i] == getLocation(gameState, j)) occupied = 1; if (!occupied) {newLoc = i; break;} } } if (newLoc != UNKNOWN_LOCATION) move = adj[newLoc]; } } if (target != UNKNOWN_LOCATION) printf("*Moving from %s (%d) to target %s (%d) via %s (%d)*\n", locations[getLocation(gameState, id)], getLocation(gameState, id), locations[target], target, locations[move], move); else printf("*No target - moving from %s (%d) to %s (%d)*\n", locations[getLocation(gameState, id)], getLocation(gameState, id), locations[move], move); if (isLegalMove(gameState, id, move, round, g)) registerBestPlay(locations[move], ""); else { printf("ERROR: Location is invalid! Registering default rest move..."); registerBestPlay(locations[getLocation(gameState, id)], ""); } destroyGraph(g); free(adj); }