I have a problem with my code. So our task was to create a code, which inputs info from a txt file (includes name of a city with its longitude and latitude) and make a game which asks "What city is closest to _____" and gives you 3 options, from which you have to pick. Then it tells you correct/incorrect and shows you the distances. The problem is, that my code doesn't calculate the distance between the towns in kilometres, but a really strange form. the result is e.g. 3.582e-307 and similar. Do you know what could be the problem?
#include <iostream>
#include <cstdlib>
#include <stdlib.h>
#include <fstream>
#include <sstream>
#include <string>
#include <time.h>
#include <random>
#include <numeric>
#include <math.h>
#include <cmath>
#include <algorithm>
#include <ctime>
#define PI 3.14159265
using namespace std;
struct District {
double lng ;
double lat ;
string city ;
};
struct Distance {
double lng;
double lat;
};
//void for changing degrees to rad
double dtr(double deg) {
return (deg * PI / 180);
};
//void calculation of distance
// this doesnt work correctly - the output isnt the distance in KM, i used the formula from - https://en.m.wikipedia.org/wiki/Great-circle_distance
double* distancecalc (double pos[], double distance[]) {
Distance locat [4] ;
District districts [79] ;
double posi [4];
for (int x=0; x<4; x++) {
posi [x] = pos [x] ;
}
for (int u=posi[0]; u<posi[4]; u++) {
locat [u].lat = districts [u].lat ;
locat [u].lng = districts [u]. lng;
locat [u].lat = dtr(locat [u].lat );
locat [u].lng =dtr (locat [u].lng) ;
}
//calculate the distance between cities (0 (base) and 1-3)
for (int u=0; u<4; u++) {
double ax = locat[0].lat, ay = locat[0].lng, bx = locat[u].lat, by = locat[u].lng;
distance[u] = acos (sqrt(pow(sin((bx-ax)/2.0), 2.0)+cos(ax)*cos(bx)*pow(sin((by-ay)/2.0),2.0))) * 2 * 6371;
return distance ;
}
}
int main () {
int z=1;
do { districts [79] ;
ifstream inputFile;
inputFile.open ("districts.txt") ;
if (!inputFile.is_open()){
cout << "opening txt document" << endl;
return 0 ;
}
//shuffle
int line ;
stringstream ss;
string sdouble ;
for (line=0; line<79; line++) {
getline(inputFile, districts[line].city, ';') ;
getline(inputFile, sdouble, ';') ;
ss<< sdouble;
ss>> districts[line].lng ;
getline(inputFile, sdouble, ';' ) ;
ss<<sdouble;
ss>>districts[line].lat;
getline(inputFile, sdouble) ;
}
//shuffle the cities+ coordinates- array
srand(time(NULL));
double tempn;
int pos1,pos2;
string temp;
for (int i = 0; i < 79; ++i){
pos1 = rand()%79;
pos2 = rand()%79;
temp = districts [pos1].city ;
districts [pos1].city = districts [pos2].city;
districts [pos2].city = temp;
tempn = districts [pos1].lat;
districts [pos1].lat = districts [pos2].lat ;
districts [pos2].lat = tempn;
tempn = districts [pos1].lng ;
districts [pos1].lng = districts [pos2].lng ;
districts [pos2].lng = tempn;
}
//game
double pos [4];
double distance [3];
int loop=0, answer=0, guess, total=0;
do {
double min=999999;
//cout - city + options
cout<< endl ;
cout << "Which city is the closest to "<< districts[loop].city<< "? Pick one of the following: " <<endl;
pos [1] = loop;
loop++ ;
cout << "1) " << districts[loop].city << endl;
pos [2]= loop;
loop++ ;
cout << "2) " << districts[loop].city << endl;
pos [3] = loop;
loop++ ;
cout << "3) " << districts[loop].city << endl;
pos [4] = loop;
loop++ ;
//calculate the difference+ find answer (which is the closest)
cout << "Write your selection: " ;
cin>> guess;
for (int x=1; x<4; x++) {
if (min>distance[x] ) {
min= distance[x];
answer= x;
}
}
//if you guess the correct answer -
if (guess==answer) {
total++;
cout<< "Correct! The distances are: " << endl;
}
// if you guess the incorrect answer-
else {
cout<< "Incorrect! The distances are:" <<endl;
}
//witing the distances between 1 city
cout<< "1) " << districts[loop-3].city << "- " << distance [1] << endl;
cout<< "2) " << districts[loop-2].city << "- " << distance [2] << endl;
cout<< "3) " << districts[loop-1].city << "- " << distance [3] << endl << endl;
for (int u=0 ; u< 80; u++) {
cout << "-" ;
}
} while(loop<40) ;
//end of game
cout << endl << "Conratulations, you finished the game! Your score is: " << total << " out of 10" << endl;
int selection ;
cout <<endl << "Do you want to play again?" << endl << "1= Yes" << endl << "0= No" << endl;
cout << "Your selection: " ;
cin>> selection;
if (selection== 0) {
z= 0;
}
else {
z=1;
if (system("CLS")) system("clear") ;
}
} while (z==1 );
}
**END OF CODE**
Your latitudes and longitudes are in degrees, right? The n you can avoid calling a function to transform them to radians:
constexpr double DEG2RAD = 3.141592653589793 / 180;
So that:
for (int u=posi[0]; u<posi[4]; u++) {
locat [u].lat = districts [u].lat * DEG2RAD;
locat [u].lng = districts [u].lng * DEG2RAD;
}
Then, in the link you posted the formula is different, you use acos
instead of asin
, but most of all you didn't pass districts[]
to the function, so it is local to that function and uninitialized. You have to decide if make that array global or not.
Then you have to call distancecalc()
somewhere...