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...
in this part of your code:
double* distancecalc (double pos[], double distance[]) {
Distance locat [4] ;
District districts [79] ;
....
for (int u=posi[0]; u<posi[4]; u++) {
locat [u].lat = districts [u].lat ;
locat [u].lng = districts [u]. lng;
....
districts
is not initialized. localt
is getting random values