diff --git a/Aufgabenblock_2/ClientSocket.cpp b/Aufgabenblock_2/ClientSocket.cpp deleted file mode 100644 index 74e2c6b..0000000 --- a/Aufgabenblock_2/ClientSocket.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/** - * 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 deleted file mode 100644 index 868e0f5..0000000 --- a/Aufgabenblock_2/ClientSocket.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - * 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/SimuClient.cpp b/Aufgabenblock_2/SimuClient.cpp deleted file mode 100644 index 6932ec6..0000000 --- a/Aufgabenblock_2/SimuClient.cpp +++ /dev/null @@ -1,530 +0,0 @@ -/** - * 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 index 80133d0..f7c7252 100644 --- a/Aufgabenblock_2/SimuClient.h +++ b/Aufgabenblock_2/SimuClient.h @@ -1,40 +1,41 @@ -#pragma once -#pragma warning (disable:4786) -#include -using namespace std; - -// Folgender ifdef-Block ist die Standardmethode zum Erstellen von Makros, die das Exportieren -// aus einer DLL vereinfachen. Alle Dateien in dieser DLL werden mit dem SIMUCLIENT_EXPORTS-Symbol -// kompiliert, das in der Befehlszeile definiert wurde. Das Symbol darf nicht für ein Projekt definiert werden, -// das diese DLL verwendet. Alle anderen Projekte, deren Quelldateien diese Datei beinhalten, erkennen -// SIMUCLIENT_API-Funktionen als aus einer DLL importiert, während die DLL -// mit diesem Makro definierte Symbole als exportiert ansieht. -#ifdef SIMUCLIENT_EXPORTS -#define SIMUCLIENT_API __declspec(dllexport) -#else -#define SIMUCLIENT_API __declspec(dllimport) -#endif - -// NUTZBARE FUNKTIONEN (offizielle Schnittstelle) -SIMUCLIENT_API bool bInitialisiereGrafik(int sizeX, int sizeY, char* address = "127.0.0.1"); -SIMUCLIENT_API bool bZeichneKreuzung(int posX, int posY); -SIMUCLIENT_API bool bZeichneStrasse(const string& way_to_name, const string& way_back_name, int length, int numPoints, int* points_xy); -SIMUCLIENT_API bool bZeichnePKW(const string& carname, const string& streetname, double rel_position, double speed, double tank); -SIMUCLIENT_API bool bZeichneFahrrad(const string& bikename, const string& streetname, double relposition, double speed); -SIMUCLIENT_API void vBeendeGrafik(); -SIMUCLIENT_API void vSetzeZeit(const double dTime); - -// Zusätzliche Schnittstellen (wegen Konvertierungsproblemen bei string/char*) - -SIMUCLIENT_API bool bZeichneStrasse(const char* way_to_name, const char* way_back_name, int length, int numPoints, int* points_xy); -SIMUCLIENT_API bool bZeichneStrasse(const string& way_to_name, const char* way_back_name, int length, int numPoints, int* points_xy); -SIMUCLIENT_API bool bZeichneStrasse(const char* way_to_name, const string& way_back_name, int length, int numPoints, int* points_xy); -SIMUCLIENT_API bool bZeichnePKW(const string& carname, const char* streetname, double rel_position, double speed, double tank); -SIMUCLIENT_API bool bZeichneFahrrad(const string& bikename, const char* streetname, double rel_position, double speed); -SIMUCLIENT_API bool bZeichnePKW(const char* carname, const char* streetname, double rel_position, double speed, double tank); -SIMUCLIENT_API bool bZeichneFahrrad(const char* bikename, const char* streetname, double rel_position, double speed); -SIMUCLIENT_API bool bZeichnePKW(const char* carname, const string& streetname, double rel_position, double speed, double tank); -SIMUCLIENT_API bool bZeichneFahrrad(const char* bikename, const string& streetname, double rel_position, double speed); - -// Wrapperfunktion fuer Sleep -SIMUCLIENT_API void vSleep(int mSec); \ No newline at end of file +/* + * 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; + +// Funktionen der Library +bool bInitialisiereGrafik(int sizeX, int sizeY, bool bStarteServer = true, const string& sServer = "localhost", const unsigned short iPort = 7654); +bool bZeichneKreuzung(int posX, int posY); +bool bZeichneStrasse(const string& way_to_name, const string& way_back_name, int length, int numPoints, int* points_xy); +bool bZeichnePKW(const string& carname, const string& streetname, double rel_position, double speed, double tank); +bool bZeichneFahrrad(const string& bikename, const string& streetname, double relposition, double speed); +void vSetzeZeit(const double dTime); // sendet die Simulationszeit an den erweiterten Grafikserver +void Sleep(const int mSec); // ersetzt die Sleep()-Funktion von Windows, die mSek übernimmt +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 +// eof diff --git a/Aufgabenblock_2/libsimu.so b/Aufgabenblock_2/libsimu.so new file mode 100644 index 0000000..f9ef4f1 Binary files /dev/null and b/Aufgabenblock_2/libsimu.so differ diff --git a/Aufgabenblock_3/AktivesVO.cpp b/Aufgabenblock_3/AktivesVO.cpp new file mode 100644 index 0000000..d353405 --- /dev/null +++ b/Aufgabenblock_3/AktivesVO.cpp @@ -0,0 +1,95 @@ +#include +#include +#include + +#include "AktivesVO.h" + +extern double dGlobaleZeit; + +int AktivesVO::p_iMaxID = 0; +map AktivesVO::p_pObjekte; + +AktivesVO::AktivesVO() { + vInitialisierung(); +} + +AktivesVO::AktivesVO(string sName) { + vInitialisierung(); + p_sName = sName; + vRegister(); +} + +AktivesVO::AktivesVO(AktivesVO &vo) { + vInitialisierung(); + p_sName = vo.p_sName; + vRegister(); +} + +AktivesVO::~AktivesVO() { + p_pObjekte.erase(p_sName); +} + +void AktivesVO::vRegister() { + map::iterator result = p_pObjekte.find(p_sName); + if (result != p_pObjekte.end()) { + throw string("Ein Objekt mit dem Namen existiert bereits!"); + } + + p_pObjekte[p_sName] = this; +} + +AktivesVO * AktivesVO::pObjekt(string sName) { + map::iterator result = p_pObjekte.find(sName); + if (result == p_pObjekte.end()) { + throw string("Ein Objekt mit dem Namen existiert nicht!"); + } + + return result->second; +} + +void AktivesVO::vInitialisierung() { + p_iID = ++p_iMaxID; + + p_sName = ""; + p_dZeit = 0; +} + +void AktivesVO::vAusgabeHeader() { + cout << "ID Zeit Name : Kmh GesamtStrecke Verbrauch Tankinhalt" << endl; + cout << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" + << endl; +} + +ostream& AktivesVO::ostreamAusgabe(ostream &stream) const { + stream << setprecision(1) << setiosflags(ios::fixed) + << resetiosflags(ios::right) << setiosflags(ios::left) + << setw(3) << p_iID + << setw(5) << p_dZeit + << setw(7) << p_sName << ":"; + + return stream; +} + +istream& AktivesVO::istreamEingabe(istream &stream) { + if (p_sName != "") { + throw string("Verkehrsobjekt ist bereits initialisiert!"); + } + + stream >> p_sName; + + vRegister(); + + return stream; +} + +string AktivesVO::getName() const { + return p_sName; +} + +ostream& operator<<(ostream &stream, const AktivesVO &vo) { + return vo.ostreamAusgabe(stream); +} + +istream& operator>>(istream &in, AktivesVO &vo) { + return vo.istreamEingabe(in); +} diff --git a/Aufgabenblock_3/AktivesVO.h b/Aufgabenblock_3/AktivesVO.h new file mode 100644 index 0000000..f052eba --- /dev/null +++ b/Aufgabenblock_3/AktivesVO.h @@ -0,0 +1,46 @@ +#ifndef AKTIVESVO_H_ +#define AKTIVESVO_H_ + +#include +#include + +using namespace std; + +class AktivesVO { +public: + AktivesVO(); + AktivesVO(AktivesVO &vo); + AktivesVO(string sName); + virtual ~AktivesVO(); + + static void vAusgabeHeader(); + static AktivesVO * pObjekt(string sName); + + virtual ostream& ostreamAusgabe(ostream &stream) const; + virtual istream& istreamEingabe(istream &stream); + + virtual void vAbfertigung() = 0; /* AktivesVO ist eine abstrakte Klasse */ + virtual void vZeichnen() const = 0; + + string getName() const; + +protected: + double p_dZeit; + + /* nicht virtuell, da virtuelle Funktionen nicht + * in Konstruktoren aufgerufen werden dürfen!!! */ + void vInitialisierung(); + void vRegister(); + +private: + static int p_iMaxID; + static map p_pObjekte; + + int p_iID; + string p_sName; +}; + +ostream& operator<<(ostream &out, const AktivesVO &vo); +istream& operator>>(istream &in, AktivesVO &vo); + +#endif /* AKTIVESVO_H_ */ diff --git a/Aufgabenblock_3/FahrAusnahme.cpp b/Aufgabenblock_3/FahrAusnahme.cpp new file mode 100644 index 0000000..4627ad1 --- /dev/null +++ b/Aufgabenblock_3/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_3/FahrAusnahme.h b/Aufgabenblock_3/FahrAusnahme.h new file mode 100644 index 0000000..a705a15 --- /dev/null +++ b/Aufgabenblock_3/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_3/Fahrrad.cpp b/Aufgabenblock_3/Fahrrad.cpp new file mode 100644 index 0000000..0714321 --- /dev/null +++ b/Aufgabenblock_3/Fahrrad.cpp @@ -0,0 +1,27 @@ +#include + +#include "Fahrrad.h" + +/* Standardkonstruktor */ +Fahrrad::Fahrrad() : Fahrzeug() +{ } + +Fahrrad::Fahrrad(string sName, double dMaxGeschwindigkeit) : Fahrzeug(sName, dMaxGeschwindigkeit) +{ } + +/* Destruktor */ +Fahrrad::~Fahrrad() +{ } + +double Fahrrad::dGeschwindigkeit() const { + double dGeschwindigkeit; + int iReduzierung = p_dGesamtStrecke / 20; + + dGeschwindigkeit = p_dMaxGeschwindigkeit * powl(0.9, iReduzierung); + + if (dGeschwindigkeit < 12) { + dGeschwindigkeit = 12; + } + + return dGeschwindigkeit; +} diff --git a/Aufgabenblock_3/Fahrrad.h b/Aufgabenblock_3/Fahrrad.h new file mode 100644 index 0000000..4853d87 --- /dev/null +++ b/Aufgabenblock_3/Fahrrad.h @@ -0,0 +1,17 @@ +#ifndef FAHRRAD_H_ +#define FAHRRAD_H_ + +#include "Fahrzeug.h" + +using namespace std; + +class Fahrrad: public Fahrzeug { +public: + Fahrrad(); + Fahrrad(string sName, double dMaxGeschwindigkeit); + virtual ~Fahrrad(); + + double dGeschwindigkeit() const; +}; + +#endif /* FAHRRAD_H_ */ diff --git a/Aufgabenblock_3/Fahrzeug.cpp b/Aufgabenblock_3/Fahrzeug.cpp new file mode 100644 index 0000000..ffeb48e --- /dev/null +++ b/Aufgabenblock_3/Fahrzeug.cpp @@ -0,0 +1,125 @@ +#include +#include +#include + +#include "Fahrzeug.h" +#include "Weg.h" +#include "FzgFahren.h" +#include "FzgParken.h" +#include "SimuClient.h" + +extern double dGlobaleZeit; + +/* Standardkonstruktor */ +Fahrzeug::Fahrzeug() : + AktivesVO() { + vInitialisierung(); +} + +Fahrzeug::Fahrzeug(string sName) : + AktivesVO(sName) { + vInitialisierung(); +} + +Fahrzeug::Fahrzeug(string sName, double dMaxGeschwindkeit) : + AktivesVO(sName) { + vInitialisierung(); + p_dMaxGeschwindigkeit = dMaxGeschwindkeit; +} + +/* Kopierkonstruktor */ +Fahrzeug::Fahrzeug(Fahrzeug &fz) : AktivesVO(fz) { + vInitialisierung(); + p_dMaxGeschwindigkeit = fz.p_dMaxGeschwindigkeit; +} + +/* Destruktor */ +Fahrzeug::~Fahrzeug() { +} + +void Fahrzeug::vInitialisierung() { + p_dMaxGeschwindigkeit = 0; + p_dGesamtStrecke = 0; + p_dAbschnittStrecke = 0; + p_dGesamtZeit = 0; + p_pVerhalten = NULL; +} + +ostream& Fahrzeug::ostreamAusgabe(ostream &stream) const { + AktivesVO::ostreamAusgabe(stream) << setprecision(2) + << resetiosflags(ios::left) << setiosflags(ios::right) + << setw(8) << dGeschwindigkeit() + << setw(7) << p_dGesamtStrecke << " (" + << setw(6) << p_dAbschnittStrecke << ")"; + + return stream; +} + +istream& Fahrzeug::istreamEingabe(istream &stream) { + AktivesVO::istreamEingabe(stream) >> p_dMaxGeschwindigkeit; + + return stream; +} + +void Fahrzeug::vAbfertigung() { + /* nicht doppelt abfertigen (Gleitkommavgl.) */ + if (p_dZeit >= dGlobaleZeit - 1e-5) return; + + double dDelta = dGlobaleZeit - p_dZeit;; + double dStrecke = p_pVerhalten->dStrecke(this, dDelta); + + p_dGesamtZeit += dDelta; + p_dGesamtStrecke += dStrecke; + p_dAbschnittStrecke += dStrecke; + + p_dZeit = dGlobaleZeit; /* wird nur aktualisiert, falls keine Ausnahme aufgetreten ist */ +} + +double Fahrzeug::dGeschwindigkeit() const { + if (p_pVerhalten != NULL) { + Weg *pWeg = p_pVerhalten->getWeg(); + + if (pWeg != NULL) { + double dBeschraenkung = pWeg->getMaxGeschwindigkeit(); + + if (p_dMaxGeschwindigkeit > dBeschraenkung) { + return dBeschraenkung; + } + } + } + + return p_dMaxGeschwindigkeit; + +} + +double Fahrzeug::dTanken(double dMenge) { + return 0; +} + +void Fahrzeug::vNeueStrecke(Weg *pWeg, double dStartZeit) { + if (p_pVerhalten != NULL) { /* alter Weg vorhanden? */ + delete p_pVerhalten; /* Speicherleck vermeiden! */ + } + + if (dStartZeit > 0) { + p_pVerhalten = new FzgParken(pWeg, dStartZeit); + } + else { + p_pVerhalten = new FzgFahren(pWeg); + } + + p_dAbschnittStrecke = 0; +} + +double Fahrzeug::getAbschnittStrecke() const { + return p_dAbschnittStrecke; +} + +bool Fahrzeug::operator<(Fahrzeug &fz) const { + return (this->p_dGesamtStrecke < fz.p_dGesamtStrecke); +} + +void Fahrzeug::vZeichnen() const { + Weg *pWeg = p_pVerhalten->getWeg(); + bZeichneFahrrad(getName(), pWeg->getName(), getAbschnittStrecke() / pWeg->getLaenge(), dGeschwindigkeit()); +} diff --git a/Aufgabenblock_3/Fahrzeug.h b/Aufgabenblock_3/Fahrzeug.h new file mode 100644 index 0000000..e211d32 --- /dev/null +++ b/Aufgabenblock_3/Fahrzeug.h @@ -0,0 +1,45 @@ +#ifndef FAHRZEUG_H_ +#define FAHRZEUG_H_ + +#include "AktivesVO.h" +#include "FzgVerhalten.h" + +using namespace std; + +class Weg; + +class Fahrzeug : public AktivesVO { +public: + Fahrzeug(); + Fahrzeug(Fahrzeug &fz); /* Kopier Konstruktor */ + Fahrzeug(string sName); + Fahrzeug(string sName, double dMaxGeschwindkeit); + + virtual ~Fahrzeug(); /* Destruktor */ + + virtual void vAbfertigung(); + virtual double dTanken(double dMenge = 0.0); + virtual void vZeichnen() const; + virtual double dGeschwindigkeit() const; + void vNeueStrecke(Weg *pWeg, double dStartZeit = 0.0); + + double getAbschnittStrecke() const; + + bool operator<(Fahrzeug &fz) const; + //Fahrzeug & operator=(Fahrzeug &fz); /* benutze Standardzuweisungs Operator */ + + virtual ostream& ostreamAusgabe(ostream &stream) const; + virtual istream& istreamEingabe(istream &stream); + +protected: + double p_dMaxGeschwindigkeit; + double p_dGesamtStrecke; + double p_dGesamtZeit; + double p_dAbschnittStrecke; + FzgVerhalten * p_pVerhalten; + +private: + void vInitialisierung(); +}; + +#endif /* FAHRZEUG_H_ */ diff --git a/Aufgabenblock_3/FzgFahren.cpp b/Aufgabenblock_3/FzgFahren.cpp new file mode 100644 index 0000000..e429afe --- /dev/null +++ b/Aufgabenblock_3/FzgFahren.cpp @@ -0,0 +1,34 @@ +#include +#include + +#include "FzgFahren.h" +#include "Fahrzeug.h" +#include "Streckenende.h" + +using namespace std; + +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() - 1e-5) { /* bereits zuweit gefahren */ + throw Streckenende(pFz, p_pWeg); + } + else if (pFz->getAbschnittStrecke() + dStrecke > p_pWeg->getSchranke() - 1e-5) { + return p_pWeg->getSchranke() - pFz->getAbschnittStrecke(); + } + else if (pFz->getAbschnittStrecke() + dStrecke > p_pWeg->getLaenge() - 1e-5) { /* fahre nur bis zum Streckenende */ + return p_pWeg->getLaenge() - pFz->getAbschnittStrecke(); + } + else { /* fahre maximal mögliche Strecke */ + p_pWeg->setSchranke(pFz->getAbschnittStrecke() + dStrecke); + //cout << "Schranke gesetzt: " << p_pWeg->getSchranke() << " von: " << pFz->getName() << endl; + return dStrecke; + } +} + diff --git a/Aufgabenblock_3/FzgFahren.h b/Aufgabenblock_3/FzgFahren.h new file mode 100644 index 0000000..acd821f --- /dev/null +++ b/Aufgabenblock_3/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_3/FzgParken.cpp b/Aufgabenblock_3/FzgParken.cpp new file mode 100644 index 0000000..ed9594d --- /dev/null +++ b/Aufgabenblock_3/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 - 1e-5) { + return 0.0; + } + else { + throw Losfahren(pFz, p_pWeg); + } +} diff --git a/Aufgabenblock_3/FzgParken.h b/Aufgabenblock_3/FzgParken.h new file mode 100644 index 0000000..0e55756 --- /dev/null +++ b/Aufgabenblock_3/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_3/FzgVerhalten.cpp b/Aufgabenblock_3/FzgVerhalten.cpp new file mode 100644 index 0000000..83902d1 --- /dev/null +++ b/Aufgabenblock_3/FzgVerhalten.cpp @@ -0,0 +1,15 @@ +#include "FzgVerhalten.h" + +extern double dGlobaleZeit; + +FzgVerhalten::FzgVerhalten(Weg *pWeg) { + p_pWeg = pWeg; +} + +/* Destruktor */ +FzgVerhalten::~FzgVerhalten() +{ } + +Weg * FzgVerhalten::getWeg() { + return p_pWeg; +} diff --git a/Aufgabenblock_3/FzgVerhalten.h b/Aufgabenblock_3/FzgVerhalten.h new file mode 100644 index 0000000..87d5498 --- /dev/null +++ b/Aufgabenblock_3/FzgVerhalten.h @@ -0,0 +1,19 @@ +#ifndef FZGVERHALTEN_H_ +#define FZGVERHALTEN_H_ + +#include "Weg.h" + +class FzgVerhalten { +public: + FzgVerhalten(Weg *pWeg); + virtual ~FzgVerhalten(); + + virtual double dStrecke(Fahrzeug *pFz, double dDelta) = 0; + Weg * getWeg(); + +protected: + Weg *p_pWeg; + +}; + +#endif /* FZGVERHALTEN_H_ */ diff --git a/Aufgabenblock_3/Kreuzung.cpp b/Aufgabenblock_3/Kreuzung.cpp new file mode 100644 index 0000000..6267e7d --- /dev/null +++ b/Aufgabenblock_3/Kreuzung.cpp @@ -0,0 +1,123 @@ +#include +#include +#include + +#include "Kreuzung.h" +#include "Fahrzeug.h" + +using namespace std; + +extern double dGlobaleZeit; + +Kreuzung::Kreuzung() : + AktivesVO() +{} + +Kreuzung::Kreuzung(string sName, double dTankvolumen) : + AktivesVO(sName), + p_dTankstelle(dTankvolumen) +{ } + +void Kreuzung::vVerbinde(Kreuzung *pZielKreuzung, string sHinweg, string sRueckweg, double dLaenge, Weg::Begrenzung eLimit, bool bUeberholverbot) { + Weg *pHinweg = new Weg(sHinweg, dLaenge, eLimit, bUeberholverbot); + Weg *pRueckweg = new Weg(sRueckweg, dLaenge, eLimit, bUeberholverbot); + + pHinweg->setZielKreuzung(pZielKreuzung); + pRueckweg->setZielKreuzung(this); + + pHinweg->setRueckweg(pRueckweg); + pRueckweg->setRueckweg(pHinweg); + + p_lWege.push_back(pHinweg); + pZielKreuzung->p_lWege.push_back(pRueckweg); +} + +void Kreuzung::vTanken(Fahrzeug *pFz) { + if (p_dTankstelle > 0) { + p_dTankstelle -= pFz->dTanken(); /* immmer volltanken */ + } + else { + p_dTankstelle = 0; + } +} + +void Kreuzung::vAnnahme(Fahrzeug *pFz, double dStartZeit, Weg *pNeuerWeg) { + if (pNeuerWeg != NULL) { + pNeuerWeg->vAnnahme(pFz, dStartZeit); + } + else { + p_lWege.front()->vAnnahme(pFz, dStartZeit); + } +} + +double Kreuzung::getTankinhalt() { + return p_dTankstelle; +} + +void Kreuzung::vAbfertigung() { + if (p_dZeit >= dGlobaleZeit - 1e-10) return; + + list::iterator it; + for (it = p_lWege.begin(); it != p_lWege.end(); it++) { + (*it)->vAbfertigung(); + } + + p_dZeit = dGlobaleZeit; +} + +void Kreuzung::vZeichnen() const { + list::const_iterator it; + for (it = p_lWege.begin(); it != p_lWege.end(); it++) { + (*it)->vZeichnen(); + } +} + +void Kreuzung::vZeichnen(Koordinaten iKoordinaten) const { + bZeichneKreuzung(iKoordinaten.x, iKoordinaten.y); +} + +ostream& Kreuzung::ostreamAusgabe(ostream &stream) const { + AktivesVO::ostreamAusgabe(stream) << setprecision(2) + << resetiosflags(ios::left) << setiosflags(ios::right) + << setw(8) << p_dTankstelle << " ( "; + + list::const_iterator it; + for (it = p_lWege.begin(); it != p_lWege.end(); it++) { + stream << (*it)->getName() << " "; + } + stream << ")"; + + + for (it = p_lWege.begin(); it != p_lWege.end(); it++) { + stream << endl << **it; + } + + return stream; +} + +istream& Kreuzung::istreamEingabe(istream &stream) { + AktivesVO::istreamEingabe(stream) >> p_dTankstelle; + + return stream; +} + +Weg * Kreuzung::pZufaelligerWeg(Weg *pAlterWeg) { + Weg *pZufallWeg = NULL; + + do { + list::iterator it; + int iZufall = rand() % p_lWege.size(); + int i = 0; + + for (it = p_lWege.begin(); it != p_lWege.end(); it++) { + pZufallWeg = *it; + + if (i++ >= iZufall) break; + } + } while (pZufallWeg == pAlterWeg->getRueckweg() && p_lWege.size() > 1); + + return pZufallWeg; +} + +Kreuzung::~Kreuzung() +{ } diff --git a/Aufgabenblock_3/Kreuzung.h b/Aufgabenblock_3/Kreuzung.h new file mode 100644 index 0000000..f1d1cd8 --- /dev/null +++ b/Aufgabenblock_3/Kreuzung.h @@ -0,0 +1,32 @@ +#ifndef KREUZUNG_H_ +#define KREUZUNG_H_ + +#include "SimuClient.h" +#include "AktivesVO.h" +#include "Weg.h" + +class Kreuzung: public AktivesVO { +public: + Kreuzung(); + Kreuzung(string sName, double dTankvolumen = 0); + virtual ~Kreuzung(); + + void vVerbinde(Kreuzung *pZielKreuzung, string sHinweg, string sRueckweg, double dLaenge, Weg::Begrenzung eLimit, bool bUeberholverbot); + void vTanken(Fahrzeug *pFz); + void vAnnahme(Fahrzeug *pFz, double dStartZeit = 0, Weg *pAlterWeg = NULL); + void vAbfertigung(); + void vZeichnen() const; + void vZeichnen(Koordinaten iKoordinaten) const; + Weg * pZufaelligerWeg(Weg *pAlterWeg); + + double getTankinhalt(); + + ostream& ostreamAusgabe(ostream &stream) const; + istream& istreamEingabe(istream &stream); + +private: + list p_lWege; + double p_dTankstelle; +}; + +#endif /* KREUZUNG_H_ */ diff --git a/Aufgabenblock_3/LazyAktion.h b/Aufgabenblock_3/LazyAktion.h new file mode 100644 index 0000000..bcaaf6f --- /dev/null +++ b/Aufgabenblock_3/LazyAktion.h @@ -0,0 +1,82 @@ +#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 auf die die Aktionen angewendet werden sollen +}; + +// 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: + using LazyAktion::p_ptLazyListe; /* für gcc notwendig */ + T p_tObjekt; +}; + +// LazyPushBack +template class LazyPushBack : public LazyAktion { + +public: + LazyPushBack(const T &einObjekt, list *eineListe) : + LazyAktion (eineListe), + p_tObjekt(einObjekt) + { } + + virtual ~LazyPushBack() { } + + void vAusfuehren() { + p_ptLazyListe->push_back(p_tObjekt); + } + +private: + using LazyAktion::p_ptLazyListe; /* für gcc notwendig */ + T p_tObjekt; +}; + +template class LazyErase : public LazyAktion { + // typedef für iterator + typedef typename list::iterator iterator; + typedef typename list::const_iterator const_iterator; + +public: + LazyErase(const iterator &itObjekt, list *eineListe) : + LazyAktion (eineListe), + p_itObjekt(itObjekt) + { } + + virtual ~LazyErase() { } + + void vAusfuehren() { + p_ptLazyListe->erase(p_itObjekt); + } + +private: + using LazyAktion::p_ptLazyListe; /* für gcc notwendig */ + iterator p_itObjekt; // bei erase Iterator speichern +}; + +#endif /* LAZYAKTION_H_ */ diff --git a/Aufgabenblock_3/LazyListe.h b/Aufgabenblock_3/LazyListe.h new file mode 100644 index 0000000..90d974d --- /dev/null +++ b/Aufgabenblock_3/LazyListe.h @@ -0,0 +1,94 @@ +#ifndef LAZYLISTE_H_ +#define LAZYLISTE_H_ + +#include + +#include "LazyAktion.h" + +using namespace std; + +template class LazyListe { + +public: + // typedef für 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 { + return p_ListeObjekte.end(); + } + + iterator begin() { + return p_ListeObjekte.begin(); + } + + iterator end() { + return p_ListeObjekte.end(); + } + + bool empty() const { + return p_ListeObjekte.empty(); + } + + // Schreibfunktionen + void push_back(const T einObjekt) { + p_ListeAktionen.push_back(new LazyPushBack(einObjekt, &p_ListeObjekte)); + bChanged = true; + } + + void push_front(const T einObjekt) { + p_ListeAktionen.push_back(new LazyPushFront(einObjekt, &p_ListeObjekte)); + bChanged = true; + } + + void erase(iterator itObjekt) { + p_ListeAktionen.push_back(new LazyErase(itObjekt, &p_ListeObjekte)); + bChanged = true; + } + + // Änderungen auf Objektliste übertragen + void vAktualisieren() { + if (bChanged) { + // ausstehende Aktionen durchfuehren + typename list *>::const_iterator it; // TODO warum typename?! + for (it = p_ListeAktionen.begin(); it != p_ListeAktionen.end(); it++) { + // Aktion ausführen + LazyAktion *pAktion = *it; + pAktion->vAusfuehren(); + + // Zeiger auf Action-Element löschen + delete *it; + } + // Liste der Aktionen leeren + p_ListeAktionen.clear(); + + bChanged = false; + } + } + +private: + list p_ListeObjekte; + list *> p_ListeAktionen; + bool bChanged; +}; + +#endif /* LAZYLISTE_H_ */ diff --git a/Aufgabenblock_3/Losfahren.cpp b/Aufgabenblock_3/Losfahren.cpp new file mode 100644 index 0000000..1855497 --- /dev/null +++ b/Aufgabenblock_3/Losfahren.cpp @@ -0,0 +1,18 @@ +#include + +#include "Losfahren.h" + +using namespace std; + +Losfahren::Losfahren(Fahrzeug *pFahrzeug, Weg *pWeg) : FahrAusnahme(pFahrzeug, pWeg) +{ } + +Losfahren::~Losfahren() +{ } + +void Losfahren::vBearbeiten() { + cerr << "Fahrausnahme: Losfahren (Fzg: " << *p_pFahrzeug << ", Weg: " << *p_pWeg << ")" << endl; + + p_pWeg->vAbgabe(p_pFahrzeug); + p_pWeg->vAnnahme(p_pFahrzeug); +} diff --git a/Aufgabenblock_3/Losfahren.h b/Aufgabenblock_3/Losfahren.h new file mode 100644 index 0000000..32dfb59 --- /dev/null +++ b/Aufgabenblock_3/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_3/PKW.cpp b/Aufgabenblock_3/PKW.cpp new file mode 100644 index 0000000..2b774d5 --- /dev/null +++ b/Aufgabenblock_3/PKW.cpp @@ -0,0 +1,97 @@ +#include +#include + +#include "PKW.h" +#include "SimuClient.h" + +using namespace std; + +extern double dGlobaleZeit; + +/* Standardkonstruktor */ +PKW::PKW() : + Fahrzeug(), + p_dVerbrauch(0), + p_dTankinhalt(0), + p_dTankvolumen(0) +{ } + +PKW::PKW(string sName, double dMaxGeschwindigkeit) : + Fahrzeug(sName, dMaxGeschwindigkeit), + p_dVerbrauch(0), + p_dTankinhalt(0), + p_dTankvolumen(0) +{ } + +PKW::PKW(string sName, double dMaxGeschwindigkeit, double dVerbrauch, double dTankvolumen) : + Fahrzeug(sName, dMaxGeschwindigkeit), + p_dVerbrauch(dVerbrauch), + p_dTankinhalt(dTankvolumen / 2), + p_dTankvolumen(dTankvolumen) +{ } + +/* Destruktor */ +PKW::~PKW() +{ } + +double PKW::dTanken(double dMenge) { + double dAlterInhalt = p_dTankinhalt; + + if (dMenge == 0) { + p_dTankinhalt = p_dTankvolumen; + } else { + p_dTankinhalt += dMenge; + if (p_dTankinhalt > p_dTankvolumen) { + p_dTankinhalt = p_dTankvolumen; /* Verhindere Ãœberfüllung */ + } + } + + return p_dTankinhalt - dAlterInhalt; +} + +void PKW::vZeichnen() const { + Weg *pWeg = p_pVerhalten->getWeg(); + bZeichnePKW(getName(), pWeg->getName(), getAbschnittStrecke() / pWeg->getLaenge(), dGeschwindigkeit(), getTankinhalt()); +} + +void PKW::vAbfertigung() { + if (p_dTankinhalt > 0) { /* prüfen, ob etwas im Tank ist */ + double dDelta = dGlobaleZeit - p_dZeit; + double dStrecke = p_pVerhalten->dStrecke(this, dDelta); + + p_dTankinhalt -= dStrecke * p_dVerbrauch / 100; + + if (p_dTankinhalt < 0) { /* falls Tankinhalt negativ ist */ + p_dTankinhalt = 0; + } + + Fahrzeug::vAbfertigung(); + } + else { + p_dZeit = dGlobaleZeit; + } +} + +ostream& PKW::ostreamAusgabe(ostream &stream) const { + Fahrzeug::ostreamAusgabe(stream) << setprecision(2) << setiosflags(ios::fixed) + << resetiosflags(ios::left) << setiosflags(ios::right) + << setw(12) << dVerbrauch() + << setw(13) << p_dTankinhalt; + + return stream; +} + +istream& PKW::istreamEingabe(istream &stream) { + Fahrzeug::istreamEingabe(stream) >> p_dVerbrauch >> p_dTankvolumen; + p_dTankinhalt = p_dTankvolumen/2; + + return stream; +} + +double PKW::dVerbrauch() const { + return p_dGesamtStrecke * p_dVerbrauch / 100; +} + +double PKW::getTankinhalt() const { + return p_dTankinhalt; +} diff --git a/Aufgabenblock_3/PKW.h b/Aufgabenblock_3/PKW.h new file mode 100644 index 0000000..b1b20b3 --- /dev/null +++ b/Aufgabenblock_3/PKW.h @@ -0,0 +1,39 @@ +/* + * PKW.h + * + * Created on: 18.08.2011 + * Author: stv0g + */ + +#ifndef PKW_H_ +#define PKW_H_ + +#include + +#include "Fahrzeug.h" + +using namespace std; + +class PKW: public Fahrzeug { +public: + PKW(); + PKW(string sName, double dMaxGeschwindigkeit); + PKW(string sName, double dMaxGeschwindigkeit, double dVerbrauch, double dTankvolumen = 55); + virtual ~PKW(); + + void vAbfertigung(); + double dVerbrauch() const; + double dTanken(double dMenge = 0.0); + void vZeichnen() const; + double getTankinhalt() const; + + ostream& ostreamAusgabe(ostream &stream) const; + istream& istreamEingabe(istream &stream); + +private: + double p_dVerbrauch; + double p_dTankinhalt; + double p_dTankvolumen; +}; + +#endif /* PKW_H_ */ diff --git a/Aufgabenblock_3/SimuClient.h b/Aufgabenblock_3/SimuClient.h new file mode 100644 index 0000000..f20ec4e --- /dev/null +++ b/Aufgabenblock_3/SimuClient.h @@ -0,0 +1,46 @@ +/* + * 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; + +typedef struct { + int x; + int y; +} Koordinaten; + +// Funktionen der Library +bool bInitialisiereGrafik(int sizeX, int sizeY, bool bStarteServer = true, const string& sServer = "localhost", const unsigned short iPort = 7654); +bool bZeichneKreuzung(int posX, int posY); +bool bZeichneStrasse(const string& way_to_name, const string& way_back_name, int length, int numPoints, int* points_xy); +bool bZeichnePKW(const string& carname, const string& streetname, double rel_position, double speed, double tank); +bool bZeichneFahrrad(const string& bikename, const string& streetname, double relposition, double speed); +void vSetzeZeit(const double dTime); // sendet die Simulationszeit an den erweiterten Grafikserver +void Sleep(const int mSec); // ersetzt die Sleep()-Funktion von Windows, die mSek �bernimmt +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 +// eof diff --git a/Aufgabenblock_3/SimuServer.jar b/Aufgabenblock_3/SimuServer.jar new file mode 100644 index 0000000..e8c7e93 Binary files /dev/null and b/Aufgabenblock_3/SimuServer.jar differ diff --git a/Aufgabenblock_3/Streckenende.cpp b/Aufgabenblock_3/Streckenende.cpp new file mode 100644 index 0000000..06e3da4 --- /dev/null +++ b/Aufgabenblock_3/Streckenende.cpp @@ -0,0 +1,27 @@ +#include + +#include "Streckenende.h" +#include "Kreuzung.h" + +using namespace std; + +Streckenende::Streckenende(Fahrzeug *pFahrzeug, Weg *pWeg) : FahrAusnahme(pFahrzeug, pWeg) +{ } + +Streckenende::~Streckenende() +{ } + +void Streckenende::vBearbeiten() { + Kreuzung *pZielKreuzung = p_pWeg->getZielKreuzung(); + Weg *pNeuerWeg = pZielKreuzung->pZufaelligerWeg(p_pWeg); /* wähle zufälligen Weg */ + + p_pWeg->vAbgabe(p_pFahrzeug); + pZielKreuzung->vTanken(p_pFahrzeug); + pZielKreuzung->vAnnahme(p_pFahrzeug, 0, pNeuerWeg); + + cerr << "Fahrausnahme: Fahrzeug wird umgesetzt (" + << "Fzg: " << p_pFahrzeug->getName() + << ", Weg: " << p_pWeg->getName() << " => " << pNeuerWeg->getName() + << ", Kreuz.: " << pZielKreuzung->getName() << " (Tank: " << pZielKreuzung->getTankinhalt() << ")" + << ")" << endl; +} diff --git a/Aufgabenblock_3/Streckenende.h b/Aufgabenblock_3/Streckenende.h new file mode 100644 index 0000000..8a34497 --- /dev/null +++ b/Aufgabenblock_3/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_ */ diff --git a/Aufgabenblock_3/Weg.cpp b/Aufgabenblock_3/Weg.cpp new file mode 100644 index 0000000..4dd9eb1 --- /dev/null +++ b/Aufgabenblock_3/Weg.cpp @@ -0,0 +1,147 @@ +#include +#include +#include +#include + +#include "SimuClient.h" +#include "Weg.h" +#include "Fahrzeug.h" +#include "FahrAusnahme.h" + +extern double dGlobaleZeit; + +/* Standardkonstruktor */ +Weg::Weg() : AktivesVO() +{ } + +Weg::Weg(string sName, double dLaenge, Begrenzung eLimit, bool bUeberholverbot) : + AktivesVO(sName), + p_dLaenge(dLaenge), + p_dUeberholverbot(bUeberholverbot), + p_eLimit(eLimit), + p_pZielKreuzung(NULL), + p_pRueckweg(NULL) +{ } + +/* Destruktor */ +Weg::~Weg() +{ } + +/* fertige alle Fahrzeuge auf Weg ab */ +void Weg::vAbfertigung() { + LazyListe::iterator it; + p_dSchranke = p_dLaenge; + + p_lFahrzeuge.vAktualisieren(); + for (it = p_lFahrzeuge.begin(); it != p_lFahrzeuge.end(); it++) { + try { + (*it)->vAbfertigung(); + } catch (FahrAusnahme &ausnahme) { + ausnahme.vBearbeiten(); + //(*it)->vAbfertigung(); + } + } + + p_lFahrzeuge.vAktualisieren(); + p_dZeit = dGlobaleZeit; +} + +void Weg::vAnnahme(Fahrzeug *pFz, double dStartZeit) { + pFz->vNeueStrecke(this, dStartZeit); + + if (dStartZeit > 0) { /* parkende Fahrzeuge werden vorne eingef�gt */ + p_lFahrzeuge.push_front(pFz); + } + else { /* fahrende hinten */ + p_lFahrzeuge.push_back(pFz); + } +} + +void Weg::vAbgabe(Fahrzeug *pFz) { + LazyListe::iterator result; + + result = find(p_lFahrzeuge.begin(), p_lFahrzeuge.end(), pFz); + + if (result != p_lFahrzeuge.end()) { /* gefunden */ + p_lFahrzeuge.erase(result); + } +} + +void Weg::vZeichnen(size_t iAnzahlKoordinaten, Koordinaten iKoordinaten[]) const { + bZeichneStrasse(getName(), p_pRueckweg->getName(), getLaenge(), iAnzahlKoordinaten, (int *) iKoordinaten); +} + +void Weg::vZeichnen() const { + LazyListe::const_iterator it; + for (it = p_lFahrzeuge.begin(); it != p_lFahrzeuge.end(); it++) { + (*it)->vZeichnen(); + } +} + +double Weg::getLaenge() const { + return p_dLaenge; +} + +double Weg::getSchranke() const { + return p_dSchranke; +} + +void Weg::setSchranke(double dSchranke) { + p_dSchranke = dSchranke; +} + +void Weg::setRueckweg(Weg * pRueckweg) { + p_pRueckweg = pRueckweg; +} + +Weg * Weg::getRueckweg() { + return p_pRueckweg; +} + +void Weg::setZielKreuzung(Kreuzung * pZielKreuzung) { + p_pZielKreuzung = pZielKreuzung; +} + +Kreuzung * Weg::getZielKreuzung() { + return p_pZielKreuzung; +} + +double Weg::getMaxGeschwindigkeit() const { + switch (p_eLimit) { + case Weg::Innerorts: return 50; + case Weg::Landstrasse: return 100; + case Weg::Autobahn: return DBL_MAX; /* unbegrenzt */ + default: return 0; + } +} + + +ostream& Weg::ostreamAusgabe(ostream &stream) const { + double dMaxGeschwindigkeit = getMaxGeschwindigkeit(); + + AktivesVO::ostreamAusgabe(stream) << setprecision(2) + << resetiosflags(ios::left) << setiosflags(ios::right) + << setw(8); + + if (dMaxGeschwindigkeit == DBL_MAX) { + stream << "(inf)"; + } + else { + stream << dMaxGeschwindigkeit; + } + + stream << setw(16) << p_dLaenge << " ( "; + + LazyListe::const_iterator it; + for (it = p_lFahrzeuge.begin(); it != p_lFahrzeuge.end(); it++) { + stream << (*it)->getName() << " "; + } + + stream << ")"; + + for (it = p_lFahrzeuge.begin(); it != p_lFahrzeuge.end(); it++) { + stream << endl << **it; + } + + return stream; +} diff --git a/Aufgabenblock_3/Weg.h b/Aufgabenblock_3/Weg.h new file mode 100644 index 0000000..55061fd --- /dev/null +++ b/Aufgabenblock_3/Weg.h @@ -0,0 +1,57 @@ +#ifndef WEG_H_ +#define WEG_H_ + +#include +#include + +#include "AktivesVO.h" +#include "LazyListe.h" +#include "SimuClient.h" + +using namespace std; + +/* Forward Deklarationen */ +class Fahrzeug; +class Kreuzung; + +class Weg : public AktivesVO { +public: + typedef enum { + Innerorts, /* 50 km/h */ + Landstrasse, /* 100 km/h */ + Autobahn /* unbegrenzt */ + } Begrenzung; + + Weg(); + Weg(string sName, double dLaenge, Begrenzung eLimit = Autobahn, bool dUeberholverbot = true); + virtual ~Weg(); + + void vAbfertigung(); + void vAnnahme(Fahrzeug *pFz, double dStartZeit = 0); + void vAbgabe(Fahrzeug *pFz); + void vZeichnen(size_t iAnzahlKoordinaten, Koordinaten iKoordinaten[]) const; /* zeichnet Weg */ + void vZeichnen() const; /* zeichnet Fahrzeuge, die sich auf dem Weg befinden */ + + double getMaxGeschwindigkeit() const; + double getSchranke() const; + void setSchranke(double dSchranke); + double getLaenge() const; + void setRueckweg(Weg * pRueckweg); + Weg * getRueckweg(); + void setZielKreuzung(Kreuzung * pZielKreuzung); + Kreuzung * getZielKreuzung(); + + ostream& ostreamAusgabe(ostream &stream) const; + +private: + double p_dLaenge; + double p_dSchranke; + bool p_dUeberholverbot; + Begrenzung p_eLimit; + LazyListe p_lFahrzeuge; + + Kreuzung *p_pZielKreuzung; + Weg *p_pRueckweg; +}; + +#endif /* WEG_H_ */ diff --git a/Aufgabenblock_3/Welt.cpp b/Aufgabenblock_3/Welt.cpp new file mode 100644 index 0000000..cc1e34f --- /dev/null +++ b/Aufgabenblock_3/Welt.cpp @@ -0,0 +1,185 @@ +#include +#include + +#include "Welt.h" +#include "PKW.h" +#include "Weg.h" +#include "Fahrrad.h" + +Welt::Welt() +{ } + +Welt::~Welt() +{ } + +void Welt::vAbfertigung() { + list::iterator it; + for (it = p_pKreuzungen.begin(); it != p_pKreuzungen.end(); it++) { + (*it)->vAbfertigung(); + } +} + +void Welt::vZeichnen() { + list::iterator it; + for (it = p_pKreuzungen.begin(); it != p_pKreuzungen.end(); it++) { + (*it)->vZeichnen(); + } +} + +ostream& Welt::ostreamAusgabe(ostream &stream) const { + list::const_iterator it; + for (it = p_pKreuzungen.begin(); it != p_pKreuzungen.end(); it++) { + stream << **it << endl; + } + + return stream; +} + +ostream& operator<<(ostream &stream, const Welt &w) { + return w.ostreamAusgabe(stream); +} + +void Welt::vEinlesen(istream &in) { + while (!in.eof()) { + string sTyp; + in >> sTyp; + + if (sTyp == "KREUZUNG") { + Kreuzung *pKr = new Kreuzung; + in >> *pKr; + + p_pKreuzungen.push_back(pKr); + } + else if (sTyp == "STRASSE") { + string sQuellKreuzung, sZielKreuzung; + string sHinweg, sRueckweg; + double dLaenge; + int eLimit; + bool bUeberholverbot; + + /* Daten einlesen */ + in >> sQuellKreuzung + >> sZielKreuzung + >> sHinweg + >> sRueckweg + >> dLaenge + >> eLimit + >> bUeberholverbot; + + /* Kreuzungen suchen */ + Kreuzung *pQuellKreuzung = static_cast(AktivesVO::pObjekt(sQuellKreuzung)); + Kreuzung *pZielKreuzung = static_cast(AktivesVO::pObjekt(sZielKreuzung)); + + eLimit--; + if (eLimit > 2 || eLimit < 0) { + throw string("Ungültige Geschwindikeitsbegrenzung (0-2)"); + } + + /* Kreuzungen verbinden & Wege erstellen */ + pQuellKreuzung->vVerbinde(pZielKreuzung, sHinweg, sRueckweg, dLaenge, static_cast(eLimit), bUeberholverbot); + } + else if (sTyp == "PKW") { + PKW *pPkw = new PKW(); + string sStartKreuzung; + double dStartZeit; + + /* Daten einlesen */ + in >> *pPkw >> sStartKreuzung >> dStartZeit; + + /* PKW einsetzen */ + Kreuzung *pStartKreuzung = static_cast(AktivesVO::pObjekt(sStartKreuzung)); + pStartKreuzung->vAnnahme(pPkw, dStartZeit); + } + else if (sTyp == "FAHRRAD") { + Fahrrad *pRad = new Fahrrad(); + string sStartKreuzung; + double dStartZeit; + + /* Daten einlesen */ + in >> *pRad >> sStartKreuzung >> dStartZeit; + + /* PKW einsetzen */ + Kreuzung *pStartKreuzung = static_cast(AktivesVO::pObjekt(sStartKreuzung)); + pStartKreuzung->vAnnahme(pRad, dStartZeit); + } + else if (sTyp != "") { + throw string("Unbekannter Typ!"); + } + } +} + +void Welt::vEinlesenMitGrafik(istream &in) { + while (!in.eof()) { + string sTyp; + in >> sTyp; + + if (sTyp == "KREUZUNG") { + Kreuzung *pKr = new Kreuzung; + Koordinaten iPos; + in >> *pKr >> iPos.x >> iPos.y; + + pKr->vZeichnen(iPos); + p_pKreuzungen.push_back(pKr); + } + else if (sTyp == "STRASSE") { + string sQuellKreuzung, sZielKreuzung; + string sHinweg, sRueckweg; + double dLaenge; + int eLimit, iAnzahlKoordinaten; + bool bUeberholverbot; + + /* Daten einlesen */ + in >> sQuellKreuzung + >> sZielKreuzung + >> sHinweg + >> sRueckweg + >> dLaenge + >> eLimit + >> bUeberholverbot + >> iAnzahlKoordinaten; + + Koordinaten *iPoly = new Koordinaten[iAnzahlKoordinaten]; + for (int i = 0; i < iAnzahlKoordinaten; i++) { + in >> iPoly[i].x >> iPoly[i].y; + } + + /* Kreuzungen suchen */ + Kreuzung *pQuellKreuzung = static_cast(AktivesVO::pObjekt(sQuellKreuzung)); + Kreuzung *pZielKreuzung = static_cast(AktivesVO::pObjekt(sZielKreuzung)); + + /* Kreuzungen verbinden & Wege erstellen */ + pQuellKreuzung->vVerbinde(pZielKreuzung, sHinweg, sRueckweg, dLaenge, static_cast(eLimit), bUeberholverbot); + + /* Wege Zeichnen */ + Weg *pHinweg = static_cast(AktivesVO::pObjekt(sHinweg)); + pHinweg->vZeichnen(iAnzahlKoordinaten, iPoly); + } + else if (sTyp == "PKW") { + PKW *pPkw = new PKW(); + string sStartKreuzung; + double dStartZeit; + + /* Daten einlesen */ + in >> *pPkw >> sStartKreuzung >> dStartZeit; + + /* PKW einsetzen */ + Kreuzung *pStartKreuzung = static_cast(AktivesVO::pObjekt(sStartKreuzung)); + pStartKreuzung->vAnnahme(pPkw, dStartZeit); + } + else if (sTyp == "FAHRRAD") { + Fahrrad *pRad = new Fahrrad(); + string sStartKreuzung; + double dStartZeit; + + /* Daten einlesen */ + in >> *pRad >> sStartKreuzung >> dStartZeit; + + /* PKW einsetzen */ + Kreuzung *pStartKreuzung = static_cast(AktivesVO::pObjekt(sStartKreuzung)); + pStartKreuzung->vAnnahme(pRad, dStartZeit); + } + else if (sTyp != "") { + throw string("Unbekannter Typ!"); + } + } +} diff --git a/Aufgabenblock_3/Welt.h b/Aufgabenblock_3/Welt.h new file mode 100644 index 0000000..fd8de2b --- /dev/null +++ b/Aufgabenblock_3/Welt.h @@ -0,0 +1,26 @@ +#ifndef WELT_H_ +#define WELT_H_ + +#include + +#include "Kreuzung.h" + +class Welt { +public: + Welt(); + virtual ~Welt(); + + void vAbfertigung(); + void vZeichnen(); + void vEinlesen(istream &in); + void vEinlesenMitGrafik(istream &in); + virtual ostream& ostreamAusgabe(ostream &stream) const; + +private: + list p_pKreuzungen; + +}; + +ostream& operator<<(ostream &out, const Welt &w); + +#endif /* WELT_H_ */ diff --git a/Aufgabenblock_3/libsimu.so b/Aufgabenblock_3/libsimu.so new file mode 100755 index 0000000..8f24c85 Binary files /dev/null and b/Aufgabenblock_3/libsimu.so differ diff --git a/Aufgabenblock_3/main.cpp b/Aufgabenblock_3/main.cpp new file mode 100644 index 0000000..67c7266 --- /dev/null +++ b/Aufgabenblock_3/main.cpp @@ -0,0 +1,509 @@ +#include +#include +#include +#include +#include + +#ifdef _WIN32 /* _Win32 is usually defined by compilers targeting 32 or 64 bit Windows systems */ +#include +#endif + +#include "SimuClient.h" +#include "Welt.h" +#include "Kreuzung.h" +#include "Fahrzeug.h" +#include "Fahrrad.h" +#include "PKW.h" +#include "Weg.h" +#include "LazyListe.h" + +using namespace std; + +double dGlobaleZeit; + +void vAufgabe1(int argc, char *argv[]) { + /* 3. Initialisieren */ + Fahrzeug fz1("Porsche"); + Fahrzeug *fz2 = new Fahrzeug(); + + string name; + cout << "Bitte geben Sie einen Fahrzeugnamen ein: "; + cin >> name; + + Fahrzeug *fz3 = new Fahrzeug(name, 22.5); + + Fahrzeug::vAusgabeHeader(); + cout << fz1 << endl << *fz2 << endl << *fz3 << endl; + + /* 9. Abfertigung */ + double dAbfertigungsIntervall; + cout << endl << "Bitte geben Sie ein Abfertigungsintervall ein: "; + cin >> dAbfertigungsIntervall; + + Fahrzeug::vAusgabeHeader(); + for ( ; dGlobaleZeit < 24; dGlobaleZeit += dAbfertigungsIntervall) { /* simuliere für einen Tag */ + fz1.vAbfertigung(); + fz2->vAbfertigung(); + fz3->vAbfertigung(); + + cout << fz1 << endl << *fz2 << endl << *fz3 << endl; + } + + delete fz2; + delete fz3; +} + +/** + * Testing debugger + */ +void vAufgabe1_deb(int argc, char *argv[]) { + Fahrzeug fz1("Opel"); + Fahrzeug fz2("Benz"); + Fahrzeug fz3("Ferrari"); + Fahrzeug fz4("Mini"); + + Fahrzeug *feld_name[4] = {&fz1, &fz2, &fz3, &fz4}; + + feld_name[2] = 0; // NULL pointer => Segmention Fault + + for (int i = 0; i < 4; i++) { + cout << *feld_name[i] << endl; + } +} + +void vAufgabe2(int argc, char *argv[]) { + int iPKWs, iFahrraeder; + vector fahrzeuge; + + /* Erzeugen */ + cout << "Wie viele PKWs möchten Sie erstellen? "; + cin >> iPKWs; + + cout << "Wie viele Fahrräder möchten Sie erstellen? "; + cin >> iFahrraeder; + + for (int i = 0; i < iPKWs + iFahrraeder; i++) { + Fahrzeug *fahrzeug; + string sName; + double dMaxGeschwindkeit; + + cout << "Bitte geben Sie den Namen des Fahrzeugs Nr. " << i+1 << " an: "; + cin >> sName; + cout << "Bitte geben Sie die maximale Geschwindkeit des Fahrzeugs Nr. " << i+1 << " an: "; + cin >> dMaxGeschwindkeit; + + if (i < iPKWs) { /* erzeuge PKW */ + double dVerbrauch; + cout << "Bitte geben Sie den Verbrauch des PKWs Nr. " << i+1 << " an: "; + cin >> dVerbrauch; + + fahrzeug = new PKW(sName, dMaxGeschwindkeit, dVerbrauch); + } + else { /* erzeuge Fahrrad */ + fahrzeug = new Fahrrad(sName, dMaxGeschwindkeit); + } + + fahrzeuge.push_back(fahrzeug); + } + + /* Abfertigen */ + + double dAbfertigungsIntervall; + size_t iNachgetankt = 0; + cout << "Bitte geben Sie ein Abfertigungsintervall ein: "; + cin >> dAbfertigungsIntervall; + cout << endl; + + Fahrzeug::vAusgabeHeader(); + + for (dGlobaleZeit = 0; dGlobaleZeit < 6; dGlobaleZeit += dAbfertigungsIntervall) { + vector::iterator it; + for (it = fahrzeuge.begin(); it != fahrzeuge.end(); it++) { + if (dGlobaleZeit > 3 && iNachgetankt < fahrzeuge.size()) { + (*it)->dTanken(); + iNachgetankt++; + } + + (*it)->vAbfertigung(); + cout << **it << endl; + } + } +} + +void vAufgabe3(int argc, char *argv[]) { + PKW vw("Golf", 200, 6.7, 88); + Fahrrad velo("Haibike", 22); + Fahrzeug boat("Schiff", 11); + + dGlobaleZeit += 1.0; + velo.vAbfertigung(); + + Fahrzeug::vAusgabeHeader(); + cout << vw << endl << velo << endl << boat << endl << endl; + + if (vw < velo) { + cout << "Das Fahrrad ist bereits weiter gefahren"; + } + else { + cout << "Der Golf ist bereits weiter gefahren"; + } + + cout << endl << endl; + + Fahrrad veloKopie = velo; /* benutze Kopier Konstrukutor */ + Fahrrad veloKopie2; + + veloKopie2 = velo; /* benutze Zuweisungsoperator */ + + Fahrzeug::vAusgabeHeader(); + cout << veloKopie << endl << veloKopie2 << endl; +} + +void vAufgabe4(int argc, char *argv[]) { + Weg weg("Allee", 150.0, Weg::Landstrasse); + PKW vw("Golf", 55, 6.7, 88); + Fahrrad velo("Haibike", 22); + + weg.vAnnahme(&vw, 1.2); + weg.vAnnahme(&velo); + + Fahrzeug::vAusgabeHeader(); + for (dGlobaleZeit = 0; dGlobaleZeit < 3; dGlobaleZeit += 0.1) { + weg.vAbfertigung(); + cout << vw << endl << velo << endl << weg << endl; + } +} + +void vAufgabe5(int argc, char *argv[]) { + Weg hin("Hinweg", 500.0, Weg::Landstrasse); + Weg rueck("Rueckweg", 500.0, Weg::Landstrasse); + + hin.setRueckweg(&rueck); + rueck.setRueckweg(&hin); + + PKW vw("Golf", 55, 10, 20); + Fahrrad velo("Haibike", 22); + + bool bStarted = bInitialisiereGrafik(800, 600); + if (!bStarted) { + cerr << "Konnte Simulationsserver nicht starten!" << endl; + } + + Koordinaten iPoly[] = {{100, 100}, {700, 500} }; + hin.vZeichnen(2, iPoly); + + hin.vAnnahme(&vw, 1.2); + rueck.vAnnahme(&velo); + + Fahrzeug::vAusgabeHeader(); + for (dGlobaleZeit = 0; dGlobaleZeit < 15; dGlobaleZeit += 0.3) { + hin.vAbfertigung(); + rueck.vAbfertigung(); + + vSetzeZeit(dGlobaleZeit); + + hin.vZeichnen(); + rueck.vZeichnen(); + + cout << vw << endl << velo << endl << hin << endl << rueck << endl; + + Sleep(500); + } + + vBeendeGrafik(); +} + +void vAufgabe6(int argc, char *argv[]) { + Weg weg("Allee", 300.0, Weg::Landstrasse); + PKW vw("Golf", 55, 6.7, 88); + + weg.vAnnahme(&vw); + + Fahrzeug::vAusgabeHeader(); + for (dGlobaleZeit = 0; dGlobaleZeit < 10; dGlobaleZeit += 0.5) { + weg.vAbfertigung(); + cout << vw << endl << weg << endl; + } +} + +void vListeAusgeben(LazyListe &tListe) { + LazyListe::iterator it; + for (it = tListe.begin(); it != tListe.end(); it++) { + cout << *it << ", "; + } + cout << endl; +} + +void vAufgabe6a(int argc, char *argv[]) { + LazyListe tListe; + LazyListe::iterator it; + + /* Mit Zufallszahlen füllen */ + cout << "Fülle mit Zufallszahlen" << endl; + for (int i = 0; i < 10; i++) { + tListe.push_back(rand() % 10 + 1); + } + + cout << "Führe LazyAktionen aus" << endl; + tListe.vAktualisieren(); + + cout << "Gebe Liste aus: "; + vListeAusgeben(tListe); + + cout << "Lösche Werte > 5..." << endl; + for (it = tListe.begin(); it != tListe.end(); it++) { + if (*it > 5) { + tListe.erase(it); + } + } + + cout << "Gebe Liste aus: "; + vListeAusgeben(tListe); + + cout << "Führe LazyAktionen aus" << endl; + tListe.vAktualisieren(); + + cout << "Gebe Liste aus: "; + vListeAusgeben(tListe); + + cout << "Weitere Änderungen..." << endl; + tListe.push_front(44); + tListe.push_back(33); + + cout << "Führe LazyAktionen aus" << endl; + tListe.vAktualisieren(); + + cout << "Gebe Liste aus: "; + vListeAusgeben(tListe); +} + +void vAufgabe7(int argc, char *argv[]) { + PKW vw("Golf", 120, 10, 90); + Fahrrad velo("Haibike", 42); + + Weg hin("Hinweg", 500.0, Weg::Landstrasse); + Weg rueck("Rueckweg", 500.0, Weg::Landstrasse); + + hin.setRueckweg(&rueck); + rueck.setRueckweg(&hin); + + bool bStarted = bInitialisiereGrafik(800, 600); + if (!bStarted) { + cerr << "Konnte Simulationsserver nicht starten!" << endl; + } + + Koordinaten iPoly[] = {{100, 100}, {700, 500} }; + hin.vZeichnen(2, iPoly); + + hin.vAnnahme(&vw, 8); + hin.vAnnahme(&velo, 1); + + Fahrzeug::vAusgabeHeader(); + for (dGlobaleZeit = 0; dGlobaleZeit <= 30; dGlobaleZeit += 0.5) { + hin.vAbfertigung(); + + hin.vZeichnen(); + rueck.vZeichnen(); + + cout << vw << endl << velo << endl << hin << endl << "--" << endl; + + vSetzeZeit(dGlobaleZeit); + Sleep(500); + } + + vBeendeGrafik(); +} + +void vAufgabe8(int argc, char *argv[]) { + bInitialisiereGrafik(1000, 700); + + PKW vw("Golf", 120, 10, 90); + PKW ferrari("Ferrari", 320, 15, 210); + Fahrrad velo("Haibike", 42); + + Kreuzung kr1("K1"); + Kreuzung kr2("K2", 1000); + Kreuzung kr3("K3"); + Kreuzung kr4("K4"); + + kr1.vVerbinde(&kr2, "W12", "W21", 40, Weg::Innerorts, true); + kr2.vVerbinde(&kr3, "W23a", "W32a", 115, Weg::Autobahn, false); + kr2.vVerbinde(&kr3, "W23b", "W32b", 40, Weg::Innerorts, true); + kr2.vVerbinde(&kr4, "W24", "W42", 55, Weg::Innerorts, true); + kr3.vVerbinde(&kr4, "W34", "W43", 85, Weg::Autobahn, false); + kr4.vVerbinde(&kr4, "W44a", "W44b", 130, Weg::Landstrasse, false); + + Koordinaten iK1 = {680, 40}; + Koordinaten iK2 = {680, 300}; + Koordinaten iK3 = {680, 570}; + Koordinaten iK4 = {320, 300}; + + Koordinaten iW12[] = {{680, 40}, {680, 300}}; + Koordinaten iW23a[] = {{680, 300}, {850, 300}, {970, 390}, {970, 500}, {850, 570}, {680, 570}}; + Koordinaten iW23b[] = {{680, 300}, {680, 570}}; + Koordinaten iW24[] = {{680, 300}, {320, 300}}; + Koordinaten iW34[] = {{680, 570}, {500, 570}, {350, 510}, {320, 420}, {320, 300}}; + Koordinaten iW44[] = {{320, 300}, {320, 150}, {200, 60}, {80, 90}, {70, 250}, {170, 300}, {320, 300}}; + + kr1.vZeichnen(iK1); + kr2.vZeichnen(iK2); + kr3.vZeichnen(iK3); + kr4.vZeichnen(iK4); + + bZeichneStrasse("W12", "W21", 40, 2, (int *) iW12); + bZeichneStrasse("W23a", "W32a", 115, 6, (int *) iW23a); + bZeichneStrasse("W23b", "W32b", 40, 2, (int *) iW23b); + bZeichneStrasse("W24", "W42", 55, 2, (int *) iW24); + bZeichneStrasse("W34", "W43", 85, 5, (int *) iW34); + bZeichneStrasse("W44a", "W44b", 130, 7, (int *) iW44); + + kr1.vAnnahme(&vw); + kr1.vAnnahme(&velo); + kr2.vAnnahme(&ferrari, 5); + + for (dGlobaleZeit = 0.3; dGlobaleZeit <= 24; dGlobaleZeit += 0.01) { + kr1.vAbfertigung(); + kr2.vAbfertigung(); + kr3.vAbfertigung(); + kr4.vAbfertigung(); + + kr1.vZeichnen(); + kr2.vZeichnen(); + kr3.vZeichnen(); + kr4.vZeichnen(); + + Fahrzeug::vAusgabeHeader(); + cout + << vw << endl + << velo << endl + << ferrari << endl + << kr1 << endl + << kr2 << endl + << kr3 << endl + << kr4 << endl + << "--" << endl; + + vSetzeZeit(dGlobaleZeit); + Sleep(40); + } + + vBeendeGrafik(); +} + +void vAufgabe9(int argc, char *argv[]) { + ifstream File; + + File.open(argv[1]); + + if(!File.good()) { + throw string("Datei existiert nicht!"); + } + + PKW pkw; + Fahrrad rad; + Kreuzung krz; + + File >> pkw >> rad >> krz; + + Fahrzeug::vAusgabeHeader(); + cout + << pkw << endl + << rad << endl + << krz << endl; + + /* Teste map */ + string sName; + cout << "Geben Sie einen Namen zum Suchen ein: "; + cin >> sName; + cout << *AktivesVO::pObjekt(sName) << endl; + + cout << endl; + PKW pkw2("Porsche", 99); +} + +void vAufgabe9a(int argc, char *argv[]) { + ifstream File; + + File.open(argv[1]); + + if(!File.good()) { + throw string("Datei existiert nicht!"); + } + + bInitialisiereGrafik(1000, 900); + + Welt tErde; + tErde.vEinlesenMitGrafik(File); + + for (dGlobaleZeit = 0; dGlobaleZeit < 24*31; dGlobaleZeit += 0.1) { + tErde.vAbfertigung(); + tErde.vZeichnen(); + + cout << tErde << "--" << endl; + + vSetzeZeit(dGlobaleZeit); + Sleep(500); + } + + vBeendeGrafik(); +} + +typedef void (*aufgabe_t)(int argc, char *argv[]); +#define NUM_AUFGABEN 11 + +int main(int argc, char *argv[]) { + /* PRNG mit konstantem seed initialisieren */ + srand(55); + + int iWahl; + + aufgabe_t pAufgaben[] = { + &vAufgabe1_deb, &vAufgabe1, &vAufgabe2, &vAufgabe3, &vAufgabe4, + &vAufgabe5, &vAufgabe6, &vAufgabe6a, &vAufgabe7, &vAufgabe8, + &vAufgabe9, &vAufgabe9a + }; + + retry: + + cout + << "0: vAufgabe1_deb()" << endl + << "1: vAufgabe1()" << endl + << "2: vAufgabe2()" << endl + << "3: vAufgabe3()" << endl + << "4: vAufgabe4()" << endl + << "5: vAufgabe5()" << endl + << "6: vAufgabe6()" << endl + << "7: vAufgabe6a()" << endl + << "8: vAufgabe7()" << endl + << "9: vAufgabe8()" << endl + << "10: vAufgabe9()" << endl + << "11: vAufgabe9a()" << endl + << "Bitte wähen Sie eine Aufgabe: "; + cin >> iWahl; + cout << endl; + + if (iWahl > NUM_AUFGABEN || iWahl < 0) { + cerr << "Ungültige Eingabe! Bitte versuchen Sie es erneut" << endl; + goto retry; + } + + dGlobaleZeit = 0; /* resette globale Uhr */ + + try { + pAufgaben[iWahl](argc, argv); /* Funktionspointer aufrufen */ + } + catch (string &exception) { + cerr << exception << endl; + exit(-1); + } + + cout << endl << endl << "Nochmal? (0/1): "; + cin >> iWahl; + cout << endl; + + if (iWahl) { + goto retry; + } + + return 0; +}