diff --git a/rute.cpp b/rute.cpp index 0b8acc32caa5714281249cf00c3fc7604ad1b57d..9bf0505f1da0f08887b91b592587762575a4cffc 100644 --- a/rute.cpp +++ b/rute.cpp @@ -112,6 +112,48 @@ bool Rute::erTall(std::string nvn) { return all_of(nvn.begin(), nvn.end(), ::isdigit); } +/** + * @brief + * + * @param fStoppNr + * @param aStoppNr + * @return true + * @return false + */ +bool Rute::erNabo(Stopp* s1, Stopp* s2) { + int fPos, + aPos, + temp, + avstand; + + auto it = find(stoppene.begin(), stoppene.end(), s1); + if (it != stoppene.end()) { // Funn av stoppNr + fPos = distance(stoppene.begin(), it); + } + + auto it2 = find(stoppene.begin(), stoppene.end(), s2); + if (it2 != stoppene.end()) { // Funn av stoppNr + aPos = distance(stoppene.begin(), it2); + } + + if (fPos < aPos) { // Hvis første er før på ruten enn andre + avstand = aPos-fPos; // Setter avstand mellom stopp på ruten + } else if (fPos > aPos) { + temp = fPos; // Gjør om slik at første stopp på ruten kommer først + fPos = aPos; + aPos = temp; + avstand = aPos-fPos; + } else if (fPos == aPos) { // Skal ikke skje + cout << "\nHer er det noe alvorlig galt.\n\n"; + } + + if (avstand == 1) { // Stoppene er naboer + return true; + } + // Stoppene er ikke naboer: + return false; +} + /** * Går gjennom om alle Stopp på en rute for å sjekke om deres * unike nr matcher en nr som bruker mener finnes på ruten @@ -148,7 +190,7 @@ bool Rute::gyldigTid(const int time, const int minutt) { /** * Finner antall minutter mellom et faktisk stopp på ruten * og startstoppestedet på ruten - * + * * @param nr - Et stoppesteds unike nummer * @param retning - Fram eller Tilbake (ulikt startsted) avhengig * av hvilken vei ruten går @@ -181,7 +223,7 @@ int Rute::finnDifferanse(const int nr, const Retning retning) { /** * Henter navn på startstasjonen på en rute - * + * * @param retning Om ruten er Fram (original) eller Tilbake ("baklengs") * @return Navnet på startstopp på rute avhengig av retning * @see Stoppesteder::hentNavnVhaIndeks(...) @@ -198,7 +240,26 @@ string Rute::hentNavn(const Retning retning) { } /** - * TODO: fjernStopp() + * Prøver å finne en peker til et stopp på en rute + * + * @param nr + * @return Stopp* + */ +Stopp* Rute::finnStopp(int nr) { + int nummer; + if (!stoppene.empty()) { // Hvis det finnes stopp på ruten: + // For alle stopp i ruten: + for (auto it = stoppene.begin(); it != stoppene.end(); it++) { + nummer = (*it)->hentNr(); // Henter stoppNr + if (nummer == nr) // Sammenligner + return (*it); // Funn, returnerer peker til rett stopp + } + } + return nullptr; // Ikke funn, returnerer nullptr +} + +/** + * TODO: fjernStopp() * Husk at her må avstanden mellom stoppene være mer enn direkte naboer (>1) * Skal fjerne de i mellom to stoppesteder ikke stoppestedene som blir oppgitt */ @@ -209,7 +270,7 @@ void Rute::fjernStopp() { /** * Leser inn og oppretter en rutetabell for et gitt stoppested på en rute * med utgangspunkt i omregning fra et startsted på ruten - * + * * @param diff - differanse mellom startsted og aktuelt stoppested i minutter * @param start - faktisk startstedsnavn på ruten * @param stSted - faktisk navn på aktuellt stoppested @@ -241,12 +302,12 @@ void Rute::ruteTabell(const int diff, const string start, const string stSted) { startTid = (startT*60)+startM; // Regner ut første avgangstid // Sørger for at starttid er gyldig, samt ikke senere enn 23:53 (1433) - while (!gyldigTid(startT, startM) || startTid > 1433) { + while (!gyldigTid(startT, startM) || startTid > 1433) { cout << "\nUlovlig klokkeslett. Prøv igjen (tt mm): "; cin >> startT >> startM; cin.ignore(); startTid = (startT*60)+startM; } - + while (startT != 0 || startM != 0) { // Så lenge bruker ikke taster 0 0 avgangsTid = startTid+diff; // Må ha en sjekk her for lang tid mellom stoppesteder, som @@ -254,13 +315,13 @@ void Rute::ruteTabell(const int diff, const string start, const string stSted) { // så man ikke får output med et klokkeslett 25:xx f.eks. if (avgangsTid < 1440) { // < 24:00 avgangstider.push_back(avgangsTid); // Legger første avgang - // i vector + // i vector } else { // Omregning av hva som skal i vector, for spesielle // tilfeller, unngå 25:xx f.eks.: avgangstider.push_back(avgangsTid%1440); } - - + + // Leser tid mellom avganger: // Ny sjekk her for å sørge for riktig output til bruker // basert på valgt "fra"-tid. Godtar ikke 6-120 min for @@ -311,7 +372,7 @@ void Rute::ruteTabell(const int diff, const string start, const string stSted) { startTotal = (startT*60)+startM; // Omregning // Sørger for ny lovlig starttid: while ((!gyldigTid(startT, startM) || startTotal <= sluttTotal) - && (startT != 0 || startM != 0)) { + && (startT != 0 || startM != 0)) { cout << "\nUlovlig klokkeslett. Prøv igjen (tt mm): "; cin >> startT >> startM; cin.ignore(); startTotal = (startT*60)+startM; // Omregning @@ -319,10 +380,10 @@ void Rute::ruteTabell(const int diff, const string start, const string stSted) { startTid = (startT*60)+startM; // Omregning } else { // Avslutter innlesning fra bruker hvis slutttid er 23:53 // eller senere (da det må være +1 min minimum til neste - // avgang). + // avgang). startT = 0; startM = 0; // Sørger for stopp av innlesning } - + } cout << "\n\nRutetabell for stoppested: " << stSted << "\n\n"; // Sorterer vektoren, slik at man ikke får duplikat utskrift av @@ -342,7 +403,7 @@ void Rute::ruteTabell(const int diff, const string start, const string stSted) { } else { // Hvis time er mer enn 24 (skjer ved stor avstand) // mellom stoppesteder på en rute, gjør modulo // slik at det ikke skrives ut 25:xx f.eks.: - cout << '\n' << ((timer%24 < 10) ? "0" : "") << timer%24 + cout << '\n' << ((timer%24 < 10) ? "0" : "") << timer%24 << ": " << ((minutter < 10) ? "0" : "") << minutter; } @@ -427,14 +488,18 @@ void Rute::slettData(){ void Rute::smettStopp() { string navn, fNavn, - aNavn; + aNavn, + nNavn; int stoppNr, fStoppNr, aStoppNr, + nStoppNr, indeks, naboIndeks, fIndeks, - aIndeks; + aIndeks, + tid, + storrelse = stoppene.size(); Stopp* fStopp = nullptr; Stopp* aStopp = nullptr; Stopp* nStopp = nullptr; @@ -445,7 +510,7 @@ void Rute::smettStopp() { cout << "\n\nMellom start\n" << "Stoppested (entydig navn / tall / ENTER for å avslutte): "; getline(cin, navn); - + while (navn.size() > 0) { // Så lenge ikke skrevet enter: navn = gStoppestederBase.byttBokstaver(navn); // fjerner æøåÆØÅ @@ -466,19 +531,238 @@ void Rute::smettStopp() { fStoppNr = fIndeks+1; // Setter eget stoppNr if (finnesStopp(fStoppNr)) { // Hvis stoppen finnes på ruta + // Henter peker til eget stoppested i vectoren + fStoppested = gStoppestederBase.finnDuplikat(fNavn); + // Henter peker til eget stopp i listen + fStopp = finnStopp(fStoppNr); // Finne riktige pekere til stoppested og stopp // Starte på neste while for å finne andre stopp? + navn = ""; // Sørger for at man kommer seg ut av whilen } else { + navn = ""; // TEST + cout << "\nStoppen finnes ikke på denne ruten.\n" + << "\nStoppested (entydig navn / tall / ENTER" + << " for å avslutte): "; + getline(cin, navn); //send inn i while igjen, stopp er ikke på ruta } } else { + navn = ""; // TEST + cout << "\nIngen entydig stopp funnet.\n" + << "\nStoppested (entydig navn / tall / ENTER" + << " for å avslutte): "; + getline(cin, navn); //send inn i while igjen, ikke entydig } + } + if (fNavn.size() > 0) { // Hvis suksessfull funn av startsted + cout << "\n\nMellom slutt\n" + << "Stoppested (entydig navn / tall / ENTER for å avslutte): "; + getline(cin, navn); + while (navn.size() > 0) { // Så lenge ikke skrevet enter: + navn = gStoppestederBase.byttBokstaver(navn); // fjerner æøå + if (erTall(navn)) { + stoppNr = stoi(navn); // Hvis kun tall, konverter til int + // Hvis tallet er et faktisk stoppested: + if (gStoppestederBase.finnesIndeks(stoppNr-1)) { + // Henter det faktiske navnet: + navn = gStoppestederBase.hentNavnVhaIndeks(stoppNr); + } + } + // Sjekker entydighet: + aNavn = gStoppestederBase.finnEntydig(navn); + + if (aNavn.size() > 0) { // Hvis entydig navn: + // Henter faktisk indeks for stoppested: + aIndeks = gStoppestederBase.hentIndeksVhaNavn(aNavn); + aStoppNr = aIndeks+1; // Setter eget stoppNr + + if (aStoppNr != fStoppNr) { // Hvis ikke samme stopp 2x på rad + // Finnes stoppen på ruta? + if (finnesStopp(aStoppNr)) { + // Sjekker om stoppene er nabo på ruta: + // Henter peker til egen stopp: + aStopp = finnStopp(aStoppNr); + if (erNabo(fStopp, aStopp)) { + // Henter peker til eget stoppested i vector + aStoppested = gStoppestederBase.finnDuplikat(aNavn); + // Henter peker til eget stopp i ruten + //aStopp = finnStopp(aStoppNr); + navn = ""; // Sørger for at man kommer seg ut av while + } else { + navn = ""; // TEST + // Stoppene er ikke naboer på ruta + cout << "\nStoppene er ikke naboer på ruten.\n" + << "\nStoppested (entydig navn / tall / " + << "ENTER for å avslutte): "; + getline(cin, navn); + } + + } else { + navn = ""; // TEST + // stoppen er ikke på ruta + cout << "\nStoppen er ikke på ruten.\n" + << "\nStoppested (entydig navn / tall / " + << "ENTER for å avslutte): "; + getline(cin, navn); + } + + } else { + navn = ""; // TEST + // andre stopp er samme som første stopp + cout << "\nStart- og sluttstopp kan ikke være lik.\n" + << "\nStoppested (entydig navn / tall / " + << "ENTER for å avslutte): "; + getline(cin, navn); + } + + } else { + navn = ""; // TEST + // IKKE ENTYDIG NAVN + cout << "\nIngen entydig stopp funnet.\n" + << "Stoppested (entydig navn / tall / ENTER" + << " for å avslutte): "; + getline(cin, navn); + } + } } + if (aNavn.size() > 0) { // Hvis suksessfullt funn av stoppsted + cout << "\n\nNye stoppested(er) etter " << fNavn + << " og før " << aNavn << ":\n" + << "Stoppested (entydig navn / tall / ENTER): "; + getline (cin, navn); + + while (navn.size() > 0) { // Så lenge ikke tastet enter: + navn = gStoppestederBase.byttBokstaver(navn); // Fjerner æøå + + if (erTall(navn)) { // Sjekker om navn kun består av tall + stoppNr = stoi(navn); // Hvis kun tall, gjør om til int + // Hvis faktisk stoppested: + if (gStoppestederBase.finnesIndeks(stoppNr-1)) { + // Henter navn + navn = gStoppestederBase.hentNavnVhaIndeks(stoppNr); + } + } + nNavn = gStoppestederBase.finnEntydig(navn); // Sjekker for entydighet + + if (nNavn.size() > 0) { // Hvis entydig navn + // Henter egen indeks + indeks = gStoppestederBase.hentIndeksVhaNavn(nNavn); + nStoppNr = indeks+1; // Setter eget stoppNr + // Hvis ikke stoppen er en av de som skal smettes inn mellom: + if (nStoppNr != aStoppNr && nStoppNr != fStoppNr) { + // Hvis stoppen ikke finnes på ruta fra før: + if (!finnesStopp(nStoppNr)) { + // Finner peker til eget stoppested i vector + nStoppested = gStoppestederBase.finnDuplikat(nNavn); + + // Hvis nabo finnes fra før: + if (nStoppested->finnesNabo(fStoppNr)) { + // Henter naboens indeks: + naboIndeks = nStoppested->hentNaboIndeks(fStoppNr); + // Henter tid til nabo: + tid = nStoppested->hentNaboTid(naboIndeks); + nStopp = new Stopp(nStoppNr, tid); + // Hvordan får jeg satt dette i listen riktig??? + // Insert evt., men skjønner ikke helt hvordan det + // fungerer + auto it = find(stoppene.begin(), stoppene.end(), aStopp); + stoppene.insert(it, nStopp); // Settes inn foran + // slutt stopp i intervall + // Oppdaterer peker og fStoppNr for videre bruk: + fStoppNr = nStoppNr; + fStoppested = nStoppested; + fIndeks = indeks; + cout << "\nTiden mellom stoppestedene er allerede" + << " registrert som " << tid + << " minutter.\n" + << "\nStoppested (entydig navn / tall / " + << "ENTER for å avslutte): "; + getline(cin, navn); + + } else { // Hvis nabo ikke finnes fra før + // Leser tid mellom stopp + tid = lesInt("Tid fra forrige stopp", 1, 10); + // Oppdaterer forrige stopps nabovektor + fStoppested->settNaboIndeks(indeks); + // Oppdaterer forrige stopps tid til nabo vektor + fStoppested->settNaboTid(tid); + // Oppdaterer egen stopps nabovektor + nStoppested->settNaboIndeks(fIndeks); + //Oppdaterer nåværende stopps tid til nabo vektor + nStoppested->settNaboTid(tid); + // Oppretter ny stopp på ruten + nStopp = new Stopp(nStoppNr, tid); + // Setter inn på rett sted (1 foran bakerst i intervall): + auto it = find(stoppene.begin(), stoppene.end(), aStopp); + stoppene.insert(it, nStopp); + // Oppdaterer variabler for videre bruk: + fStoppNr = nStoppNr; + fStoppested = nStoppested; + fIndeks = indeks; + + cout << "\n\nStoppested (entydig navn / tall / " + << "ENTER for å avslutte): "; + getline(cin, navn); + } + } else { + navn = ""; // TEST + cout << "\nStoppet finnes allerede på ruten.\n" + << "\nStoppested (entydig navn / tall / " + << "ENTER for å avslutte): "; + getline(cin, navn); + // Stoppen finnes allerede på ruten + } + } else { + navn = ""; // TEST + cout << "\nStoppet finnes allerede på ruten.\n" + << "\nStoppested (entydig navn / tall / " + << "ENTER for å avslutte): "; + getline(cin, navn); + // Stoppen er en av de som skal smettes inn mellom + } + + } else { + navn = ""; // TEST + cout << "\nIngen entydig stopp funnet.\n" + << "Stoppested (entydig navn / tall / ENTER" + << " for å avslutte): "; + getline(cin, navn); + } + } + } + // Hvis minimum et nytt stopp lagt til på ruten: + if (stoppene.size() > storrelse) { + cout << "\n\nFra " << nNavn << " til " << aNavn << ":\n"; + // Hvis nabo finnes fra før: + if (aStoppested->finnesNabo(nStoppNr)) { + naboIndeks = aStoppested->hentNaboIndeks(nStoppNr); + tid = nStoppested->hentNaboTid(naboIndeks); + aStopp->nr = tid; // oppdaterer tid til forrige nabo + cout << "\nTiden mellom stoppestedene er allerede " + << "registrert som " << tid << " minutter.\n\n"; + + skrivRute(Fram); // Skriver oppdaterte ruten forlengs + + } else { // Nabo finnes ikke fra før: + // Leser tid mellom stopp + tid = lesInt("Tid fra forrige stopp", 1, 10); + // Oppdaterer forrige stopps nabovektor + nStoppested->settNaboIndeks(aIndeks); + // Oppdaterer forrige stopps tid til nabo vektor + nStoppested->settNaboTid(tid); + // Oppdaterer egen stopps nabovektor + aStoppested->settNaboIndeks(indeks); + // Oppdaterer egen stopps tid til nabo vektor + aStoppested->settNaboTid(tid); + aStopp->nr = tid; // oppdaterer tid til forrige nabo + skrivRute(Fram); // skriver oppdatert rute forlengs + } + } } /** @@ -531,13 +815,13 @@ void Rute::lesData() { // Henter et stoppesteds faktiske indeks i vector: indeks = gStoppestederBase.hentIndeksVhaNavn(fNavn); // Hvis stopp ikke finnes fra før på ruten: - if (!finnesStopp(indeks+1)) { - + if (!finnesStopp(indeks+1)) { + if (stoppene.size() > 0) { // Hvis ikke første stopp på ruten // Henter peker til eget stoppested: nStopp = gStoppestederBase.finnDuplikat(fNavn); // Hvis nabo finnes fra før: - if (nStopp->finnesNabo(naboIndeks+1)) { + if (nStopp->finnesNabo(naboIndeks+1)) { // Henter naboens indeks naboIndeks = nStopp->hentNaboIndeks(naboIndeks+1); // Henter tid til naboen: @@ -546,7 +830,7 @@ void Rute::lesData() { nyStopp = new Stopp(indeks+1, tidTilF); stoppene.push_back(nyStopp); // Legges i lista // Oppdaterer naboindeks for videre bruk: - naboIndeks = indeks; + naboIndeks = indeks; cout << "\nTiden mellom stoppestedene er allerede" << " registrert som " << tidTilF << " minutter.\n"; @@ -581,11 +865,11 @@ void Rute::lesData() { // forrige nabo å være 0, da første stopp på ruten stoppene.push_back(nyStopp); // Legges til ruten // Oppdaterer naboindeks for videre bruk - naboIndeks = indeks; + naboIndeks = indeks; } // Setter peker til forrige stopp til å peke på riktig // stoppested for videre bruk: - fStopp = nStopp; + fStopp = nStopp; } else // Stoppet finnes allerede på ruten: cout << "\nStoppet er allerede registrert på ruten!\n"; } else { // Hvis ikke entydig: diff --git a/rute.h b/rute.h index 451328ed3b81ea61fe08be59e2366ffca404eccd..05868fd1c306abd23c6bd7225b1ef869fc8bf308 100644 --- a/rute.h +++ b/rute.h @@ -36,11 +36,13 @@ class Rute { Rute(); Rute(std::ifstream & inn); bool erListeGyldig(); + bool erNabo(Stopp* s1, Stopp* s2); bool erTall(std::string nvn); bool finnesStopp(const int nr); bool gyldigTid(const int time, const int minutt); int finnDifferanse(const int nr, const Retning retning); std::string hentNavn(const Retning retning); + Stopp* finnStopp(int nr); void fjernStopp(); void ruteTabell(const int diff, const std::string start, const std::string stSted);