diff --git a/Aufgabenblock_2/ClientSocket.cpp b/Aufgabenblock_2/ClientSocket.cpp new file mode 100644 index 0000000..74e2c6b --- /dev/null +++ b/Aufgabenblock_2/ClientSocket.cpp @@ -0,0 +1,110 @@ +/** + * ClientSocket implementation + * + * @version 0.2 + * @copyright (c) Robert Uhl 2009 + */ + +#include "ClientSocket.h" + +//#define DEBUG DEBUG // Debugging an/aus(auskommentieren!) + +/** + * Öffentliche Methoden + */ + +/** + * Konstruktor, der den Typ des Sockets übergeben bekommt + */ +ClientSocket::ClientSocket(const int iType) : p_iType(iType), p_iSocket(-1), p_bVerbunden(false) { + p_iSocket = socket(AF_INET, p_iType, 0); // Socket anlegen + + if (p_iSocket == -1) { + std::cerr << "--> Socket konnte nicht angelegt werden!" << std::endl; + } +} + +/** + * Destruktor + */ +ClientSocket::~ClientSocket(void) { + if (p_bVerbunden) { + Disconnect(); + } +} + +/** + * Verbindung zum Server aufnehmen + * @return bool true wenn Verbindung erfolgreich aufgebaut + */ +bool ClientSocket::Connect(const std::string& sServer, const unsigned short iPort) { + struct sockaddr_in strAdresse; + struct in_addr strInAdresse; + struct hostent* strHost; + + if (p_iSocket == -1) { + std::cerr << "--> Connect(): Socket wurde nicht angelegt!" << std::endl; + return false; + } + + if (p_bVerbunden) { + std::cerr << "--> Connect(): Achtung, noch verbunden! Keine neue Verbindung angelegt!" << std::endl; + return false; + } + + // Domainnamen in IP auflösen + strHost = gethostbyname(sServer.c_str()); + +#ifdef DEBUG + std::cout << "Host: " << strHost->h_name << std::endl; + std::cout << "IP: " << inet_ntoa( **(struct in_addr**) strHost->h_addr_list) << std::endl; + std::cout << "Port: " << iPort << std::endl; +#endif + + // IP-Adresse für connect() erzeugen + strInAdresse = **(struct in_addr**) strHost->h_addr_list; + strAdresse.sin_family = AF_INET; + strAdresse.sin_port = htons(iPort); + strAdresse.sin_addr = strInAdresse; + + // Verbindung aufbauen + if (connect(p_iSocket, (struct sockaddr*) &strAdresse, sizeof(strAdresse)) == -1) { + std::cerr << "--> connect() nicht erfolgreich!" << std::endl; + return false; + } else { + p_bVerbunden = true; + return true; + } +} + +/** + * Verbindung zum Server abbauen + */ +void ClientSocket::Disconnect(void) { + if (close(p_iSocket) == -1) { + std::cerr << "--> Disconnect(): Konnte die Verbindung nicht schliessen!" << std::endl; + } else { + p_bVerbunden = false; + } +} + +/** + * Sendet etwas über das Socket + */ +bool ClientSocket::Send(const void* vDaten, ssize_t data_len) { + if (p_iSocket == -1) { + std::cerr << "--> Send(): Socket wurde nicht angelegt!" << std::endl; + return false; + } else if (!p_bVerbunden) { + std::cerr << "--> Send(): Noch keine Verbindung aufgebaut!" << std::endl; + return false; + } + + // Senden + if (send(p_iSocket, vDaten, data_len, 0) != data_len) { + std::cerr << "--> Send(): Es konnte nicht alles gesendet werden!" << std::endl; + return false; + } + + return true; +} diff --git a/Aufgabenblock_2/ClientSocket.h b/Aufgabenblock_2/ClientSocket.h new file mode 100644 index 0000000..868e0f5 --- /dev/null +++ b/Aufgabenblock_2/ClientSocket.h @@ -0,0 +1,37 @@ +/** + * ClientSocket header + * + * @version 0.2 + * @copyright (c) Robert Uhl 2009 + */ + +#ifndef CLIENTSOCKET_H +#define CLIENTSOCKET_H + +#include +#include +#include +#include +#include +#include +#include + +class ClientSocket { + public: + // Konstruktor/Destruktor + ClientSocket(const int iType); // als Type z.B. SOCK_STREAM für TCP + ~ClientSocket(void); + + // Methoden + bool Connect(const std::string& sServer, const unsigned short iPort);// auf Server mit Namen/IP sServer verbinden mit Portangabe + void Disconnect(void); + bool Send(const void* vDaten, ssize_t data_len); + + private: + // Variablen + const int p_iType; // Socket-Type + int p_iSocket; // Socket-Nummer + bool p_bVerbunden; // true = verbunden +}; + +#endif // CLIENTSOCKET_H diff --git a/Aufgabenblock_2/FahrAusnahme.cpp b/Aufgabenblock_2/FahrAusnahme.cpp new file mode 100644 index 0000000..4627ad1 --- /dev/null +++ b/Aufgabenblock_2/FahrAusnahme.cpp @@ -0,0 +1,18 @@ +#include "FahrAusnahme.h" + +FahrAusnahme::FahrAusnahme(Fahrzeug *pFahrzeug, Weg *pWeg) : + p_pFahrzeug(pFahrzeug), + p_pWeg(pWeg) +{ } + +FahrAusnahme::~FahrAusnahme() +{ } + +Weg * FahrAusnahme::getWeg() { + return p_pWeg; +} + +Fahrzeug * FahrAusnahme::getFahrzeug() { + return p_pFahrzeug; +} + diff --git a/Aufgabenblock_2/FahrAusnahme.h b/Aufgabenblock_2/FahrAusnahme.h new file mode 100644 index 0000000..a705a15 --- /dev/null +++ b/Aufgabenblock_2/FahrAusnahme.h @@ -0,0 +1,22 @@ +#ifndef FAHRAUSNAHME_H_ +#define FAHRAUSNAHME_H_ + +#include "Fahrzeug.h" +#include "Weg.h" + +class FahrAusnahme { +public: + FahrAusnahme(Fahrzeug *pFahrzeug, Weg *pWeg); + virtual ~FahrAusnahme(); + + Weg * getWeg(); + Fahrzeug * getFahrzeug(); + + virtual void vBearbeiten() = 0; + +protected: + Fahrzeug *p_pFahrzeug; + Weg *p_pWeg; +}; + +#endif /* FAHRAUSNAHME_H_ */ diff --git a/Aufgabenblock_2/FzgFahren.cpp b/Aufgabenblock_2/FzgFahren.cpp new file mode 100644 index 0000000..f0c1528 --- /dev/null +++ b/Aufgabenblock_2/FzgFahren.cpp @@ -0,0 +1,26 @@ +#include + +#include "FzgFahren.h" +#include "Fahrzeug.h" +#include "Streckenende.h" + +FzgFahren::FzgFahren(Weg *pWeg) : FzgVerhalten(pWeg) +{ } + +FzgFahren::~FzgFahren() +{ } + +double FzgFahren::dStrecke(Fahrzeug *pFz, double dDelta) { + double dStrecke = pFz->dGeschwindigkeit() * dDelta; + + if (pFz->getAbschnittStrecke() >= p_pWeg->getLaenge()) { /* bereits zuweit gefahren */ + throw Streckenende(pFz, p_pWeg); + } + else if (pFz->getAbschnittStrecke() + dStrecke > p_pWeg->getLaenge()) { /* fahre nur bis zum Streckenende */ + return p_pWeg->getLaenge() - pFz->getAbschnittStrecke(); + } + else { /* fahre maximal mögliche Strecke */ + return dStrecke; + } +} + diff --git a/Aufgabenblock_2/FzgFahren.h b/Aufgabenblock_2/FzgFahren.h new file mode 100644 index 0000000..acd821f --- /dev/null +++ b/Aufgabenblock_2/FzgFahren.h @@ -0,0 +1,14 @@ +#ifndef FZGFAHREN_H_ +#define FZGFAHREN_H_ + +#include "FzgVerhalten.h" + +class FzgFahren: public FzgVerhalten { +public: + FzgFahren(Weg *pWeg); + virtual ~FzgFahren(); + + double dStrecke(Fahrzeug *pFz, double dDelta); +}; + +#endif /* FZGFAHREN_H_ */ diff --git a/Aufgabenblock_2/FzgParken.cpp b/Aufgabenblock_2/FzgParken.cpp new file mode 100644 index 0000000..77dedb0 --- /dev/null +++ b/Aufgabenblock_2/FzgParken.cpp @@ -0,0 +1,23 @@ +#include + +#include "FzgParken.h" +#include "Fahrzeug.h" +#include "Losfahren.h" + +extern double dGlobaleZeit; + +FzgParken::FzgParken(Weg *pWeg, double dStartZeit) : FzgVerhalten(pWeg) { + p_dStartZeit = dStartZeit; +} + +FzgParken::~FzgParken() +{ } + +double FzgParken::dStrecke(Fahrzeug *pFz, double dDelta) { + if (p_dStartZeit > dGlobaleZeit) { + return 0.0; + } + else { + throw Losfahren(pFz, p_pWeg); + } +} diff --git a/Aufgabenblock_2/FzgParken.h b/Aufgabenblock_2/FzgParken.h new file mode 100644 index 0000000..0e55756 --- /dev/null +++ b/Aufgabenblock_2/FzgParken.h @@ -0,0 +1,17 @@ +#ifndef FZGPARKEN_H_ +#define FZGPARKEN_H_ + +#include "FzgVerhalten.h" + +class FzgParken: public FzgVerhalten { +public: + FzgParken(Weg *pWeg, double dStartZeit); + virtual ~FzgParken(); + + double dStrecke(Fahrzeug *pFz, double dDelta); + +private: + double p_dStartZeit; +}; + +#endif /* FZGPARKEN_H_ */ diff --git a/Aufgabenblock_2/LazyAktion.h b/Aufgabenblock_2/LazyAktion.h new file mode 100644 index 0000000..0bf5aa3 --- /dev/null +++ b/Aufgabenblock_2/LazyAktion.h @@ -0,0 +1,60 @@ +/*** LAZYAKTION.H ***/ + +#ifndef __LazyAktion_h +#define __LazyAktion_h + +#include +using namespace std; + +// Oberklasse LazyAktion +template +class LazyAktion +{ + public: + LazyAktion( list* ptLazyListe ) + : p_ptLazyListe( ptLazyListe ) {} + virtual ~LazyAktion() {} + virtual void vAusfuehren() = 0; + protected: + list* p_ptLazyListe; // Zeiger auf p_ListeObjekte +}; + + +// LazyPushFront +template +class LazyPushFront : public LazyAktion +{ + public: + LazyPushFront(const T& einObjekt, list* eineListe) + : LazyAktion(eineListe) + , p_tObjekt(einObjekt) {} + virtual ~LazyPushFront() {} + void vAusfuehren() { p_ptLazyListe->push_front(p_tObjekt); } + private: + T p_tObjekt; +}; + + +// LazyPushBack + +... + + +// LazyErase +template +class LazyErase : public LazyAktion +{ + // typedef fuer iterator + typedef typename list::iterator iterator; + typedef typename list::const_iterator const_iterator; + + public: + LazyErase( ... ) : ... {} + virtual ~LazyErase() {} + void vAusfuehren() { ... } + private: + iterator p_itObjekt; // bei erase Iterator speichern +}; + + +#endif \ No newline at end of file diff --git a/Aufgabenblock_2/LazyListe.h b/Aufgabenblock_2/LazyListe.h new file mode 100644 index 0000000..1b3c871 --- /dev/null +++ b/Aufgabenblock_2/LazyListe.h @@ -0,0 +1,92 @@ +/*** LAZYLISTE.H ***/ + +#ifndef __LazyListe_h +#define __LazyListe_h + +#include +#include "LazyAktion.h" + +template +class LazyListe +{ + public: + // typedef fuer iterator + typedef typename list::iterator iterator; + typedef typename list::const_iterator const_iterator; + + // Konstruktor / Destruktor + LazyListe() { bChanged = false; } + virtual ~LazyListe() + { + if (bChanged) + { + // ggf. noch anstehende Aktionen löschen + do + { + delete *(p_ListeAktionen.begin()); + p_ListeAktionen.pop_front(); + } + while (p_ListeAktionen.size() > 0); + } + } + + // Lesefunktionen + const_iterator begin() const {return p_ListeObjekte.begin();} + const_iterator end() const {...} + iterator begin() {return p_ListeObjekte.begin();} + iterator end() {...} + bool empty() const {...} + + // Schreibfunktionen + void push_back( const T einObjekt ) + { + p_ListeAktionen.push_back(new LazyPushBack(...)); + bChanged = true; + return; + } + + void push_front( const T einObjekt ) + { + ... + + bChanged = true; + return; + } + + void erase( iterator itObjekt ) + { + ... + + bChanged = true; + return; + } + + // Änderungen auf Objektliste übertragen + void vAktualisieren() + { + list *>::const_iterator itL; + + if ( bChanged ) + { + // ausstehende Aktionen durchfuehren + for (itL=... ) + { + // Aktion ausführen + ... + // Zeiger auf Action-Element löschen + ... + } + // Liste der Aktionen leeren + p_ListeAktionen.clear(); + + bChanged = false; + } + } + + private: + list p_ListeObjekte; + list*> p_ListeAktionen; + bool bChanged; +}; + +#endif \ No newline at end of file diff --git a/Aufgabenblock_2/Losfahren.cpp b/Aufgabenblock_2/Losfahren.cpp new file mode 100644 index 0000000..93cd982 --- /dev/null +++ b/Aufgabenblock_2/Losfahren.cpp @@ -0,0 +1,15 @@ +#include + +#include "Losfahren.h" + +using namespace std; + +Losfahren::Losfahren(Fahrzeug *pFahrzeug, Weg *pWeg) : FahrAusnahme(pFahrzeug, pWeg) +{ } + +Losfahren::~Losfahren() +{ } + +void Losfahren::vBearbeiten() { + cout << "Fahrausnahme: Losfahren (Fzg: " << *p_pFahrzeug << ", Weg: " << *p_pWeg << ")" << endl; +} diff --git a/Aufgabenblock_2/Losfahren.h b/Aufgabenblock_2/Losfahren.h new file mode 100644 index 0000000..32dfb59 --- /dev/null +++ b/Aufgabenblock_2/Losfahren.h @@ -0,0 +1,14 @@ +#ifndef LOSFAHREN_H_ +#define LOSFAHREN_H_ + +#include "FahrAusnahme.h" + +class Losfahren: public FahrAusnahme { +public: + Losfahren(Fahrzeug *pFahrzeug, Weg *pWeg); + virtual ~Losfahren(); + + void vBearbeiten(); +}; + +#endif /* LOSFAHREN_H_ */ diff --git a/Aufgabenblock_2/SimuClient.cpp b/Aufgabenblock_2/SimuClient.cpp new file mode 100644 index 0000000..6932ec6 --- /dev/null +++ b/Aufgabenblock_2/SimuClient.cpp @@ -0,0 +1,530 @@ +/** + * SimuClient für MacOS/Linux (Praktikum Informatik 2 RWTH Aachen) + * + * @version 0.5 + * @author Robert Uhl, 2009 - 2010 + * @author Steffen Vogel + * + * Vielen Dank an den Lehrstuhl EECS, RWTH Aachen, für den Zugang zum Quellcode des SimuClient für Windows. + */ + +#include +#include +#include +#include +#include +#include + +#include "ClientSocket.h" +#include "SimuClient.h" + +//#define DEBUG DEBUG // Debugging an/aus (auskommentieren!) + +/* + * Variablen der Bibliothek + */ +static ClientSocket* p_cGrafikServerVerbindung = NULL; // Verbindung zum Grafikserver +static string p_sServer; // Servername +static unsigned int p_iPort = 0; // Serverport +static bool p_bInitialisiert = false; // Simulationsdarstellung initialisiert? true = ja +static int p_iXSize = 0; // X Größe des Verkehrsplanes +static int p_iYSize = 0; // Y Größe des Verkehrsplanes +static map p_mWege; // Map aller erzeugten Wege; map ermöglicht find() + +/** + * Sendet eine Fehlermeldung an den Server, wenn verbunden. + * Diese wird dort als Error-MsgBox angezeigt. + */ +static void vSendeNachricht(const string& sNachricht) { + ostringstream ssNachricht; + + // noch nicht initialisiert? - muss so bleiben sonst endlose Rekursion !!! + if (!p_bInitialisiert) { + cerr << "--> Fehler: GrafikServer noch nicht initialisert!" << endl; + return; + } + + // Fehlermeldung an den GrafikServer schicken + ssNachricht << "message " << sNachricht << "#"; + if (p_cGrafikServerVerbindung->Send(ssNachricht.str().c_str(), ssNachricht.str().size())) { + +#ifdef DEBUG + cerr << "Fehlermeldung gesendet: " << ssNachricht.str() << endl; +#endif + //Sleep(100); + return; + } else { + cerr << "--> Fehler: Senden der Fehlermeldung fehlgeschlagen!" << endl; + cerr << "Die Fehlermeldung war: " << sNachricht << endl; + return; + } + return; +} + +/** + * Prüft ob der Name für eine Straße den Konventionen genügt + */ +static bool bStreetOk(const string& sName, const bool bNeu) { + if (sName.empty()) { + cerr << "--> Fehler: Der Wegname ist leer!" << endl; + vSendeNachricht("Der Wegname ist leer!"); + return false; + } + + if (sName.size() > 10) { + cerr << "--> Fehler: Der Wegname darf maximal 10 Zeichen lang sein!" << endl; + vSendeNachricht("Der Wegname darf maximal 10 Zeichen lang sein!"); + return false; + } + + // Nach ungültigen Zeichen im Namen suchen + if (sName.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890_-") != string::npos) { + cerr << "--> Fehler: Der Wegname darf nur Buchstaben, Ziffern, -, _ und keine Leerzeichen enthalten!" << endl; + vSendeNachricht("Der Wegname darf nur Buchstaben, Ziffern, -, _ und keine Leerzeichen enthalten!"); + return false; + } + + if (bNeu) { // Weg wird neu angelegt + if (p_mWege.find(sName) != p_mWege.end()) { + cerr << "--> Fehler: Der Wegname wurde schon verwendet!" << endl; + vSendeNachricht("Der Wegname wurde schon verwendet!"); + return false; + } else { + p_mWege[sName] = 0; // Weg in der map speichern + return true; + } + } else { // Weg wird auf Vorhandensein geprüft + if (p_mWege.find(sName) != p_mWege.end()) { // Weg gefunden + return true; + } else { + cerr << "--> Fehler: Der Weg ist nicht vorhanden!" << endl; + vSendeNachricht("Der Weg ist nicht vorhanden!"); + return false; + } + } +} + +/** + * Prüft ob der Name für ein Farzeug den Konventionen genügt + */ +static bool bVehikelOk(const string& sName, const double rel_position, const double speed) { + if (sName.empty()) { + cerr << "--> Fehler: Fahrzeugname ist leer!" << endl; + vSendeNachricht("Fahrzeugname ist leer!"); + return false; + } + + if (sName.size() > 10) { + cerr << "--> Fehler: Der Fahrzeugname darf maximal 10 Zeichen lang sein!" << endl; + vSendeNachricht("Der Fahrzeugname darf maximal 10 Zeichen lang sein!"); + return false; + } + + // Nach ungültigen Zeichen im Namen suchen + if (sName.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890_-") != string::npos) { + cerr << "--> Fehler: Der Fahrzeugname darf nur Buchstaben, Ziffern, -, _ und keine Leerzeichen enthalten!" << endl; + vSendeNachricht("Der Fahrzeugname darf nur Buchstaben, Ziffern, -, _ und keine Leerzeichen enthalten!"); + return false; + } + + if (speed < 0.0) { + cerr << "--> Fehler: Geschwindigkeit < 0.0km/h!" << endl; + vSendeNachricht("Geschwindigkeit < 0.0km/h!"); + return false; + } + + if (speed > 300.0) { + cerr << "--> Fehler: Fahrraeder sind keine Formel1-Fahrzeuge, Geschwindigkeit <= 300km/h!" << endl; + vSendeNachricht("Fahrraeder sind keine Formel1-Fahrzeuge, Geschwindigkeit <= 300km/h!"); + return false; + } + + if ( (rel_position < 0.0) || (rel_position > 1.0) ) { + cerr << "--> Fehler: Relative Position ausserhalb [0, 1]!" << endl; + vSendeNachricht("Relative Position ausserhalb [0, 1]!"); + return false; + } + + return true; +} + +/** + * Grafik-Server initialisieren + * Standard: bStarteServer = true, sServer = "localhost", iPort = 7654 + */ +bool bInitialisiereGrafik(int sizeX, int sizeY, bool bStarteServer, const string& sServer, const unsigned short iPort) { + ostringstream ssNachricht; + + // schon initialisiert? + if (p_bInitialisiert) { + cerr << "--> Fehler: GrafikServer ist schon initialisert!" << endl; + return false; + } + + // Socket für die Kommunikation zum Server anlegen + p_cGrafikServerVerbindung = new ClientSocket(SOCK_STREAM); + p_sServer = sServer; + p_iPort = iPort; + + // Größe des Verkehrsplanes speichern + p_iXSize = sizeX; + p_iYSize = sizeY; + + // Größe des Verkehrsplanes kontrollieren + if ( (sizeX < 100) || (sizeX > 2000) || (sizeY < 100) || (sizeY > 2000) ) { + cerr << "--> Fehler: Groesse des Verkehrsplanes < 100 oder > 2000" << endl; + } + + // Grafik-Server starten + if (bStarteServer) { + cout << "--> SimuServer starten ..." << endl; + system("java -jar SimuServer.jar &"); + Sleep(1000); // eine Sekunde warten + } + + // Verbindung zum Server aufbauen + if (!p_cGrafikServerVerbindung->Connect(p_sServer, p_iPort)) { + cerr << "--> Fehler: TCP/IP-Verbindung nicht moeglich!" << endl; + return false; + } + + // Init-Befehl senden + ssNachricht << "init " << sizeX << " " << sizeY << "#"; + + if (p_cGrafikServerVerbindung->Send(ssNachricht.str().c_str(), ssNachricht.str().size())) { + p_bInitialisiert = true; + +#ifdef DEBUG + cerr << "Init gesendet: " << ssNachricht.str() << endl; +#endif + + Sleep(500); + return true; + } else { + cerr << "--> Fehler: Senden Init fehlgeschlagen!" << endl; + return false; + } +} + +/** + * Zeichnet eine Kreuzung + */ +bool bZeichneKreuzung(int posX, int posY) { + ostringstream ssNachricht; + + // noch nicht initialisiert? + if (!p_bInitialisiert) { + cerr << "--> Fehler: GrafikServer noch nicht initialisert!" << endl; + return false; + } + + // Kreuzung innerhalb des Verkehrsplanes? + if ( (posX > 0) && (posX < p_iXSize) && (posY > 0) && (posY < p_iYSize) ) { + ssNachricht << "crossing " << posX << " " << posY << "#"; + if (p_cGrafikServerVerbindung->Send(ssNachricht.str().c_str(), ssNachricht.str().size())) { + +#ifdef DEBUG + cerr << "Kreuzung gesendet: " << ssNachricht.str() << endl; +#endif + + //Sleep(100); + return true; + } else { + cerr << "--> Fehler: Senden Kreuzung fehlgeschlagen!" << endl; + vSendeNachricht("Senden Kreuzung fehlgeschlagen!"); + return false; + } + } else { + cerr << "--> Fehler: Koordinaten ausserhalb des Verkehrsplanes!" << endl; + vSendeNachricht("Koordinaten ausserhalb des Verkehrsplanes!"); + return false; + } + return false; +} + +/** + * Straße zeichnen + */ +bool bZeichneStrasse(const string& way_to_name, const string& way_back_name, int length, int numPoints, int* points_xy) { + ostringstream ssNachricht; + int iCounter; + + // noch nicht initialisiert ? + if (!p_bInitialisiert) { + cerr << "--> Fehler: GrafikServer noch nicht initialisert!" << endl; + return false; + } + + // Straßenname ok? + if (!bStreetOk(way_to_name, true) || !bStreetOk(way_back_name, true)) { + return false; + } + + if (length < 0) { + cerr << "--> Fehler: Weglaenge kleiner 0!" << endl; + vSendeNachricht("Weglaenge kleiner 0!"); + return false; + } + + if (numPoints < 2) { + cerr << "--> Fehler: Mindestens zwei Koordinaten fuer die Strasse notwendig!" << endl; + vSendeNachricht("Mindestens zwei Koordinaten fuer die Strasse notwendig!"); + return false; + } + + // Straße senden + ssNachricht << "street " << way_to_name << " " << way_back_name << " " << length << " " << numPoints; + + for (iCounter = 0; iCounter < numPoints * 2; iCounter += 2) { + if ( (points_xy[iCounter] > 0) && (points_xy[iCounter] < p_iXSize) && (points_xy[iCounter + 1] > 0) && (points_xy[iCounter + 1] < p_iYSize) ) { + ssNachricht << " " << points_xy[iCounter] << " " << points_xy[iCounter + 1]; + } else { + cerr << "--> Fehler: Koordinaten ausserhalb des Verkehrsplanes! Ueberspringe..." << endl; + //vSendeNachricht("Koordinaten ausserhalb des Verkehrsplanes! Ueberspringe..."); + } + } + + ssNachricht << "#"; + + if (p_cGrafikServerVerbindung->Send(ssNachricht.str().c_str(), ssNachricht.str().size())) { + +#ifdef DEBUG + cerr << "Strasse gesendet: " << ssNachricht.str() << endl; +#endif + + //Sleep(100); + return true; + } else { + cerr << "--> Fehler: Senden Strasse fehlgeschlagen!" << endl; + vSendeNachricht("Senden Strasse fehlgeschlagen!"); + return false; + } +} + +/** + * PKW zeichnen + */ +bool bZeichnePKW(const string& carname, const string& streetname, double rel_position, double speed, double tank) { + ostringstream ssNachricht; + + // noch nicht initialisiert ? + if (!p_bInitialisiert) { + cerr << "--> Fehler: GrafikServer noch nicht initialisert!" << endl; + return false; + } + + // PKW-Name, Position und Geschwindigkeit in den Grenzen? + if (!bVehikelOk(carname, rel_position, speed)) { + return false; + } + + if (tank < 0.0) { + cerr << "--> Fehler: Tank < 0.0l!" << endl; + vSendeNachricht("Tank < 0.0l!"); + return false; + } + + if (tank > 999.9) { + cerr << "--> Fehler: Versteckte Tanks sind nicht erlaubt! Tankinhalt < 1000l!" << endl; + vSendeNachricht("Versteckte Tanks sind nicht erlaubt! Tankinhalt < 1000l!"); + return false; + } + + // Existiert die Straße? + if (!bStreetOk(streetname, false)) { + cerr << "--> Fehler: Diese Strasse gibt es nicht!" << endl; + vSendeNachricht("Diese Strasse gibt es nicht!"); + return false; + } + + ssNachricht << "sc " << carname << " " << streetname << setiosflags(ios::fixed); + ssNachricht << " " << setw(7) << setprecision(4) << rel_position; + ssNachricht << " " << setw(6) << setprecision(1) << speed; + ssNachricht << " " << setw(6) << setprecision(1) << tank << "#"; + + if (p_cGrafikServerVerbindung->Send(ssNachricht.str().c_str(), ssNachricht.str().size())) { + +#ifdef DEBUG + cerr << "PKW gesendet: " << ssNachricht.str() << endl; +#endif + //Sleep(100); + return true; + } else { + cerr << "--> Fehler: Senden PKW fehlgeschlagen!" << endl; + vSendeNachricht("Senden PKW fehlgeschlagen!"); + return false; + } +} + +/** + * Zeichne Fahrrad + */ +bool bZeichneFahrrad(const string& bikename, const string& streetname, double rel_position, double speed) { + ostringstream ssNachricht; + + // noch nicht initialisiert ? + if (!p_bInitialisiert) { + cerr << "--> Fehler: GrafikServer noch nicht initialisert!" << endl; + return false; + } + + // Fahrradname, Position und Geschwindigkeit in den Grenzen? + if (!bVehikelOk(bikename, rel_position, speed)) { + return false; + } + + // Existiert die Straße? + if (!bStreetOk(streetname, false)) { + cerr << "--> Fehler: Diese Strasse gibt es nicht!" << endl; + vSendeNachricht("Diese Strasse gibt es nicht!"); + return false; + } + + ssNachricht << "sb " << bikename << " " << streetname << setiosflags(ios::fixed); + ssNachricht << " " << setw(7) << setprecision(4) << rel_position; + ssNachricht << " " << setw(6) << setprecision(1) << speed << "#"; + + if (p_cGrafikServerVerbindung->Send(ssNachricht.str().c_str(), ssNachricht.str().size())) { + +#ifdef DEBUG + cerr << "Fahrrad gesendet: " << ssNachricht.str() << endl; +#endif + //Sleep(100); + return true; + } else { + cerr << "--> Fehler: Senden Fahrrad fehlgeschlagen!" << endl; + vSendeNachricht("Senden Fahrrad fehlgeschlagen!"); + return false; + } +} + +/** + * Sendet die aktuelle Simulationszeit an den erweiterten SimuServer + */ +void vSetzeZeit(const double dTime) { + ostringstream ssNachricht; + +#ifdef DEBUG + cout << dTime << endl; +#endif + + // noch nicht initialisiert ? + if (!p_bInitialisiert) { + cerr << "--> Fehler: GrafikServer noch nicht initialisert!" << endl; + return; + } + + if (dTime < 0.0) { + cerr << "--> Fehler: Die Zeit darf nicht negativ sein!" << endl; + vSendeNachricht("Die Zeit darf nicht negativ sein!"); + return; + } + + ssNachricht << "time " << dTime << "#"; + + if (p_cGrafikServerVerbindung->Send(ssNachricht.str().c_str(), ssNachricht.str().size())) { + +#ifdef DEBUG + cerr << "Zeit gesendet: " << ssNachricht.str() << endl; +#endif + + //Sleep(100); + return; + } else { + cerr << "--> Fehler: Senden der Zeit fehlgeschlagen!" << endl; + vSendeNachricht("Senden der Zeit fehlgeschlagen!"); + return; + } +} + +/** + * Ersetzt die Sleep()-Funktion von Windows, die mSek übernimmt + */ +void Sleep(const int mSec) { + if (mSec > 0) { + usleep(mSec * 1000); + } + return; +} + +void vBeendeGrafik(void) { + // noch nicht initialisiert ? + if (!p_bInitialisiert) { + cerr << "--> Fehler: GrafikServer noch nicht initialisert!" << endl; + return; + } + + vSendeNachricht("Simulation beendet!"); + p_cGrafikServerVerbindung->Send("close#", 6); + +#ifdef DEBUG + cerr << "Close gesendet." << endl; +#endif + + //Sleep(100); + p_cGrafikServerVerbindung->Disconnect(); + delete p_cGrafikServerVerbindung; + p_cGrafikServerVerbindung = NULL; + return; +} + +/* + * Zusätzliche Schnittstellen wegen eventueller Konvertierungsprobleme bei string/char* + */ + +bool bZeichneStrasse(const char* way_to_name, const char* way_back_name, int length, int numPoints, int* points_xy) { + string sHinweg = string(way_to_name); + string sRueckweg = string(way_back_name); + + return bZeichneStrasse(sHinweg, sRueckweg, length, numPoints, points_xy); +} + +bool bZeichneStrasse(const string& way_to_name, const char* way_back_name, int length, int numPoints, int* points_xy) { + string sRueckweg = string(way_back_name); + + return bZeichneStrasse(way_to_name, sRueckweg, length, numPoints, points_xy); +} + +bool bZeichneStrasse(const char* way_to_name, const string& way_back_name, int length, int numPoints, int* points_xy) { + string sHinweg = string(way_to_name); + + return bZeichneStrasse(sHinweg, way_back_name, length, numPoints, points_xy); +} + +bool bZeichnePKW(const char* carname, const char* streetname, double rel_position, double speed, double tank) { + string sName = string(carname); + string sWeg = string(streetname); + + return bZeichnePKW(sName, sWeg, rel_position, speed, tank); +} + +bool bZeichnePKW(const string& carname, const char* streetname, double rel_position, double speed, double tank) { + string sWeg = string(streetname); + + return bZeichnePKW(carname, sWeg, rel_position, speed, tank); +} + +bool bZeichnePKW(const char* carname, const string& streetname, double rel_position, double speed, double tank) { + string sName = string(carname); + + return bZeichnePKW(sName, streetname, rel_position, speed, tank); +} + +bool bZeichneFahrrad(const char* bikename, const char* streetname, double rel_position, double speed) { + string sName = string(bikename); + string sWeg = string(streetname); + + return bZeichneFahrrad(sName, sWeg, rel_position, speed); +} + +bool bZeichneFahrrad(const string& bikename, const char* streetname, double rel_position, double speed) { + string sWeg = string(streetname); + + return bZeichneFahrrad(bikename, sWeg, rel_position, speed); +} + +bool bZeichneFahrrad(const char* bikename, const string& streetname, double rel_position, double speed) { + string sName = string(bikename); + + return bZeichneFahrrad(sName, streetname, rel_position, speed); +} diff --git a/Aufgabenblock_2/SimuClient.h b/Aufgabenblock_2/SimuClient.h new file mode 100644 index 0000000..cfeadd8 --- /dev/null +++ b/Aufgabenblock_2/SimuClient.h @@ -0,0 +1,74 @@ +/* + * SimuClient für MacOS/Linux (Praktikum Informatik 2, WS 2009/10 RWTH Aachen) + * Version 0.5 + * von Robert Uhl, 2009 - 2010 + * Vielen Dank an den Lehrstuhl EECS, RWTH Aachen, für den Zugang zum Quellcode + * des SimuClient für Windows. + * Datei: SimuClient.h + * Inhalt: SimuClient sendet Daten an den (erweiterten) Java-Grafik-Server + */ + +#ifndef SIMUCLIENT_H +#define SIMUCLIENT_H + +#include +using namespace std; + +/** + * Grafik-Server initialisieren + * Standard: bStarteServer = true, sServer = "localhost", iPort = 7654 + */ +bool bInitialisiereGrafik(int sizeX, int sizeY, bool bStarteServer = true, const string& sServer = "localhost", const unsigned short iPort = 7654); + +/** + * Zeichnet eine Kreuzung + */ +bool bZeichneKreuzung(int posX, int posY); + +/** + * Straße zeichnen + */ +bool bZeichneStrasse(const string& way_to_name, const string& way_back_name, int length, int numPoints, int* points_xy); + +/** + * PKW zeichnen + */ +bool bZeichnePKW(const string& carname, const string& streetname, double rel_position, double speed, double tank); + +/** + * Zeichne Fahrrad + */ +bool bZeichneFahrrad(const string& bikename, const string& streetname, double relposition, double speed); + +/** + * Sendet die aktuelle Simulationszeit an den erweiterten SimuServer + */ +void vSetzeZeit(const double dTime); + +/** + * Ersetzt die Sleep()-Funktion von Windows, die mSek übernimmt + */ +void Sleep(const int mSec); + +/** + * Grafikserver beenden + */ +void vBeendeGrafik(void); + +/* + * Zusätzliche Schnittstellen wegen eventueller Konvertierungsprobleme bei string/char* + */ + +bool bZeichneStrasse(const char* way_to_name, const char* way_back_name, int length, int numPoints, int* points_xy); +bool bZeichneStrasse(const string& way_to_name, const char* way_back_name, int length, int numPoints, int* points_xy); +bool bZeichneStrasse(const char* way_to_name, const string& way_back_name, int length, int numPoints, int* points_xy); + +bool bZeichnePKW(const char* carname, const char* streetname, double rel_position, double speed, double tank); +bool bZeichnePKW(const string& carname, const char* streetname, double rel_position, double speed, double tank); +bool bZeichnePKW(const char* carname, const string& streetname, double rel_position, double speed, double tank); + +bool bZeichneFahrrad(const char* bikename, const char* streetname, double rel_position, double speed); +bool bZeichneFahrrad(const string& bikename, const char* streetname, double rel_position, double speed); +bool bZeichneFahrrad(const char* bikename, const string& streetname, double rel_position, double speed); + +#endif // SIMUCLIENT_H diff --git a/Aufgabenblock_2/SimuServer.jar b/Aufgabenblock_2/SimuServer.jar new file mode 100644 index 0000000..496145c Binary files /dev/null and b/Aufgabenblock_2/SimuServer.jar differ diff --git a/Aufgabenblock_2/Streckenende.cpp b/Aufgabenblock_2/Streckenende.cpp new file mode 100644 index 0000000..4d21e8e --- /dev/null +++ b/Aufgabenblock_2/Streckenende.cpp @@ -0,0 +1,15 @@ +#include + +#include "Streckenende.h" + +using namespace std; + +Streckenende::Streckenende(Fahrzeug *pFahrzeug, Weg *pWeg) : FahrAusnahme(pFahrzeug, pWeg) +{ } + +Streckenende::~Streckenende() +{ } + +void Streckenende::vBearbeiten() { + cout << "Fahrausnahme: Streckenende (Fzg: " << *p_pFahrzeug << ", Weg: " << *p_pWeg << ")" << endl; +} diff --git a/Aufgabenblock_2/Streckenende.h b/Aufgabenblock_2/Streckenende.h new file mode 100644 index 0000000..8a34497 --- /dev/null +++ b/Aufgabenblock_2/Streckenende.h @@ -0,0 +1,14 @@ +#ifndef STRECKENENDE_H_ +#define STRECKENENDE_H_ + +#include "FahrAusnahme.h" + +class Streckenende: public FahrAusnahme { +public: + Streckenende(Fahrzeug *pFahrzeug, Weg *pWeg); + virtual ~Streckenende(); + + void vBearbeiten(); +}; + +#endif /* STRECKENENDE_H_ */