// 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 shortestPath(Map g, LocationID start, LocationID end, LocationID path[], TransportID trans[]) { // TODO: replace the code by a shortest path algorithm // a valid path from London to Paris // just to show what kinds of values are in the arrays //path[0] = LONDON; trans[0] = ANY; //path[1] = PLYMOUTH; trans[1] = ROAD; //path[2] = LE_HAVRE; trans[2] = BOAT; //path[3] = PARIS; trans[3] = RAIL; assert(g != NULL); //printf("%d %d\n", start, end); int *visited = malloc (g->nV * sizeof(int)); int *pathway = malloc (g->nV * sizeof(int)); int i = 0; int order = 0; while (i < g->nV){ visited[i] = pathway[i] = -1; i++; } Queue q = newQueue(); VList current; int isFound = 0; //int loop = 0; QueueJoin(q, start); while (!QueueIsEmpty(q)) { int w = QueueLeave(q); //printf("here is w %d %d %d\n", g->nV, w, visited[w]); if (visited[w] == -1) { //printf("if\n"); visited[w] = order; order++; //printf("%d\n", order); for (current = g->connections[w]; current != NULL; current = current->next) { QueueJoin(q, current->v); if (pathway[current->v] == -1) { pathway[current->v] = w; //printf("isFound is %d\n", isFound); } if (current->v == end) { isFound = 1; break; } } } else { continue; } } int distance = -1; if (!isFound) { //printf("It's not found\n"); path[0] = -1; } else { //printf("It's found\n"); int j = end; distance = 1; //printf("first\n"); while (j != start) { j = pathway[j]; distance++; } //printf("after first\n"); //printf("count = %d\n", count); path[0] = start; path[distance-1] = end; //printf("%d->%d\n",path[0],path[count] ); j = end; int x = distance; i = distance-1; //printf("second\n"); while (j != start) { path[--i] = pathway[j]; trans[--x] = g->connections[j]->type; j = pathway[j]; } } return distance; }
// road rail and sea are flags, TRUE or FALSE (const) LocationID * connectedLocations(HunterView currentView, int * numLocations, LocationID from, PlayerID player, Round round, int road, int rail, int sea) { assert(from >= 0); int i, j; int isConnected[NUM_MAP_LOCATIONS]; int numIsConnected = 0; int railTravelLength = (round + player) % 4; for (i = 0; i < NUM_MAP_LOCATIONS; i++) { // long if statement which essentially says: // if want road, and connected by road, // or want rail, and allowed to use rail, and connected by rail, // or want sea, and connected by sea. if ((road && (currentView->map[from][i] == ROAD || currentView->map[from][i] == BOTH)) || (rail && player != PLAYER_DRACULA && railTravelLength > 0 && (currentView->map[from][i] == RAIL || currentView->map[from][i] == BOTH)) || (sea && currentView->map[from][i] == SEA)) { isConnected[i] = TRUE; numIsConnected++; } else { isConnected[i] = FALSE; } } // adds "from" here to avoid being overwritten by above code // doing this saves putting extra checks in above code if (!isConnected[from]) { isConnected[from] = TRUE; numIsConnected++; } // BFS for finding rail travel connections // if railTravelLength is 1, already checked above to avoid unnecessary BFS if (rail && player != PLAYER_DRACULA && railTravelLength > 1) { Queue q = newQueue(); int distance[NUM_MAP_LOCATIONS]; for (i = 0; i < NUM_MAP_LOCATIONS; i++) { distance[i] = -1; } distance[from] = 0; QueueJoin(q, from); while (!QueueIsEmpty(q)) { LocationID l = QueueLeave(q); if (distance[l] >= railTravelLength) { break; // already searched deep enough } for (i = 0; i < NUM_MAP_LOCATIONS; i++) { if (distance[i] == -1 && (currentView->map[l][i] == RAIL || currentView->map[l][i] == BOTH)) { distance[i] = 1 + distance[l]; QueueJoin(q, i); } } } dropQueue(q); for (i = 0; i < NUM_MAP_LOCATIONS; i++) { if (distance[i] >= 0 && distance[i] <= railTravelLength && !isConnected[i]) { isConnected[i] = TRUE; numIsConnected++; } } } // Copy any reached location into new array to return LocationID * connections = malloc(sizeof(LocationID) * numIsConnected); *numLocations = numIsConnected; i = 0; for (j = 0; j < NUM_MAP_LOCATIONS; j++) { if (isConnected[j]) { connections[i] = j; i++; } } assert(i == numIsConnected); // will fail if numIsConnected was miscalculated return connections; }