-
Frederik Simonsen authoredFrederik Simonsen authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
rute.cpp 9.19 KiB
/**
* Kode-fil for rute-klassen
*
* @file rute.cpp
* @author Sondre Sand & Frederik Simonsen
*/
#include <algorithm> //all_of
#include <iostream>
#include <iomanip>
#include <list>
#include <fstream>
#include "rute.h"
#include "stoppested.h"
#include "stoppesteder.h"
#include "LesData3.h"
using namespace std;
extern Stoppesteder gStoppestederBase;
//********STOPP FUNKSJONER*******************
/**
* Construct a new Stopp:: Stopp object
*
* @param stoppNr
* @param antMin
*/
Stopp::Stopp(const int stoppNr, const int antMin) {
nr = stoppNr; minutter = antMin;
}
/**
* Henter en stopps unike nr
*
* @return Et stoppesteds unike nr
*/
int Stopp::hentNr() {
return nr;
}
/**
* skrivTilFil(...)
*
* @param ut
*/
void Stopp::skrivTilFil(ofstream & ut) {
ut << nr << ' ' << minutter << '\n';
}
//********RUTE FUNKSJONER*******************
/**
* Rute()
*/
Rute::Rute() {
// Gjør ingenting, men må være her så man kan opprette buss/bane
}
/**
* Opretter en ny rute fra fil
*
* @param inn filen det leses fra
*/
Rute::Rute(ifstream & inn) {
int antStopp,
stoppNr,
antMin;
inn >> antStopp; inn.ignore();
for (int i = 0; i < antStopp; i++) {
inn >> stoppNr >> antMin; inn.ignore();
stoppene.push_back(new Stopp(stoppNr, antMin));
}
}
/**
* -sjekker om lista er mer en 1 entry.
*
* @return true
* @return false
*/
bool Rute::erListeGyldig(){
if(stoppene.size() > 1){
return true;
}
return false;
}
/**
* @brief
*
* @param nvn
* @return true
* @return false
*/
bool Rute::erTall(std::string nvn) {
return all_of(nvn.begin(), nvn.end(), ::isdigit);
}
/**
* Sjekker om stopp er lagt til i ruta allerede
*
* @param nr
* @return true
* @return false
* @see Stopp::hentNr()
*/
bool Rute::finnesStopp(const int indeks) {
for (auto it = stoppene.begin(); it != stoppene.end(); it++) {
if ((*it)->hentNr() == indeks)
return true;
}
return false;
}
/**
* skrivRetninger(...) brukes med R T
*
*/
void Rute::skrivRetninger() const {
// Hjelpevariabler for å hente stasjonsnavnene knyttet til ruten:
int startIndeks = stoppene.front()->hentNr(),
stoppIndeks = stoppene.back()->hentNr();
string startStasjon = gStoppestederBase.hentNavnVhaIndeks(startIndeks),
endeStasjon = gStoppestederBase.hentNavnVhaIndeks(stoppIndeks);
// Skriver ut start- og endestasjon for ruten i begge retninger:
cout << "\nFram: Retningen: " << startStasjon << " - "
<< endeStasjon << "\nTilbake: Retningen: "
<< endeStasjon << " - " << startStasjon << '\n';
}
/**
* skriver rute forlengs eller baklengs
*
* @param retning forlengs eller baklengs
* @see Stoppesteder::hentNavnVhaIndeks(...)
*/
void Rute::skrivRute(const Retning retning) {
int minF = 0,
indeks = 0,
totMin = 0;
string navn;
if (retning == Fram) {
for (auto it = stoppene.begin(); it != stoppene.end(); it++) {
indeks = (*it)->nr;
minF = (*it)->minutter;
navn = gStoppestederBase.hentNavnVhaIndeks(indeks);
totMin += minF;
cout << setw(25) << navn << " - " << setw(2) << minF
<< " min fra forrige (" << setw(3) << totMin
<< " min fra rutestart)\n";
}
}
if (retning == Tilbake) {
for (auto it = stoppene.rbegin(); it != stoppene.rend(); it++) {
indeks = (*it)->nr;
navn = gStoppestederBase.hentNavnVhaIndeks(indeks);
cout << setw(25) << navn << " - " << setw(2) << minF
<< " min fra forrige (" << setw(3) << totMin
<< " min fra rutestart)\n";
minF = (*it)->minutter;
totMin += minF;
}
}
}
/**
* @brief - sletter siste entry i stoppene.
*
*/
void Rute::slettData(){
stoppene.clear();
}
/**
* Leser og oppretter stopp for en ny rute
*
* @see Stoppesteder::byttBokstaver(...)
* @see Stoppesteder::finnesIndex(...)
* @see Stoppesteder::hentNavnVhaIndex(...)
* @see Stoppesteder::finnEntydig(...)
* @see Stoppesteder::finnDuplikat(...)
* @see Rute::finnesStopp(...)
* @see Stoppested::finnesNabo(...)
* @see Stoppested::hentNaboIndeks(...)
* @see Stoppested::hentNaboTid(...)
* @see Stoppested::settNaboIndeks(...)
* @see Stoppested::settNaboTid(...)
*/
void Rute::lesData() {
string navn,
fNavn,
nNavn;
int stoppNr = 0,
indeks = 0,
naboIndeks = 0,
tidTilF = 0;
Stopp* nyStopp = nullptr;
Stoppested* fStopp = nullptr;
Stoppested* nStopp = nullptr;
cout << "\nStoppested (entydig navn / tall / ENTER for å avslutte): ";
getline(cin, navn);
while (navn.size() > 0) { //Kjør så lenge ikke blank/enter er trykket.
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
if(gStoppestederBase.finnesIndeks(stoppNr-1)){ //@see finnesIndeks, funker dette?
navn = gStoppestederBase.hentNavnVhaIndeks(stoppNr); // Hent navn
}
}
fNavn = gStoppestederBase.finnEntydig(navn); // Sjekker for entydighet
if (fNavn.size() > 0) { // Hvis entydig navn:
cout << '\n' << fNavn << '\n';
indeks = gStoppestederBase.hentIndeksVhaNavn(fNavn);
if (!finnesStopp(indeks+1)) { // Hvis stopp ikke finnes fra før på ruten
if (stoppene.size() > 0) { // Hvis ikke første stopp på ruten
nStopp = gStoppestederBase.finnDuplikat(fNavn);
if (nStopp->finnesNabo(naboIndeks+1)) { // Hvis nabo finnes fra før
naboIndeks = nStopp->hentNaboIndeks(naboIndeks+1);
tidTilF = nStopp->hentNaboTid(naboIndeks);
nyStopp = new Stopp(indeks+1, tidTilF);
stoppene.push_back(nyStopp);
naboIndeks = indeks;
cout << "\nTiden mellom stoppestedene er allerede registrert som "
<< tidTilF << " minutter.\n";
} else { // Hvis nabo ikke finnes fra før:
tidTilF = lesInt("Tid fra forrige stopp", 1, 10); // Leser tid til forrige nabo
nStopp = gStoppestederBase.finnDuplikat(fNavn); // Finner egen peker
fStopp->settNaboIndeks(indeks); // Oppdaterer forrige stopps nabovektor
fStopp->settNaboTid(tidTilF); // Oppdaterer forrige stopps tid til nabo
nStopp->settNaboIndeks(naboIndeks); // Oppdaterer nåværende stopps nabovektor
nStopp->settNaboTid(tidTilF); // Oppdaterer naværende stopps tid til nabo
nyStopp = new Stopp(indeks+1, tidTilF); // Oppretter ny stopp på ruten
stoppene.push_back(nyStopp); // Stoppen legges til ruten
naboIndeks = indeks;
}
} else { // Hvis første stopp på ruten
nStopp = gStoppestederBase.finnDuplikat(fNavn); // Peker til riktig
nyStopp = new Stopp(indeks+1, 0); // Setter stopp sitt nr
// til å korrespondere med indeks i vector, og tid til
// forrige nabo å være 0, da første stopp på ruten
stoppene.push_back(nyStopp); // Legges til listen
naboIndeks = indeks;
}
nNavn = fNavn; // Setter nåværende nabo til å være forrige navn
fStopp = nStopp; // Setter forrige stopp til å bli nåværende stopp
} else
cout << "\nStoppet er allerede registrert på ruten!\n";
} else { // Hvis ikke entydig:
cout << "\nIkke funnet (den entydige) stoppestedet!\n";
}
// Forsøker å lese evt. ny eller korrekt stopp:
cout << "\nStoppested (entydig navn / tall / ENTER for å avslutte): ";
getline(cin, navn);
}
cout << "\nOk, du angrer og ønsker ikke å legge til ny rute.\n";
}
/**
* skrivBeskrivelse()
* skriver forlengs og baklengs
*
* @see Rute::skrivRute(...)
*/
void Rute::skrivBeskrivelse() {
cout << "Ruten:\n";
skrivRute(Fram);
cout << "\n\n";
skrivRute(Tilbake);
}
/**
* Skriver ut en rute
* Første-siste stopp
*
* @see Stoppesteder::hentNavnVhaIndeks(...)
*/
void Rute::skrivData() const {
int startIndeks,
stoppIndeks;
string startNavn,
stoppNavn;
startIndeks = stoppene.front()->hentNr(); // Henter startsteds unike nr
stoppIndeks = stoppene.back()->hentNr(); // Henter stopsteds unike nr
startNavn = gStoppestederBase.hentNavnVhaIndeks(startIndeks);
stoppNavn = gStoppestederBase.hentNavnVhaIndeks(stoppIndeks);
cout << startNavn << " - " << stoppNavn;
}
/**
* @brief skrivKort() (virtuell)
*
*/
void Rute::skrivKort() const {
}
/**
* skriver rute til fil
*
* @param ut fila det skrives til
* @see Stopp::skrivTilFil(...)
*/
void Rute::skrivTilFil(ofstream & ut) {
ut << stoppene.size() << '\n';
for (auto it = stoppene.begin(); it != stoppene.end(); it++)
(*it)->skrivTilFil(ut);
}