Aufgabenblock_3 fast fertig

This commit is contained in:
Steffen Vogel 2011-11-08 21:05:08 +01:00
parent a24126cf99
commit f83007679e
37 changed files with 2068 additions and 717 deletions

View file

@ -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;
}

View file

@ -1,37 +0,0 @@
/**
* ClientSocket header
*
* @version 0.2
* @copyright (c) Robert Uhl 2009
*/
#ifndef CLIENTSOCKET_H
#define CLIENTSOCKET_H
#include <string>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <iostream>
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

View file

@ -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 <steffen.vogel@rwth-aachen.de>
*
* Vielen Dank an den Lehrstuhl EECS, RWTH Aachen, für den Zugang zum Quellcode des SimuClient für Windows.
*/
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <map>
#include <cstdlib>
#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<string, int> 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);
}

View file

@ -1,40 +1,41 @@
#pragma once
#pragma warning (disable:4786)
#include <string>
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);
/*
* 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 <string>
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

BIN
Aufgabenblock_2/libsimu.so Normal file

Binary file not shown.

View file

@ -0,0 +1,95 @@
#include <iostream>
#include <string>
#include <iomanip>
#include "AktivesVO.h"
extern double dGlobaleZeit;
int AktivesVO::p_iMaxID = 0;
map<string, AktivesVO*> 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<string, AktivesVO*>::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<string, AktivesVO*>::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);
}

View file

@ -0,0 +1,46 @@
#ifndef AKTIVESVO_H_
#define AKTIVESVO_H_
#include <string>
#include <map>
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<string, AktivesVO*> p_pObjekte;
int p_iID;
string p_sName;
};
ostream& operator<<(ostream &out, const AktivesVO &vo);
istream& operator>>(istream &in, AktivesVO &vo);
#endif /* AKTIVESVO_H_ */

View file

@ -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;
}

View file

@ -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_ */

View file

@ -0,0 +1,27 @@
#include <math.h>
#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;
}

17
Aufgabenblock_3/Fahrrad.h Normal file
View file

@ -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_ */

View file

@ -0,0 +1,125 @@
#include <iostream>
#include <iomanip>
#include <cmath>
#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());
}

View file

@ -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_ */

View file

@ -0,0 +1,34 @@
#include <stdlib.h>
#include <iostream>
#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;
}
}

View file

@ -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_ */

View file

@ -0,0 +1,23 @@
#include <stdlib.h>
#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);
}
}

View file

@ -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_ */

View file

@ -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;
}

View file

@ -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_ */

View file

@ -0,0 +1,123 @@
#include <iostream>
#include <iomanip>
#include <stdlib.h>
#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<Weg *>::iterator it;
for (it = p_lWege.begin(); it != p_lWege.end(); it++) {
(*it)->vAbfertigung();
}
p_dZeit = dGlobaleZeit;
}
void Kreuzung::vZeichnen() const {
list<Weg *>::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<Weg *>::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<Weg *>::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()
{ }

View file

@ -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<Weg *> p_lWege;
double p_dTankstelle;
};
#endif /* KREUZUNG_H_ */

View file

@ -0,0 +1,82 @@
#ifndef LAZYAKTION_H_
#define LAZYAKTION_H_
#include <list>
using namespace std;
// Oberklasse LazyAktion
template<class T> class LazyAktion {
public:
LazyAktion(list<T> *ptLazyListe) : p_ptLazyListe(ptLazyListe) { }
virtual ~LazyAktion() { }
virtual void vAusfuehren() = 0;
protected:
list<T> *p_ptLazyListe; // Zeiger auf p_ListeObjekte auf die die Aktionen angewendet werden sollen
};
// LazyPushFront
template<class T> class LazyPushFront : public LazyAktion<T> {
public:
LazyPushFront(const T &einObjekt, list<T> *eineListe) :
LazyAktion<T> (eineListe),
p_tObjekt(einObjekt)
{ }
virtual ~LazyPushFront() { }
void vAusfuehren() {
p_ptLazyListe->push_front(p_tObjekt);
}
private:
using LazyAktion<T>::p_ptLazyListe; /* für gcc notwendig */
T p_tObjekt;
};
// LazyPushBack
template<class T> class LazyPushBack : public LazyAktion<T> {
public:
LazyPushBack(const T &einObjekt, list<T> *eineListe) :
LazyAktion<T> (eineListe),
p_tObjekt(einObjekt)
{ }
virtual ~LazyPushBack() { }
void vAusfuehren() {
p_ptLazyListe->push_back(p_tObjekt);
}
private:
using LazyAktion<T>::p_ptLazyListe; /* für gcc notwendig */
T p_tObjekt;
};
template <class T> class LazyErase : public LazyAktion<T> {
// typedef für iterator
typedef typename list<T>::iterator iterator;
typedef typename list<T>::const_iterator const_iterator;
public:
LazyErase(const iterator &itObjekt, list<T> *eineListe) :
LazyAktion<T> (eineListe),
p_itObjekt(itObjekt)
{ }
virtual ~LazyErase() { }
void vAusfuehren() {
p_ptLazyListe->erase(p_itObjekt);
}
private:
using LazyAktion<T>::p_ptLazyListe; /* für gcc notwendig */
iterator p_itObjekt; // bei erase Iterator speichern
};
#endif /* LAZYAKTION_H_ */

View file

@ -0,0 +1,94 @@
#ifndef LAZYLISTE_H_
#define LAZYLISTE_H_
#include <list>
#include "LazyAktion.h"
using namespace std;
template<class T> class LazyListe {
public:
// typedef für Iterator
typedef typename list<T>::iterator iterator;
typedef typename list<T>::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<T>(einObjekt, &p_ListeObjekte));
bChanged = true;
}
void push_front(const T einObjekt) {
p_ListeAktionen.push_back(new LazyPushFront<T>(einObjekt, &p_ListeObjekte));
bChanged = true;
}
void erase(iterator itObjekt) {
p_ListeAktionen.push_back(new LazyErase<T>(itObjekt, &p_ListeObjekte));
bChanged = true;
}
// Änderungen auf Objektliste übertragen
void vAktualisieren() {
if (bChanged) {
// ausstehende Aktionen durchfuehren
typename list<LazyAktion<T> *>::const_iterator it; // TODO warum typename?!
for (it = p_ListeAktionen.begin(); it != p_ListeAktionen.end(); it++) {
// Aktion ausführen
LazyAktion<T> *pAktion = *it;
pAktion->vAusfuehren();
// Zeiger auf Action-Element löschen
delete *it;
}
// Liste der Aktionen leeren
p_ListeAktionen.clear();
bChanged = false;
}
}
private:
list<T> p_ListeObjekte;
list<LazyAktion<T> *> p_ListeAktionen;
bool bChanged;
};
#endif /* LAZYLISTE_H_ */

View file

@ -0,0 +1,18 @@
#include <iostream>
#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);
}

View file

@ -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_ */

97
Aufgabenblock_3/PKW.cpp Normal file
View file

@ -0,0 +1,97 @@
#include <iostream>
#include <iomanip>
#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;
}

39
Aufgabenblock_3/PKW.h Normal file
View file

@ -0,0 +1,39 @@
/*
* PKW.h
*
* Created on: 18.08.2011
* Author: stv0g
*/
#ifndef PKW_H_
#define PKW_H_
#include <string>
#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_ */

View file

@ -0,0 +1,46 @@
/*
* SimuClient f<EFBFBD>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<EFBFBD>r den Zugang zum Quellcode
* des SimuClient f<EFBFBD>r Windows.
* Datei: SimuClient.h
* Inhalt: SimuClient sendet Daten an den (erweiterten) Java-Grafik-Server
*/
#ifndef SIMUCLIENT_H
#define SIMUCLIENT_H
#include <string>
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 <20>bernimmt
void vBeendeGrafik(void);
// Zus<75>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

Binary file not shown.

View file

@ -0,0 +1,27 @@
#include <iostream>
#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;
}

View file

@ -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_ */

147
Aufgabenblock_3/Weg.cpp Normal file
View file

@ -0,0 +1,147 @@
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <float.h>
#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<Fahrzeug *>::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<65>gt */
p_lFahrzeuge.push_front(pFz);
}
else { /* fahrende hinten */
p_lFahrzeuge.push_back(pFz);
}
}
void Weg::vAbgabe(Fahrzeug *pFz) {
LazyListe<Fahrzeug *>::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<Fahrzeug *>::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<Fahrzeug *>::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;
}

57
Aufgabenblock_3/Weg.h Normal file
View file

@ -0,0 +1,57 @@
#ifndef WEG_H_
#define WEG_H_
#include <list>
#include <string>
#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<Fahrzeug *> p_lFahrzeuge;
Kreuzung *p_pZielKreuzung;
Weg *p_pRueckweg;
};
#endif /* WEG_H_ */

185
Aufgabenblock_3/Welt.cpp Normal file
View file

@ -0,0 +1,185 @@
#include <iostream>
#include <string>
#include "Welt.h"
#include "PKW.h"
#include "Weg.h"
#include "Fahrrad.h"
Welt::Welt()
{ }
Welt::~Welt()
{ }
void Welt::vAbfertigung() {
list<Kreuzung *>::iterator it;
for (it = p_pKreuzungen.begin(); it != p_pKreuzungen.end(); it++) {
(*it)->vAbfertigung();
}
}
void Welt::vZeichnen() {
list<Kreuzung *>::iterator it;
for (it = p_pKreuzungen.begin(); it != p_pKreuzungen.end(); it++) {
(*it)->vZeichnen();
}
}
ostream& Welt::ostreamAusgabe(ostream &stream) const {
list<Kreuzung *>::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<Kreuzung *>(AktivesVO::pObjekt(sQuellKreuzung));
Kreuzung *pZielKreuzung = static_cast<Kreuzung *>(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<Weg::Begrenzung >(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<Kreuzung *>(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<Kreuzung *>(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<Kreuzung *>(AktivesVO::pObjekt(sQuellKreuzung));
Kreuzung *pZielKreuzung = static_cast<Kreuzung *>(AktivesVO::pObjekt(sZielKreuzung));
/* Kreuzungen verbinden & Wege erstellen */
pQuellKreuzung->vVerbinde(pZielKreuzung, sHinweg, sRueckweg, dLaenge, static_cast<Weg::Begrenzung >(eLimit), bUeberholverbot);
/* Wege Zeichnen */
Weg *pHinweg = static_cast<Weg *>(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<Kreuzung *>(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<Kreuzung *>(AktivesVO::pObjekt(sStartKreuzung));
pStartKreuzung->vAnnahme(pRad, dStartZeit);
}
else if (sTyp != "") {
throw string("Unbekannter Typ!");
}
}
}

26
Aufgabenblock_3/Welt.h Normal file
View file

@ -0,0 +1,26 @@
#ifndef WELT_H_
#define WELT_H_
#include <list>
#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<Kreuzung *> p_pKreuzungen;
};
ostream& operator<<(ostream &out, const Welt &w);
#endif /* WELT_H_ */

BIN
Aufgabenblock_3/libsimu.so Executable file

Binary file not shown.

509
Aufgabenblock_3/main.cpp Normal file
View file

@ -0,0 +1,509 @@
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <stdlib.h>
#ifdef _WIN32 /* _Win32 is usually defined by compilers targeting 32 or 64 bit Windows systems */
#include <windows.h>
#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<Fahrzeug *> 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<Fahrzeug *>::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<int> &tListe) {
LazyListe<int>::iterator it;
for (it = tListe.begin(); it != tListe.end(); it++) {
cout << *it << ", ";
}
cout << endl;
}
void vAufgabe6a(int argc, char *argv[]) {
LazyListe<int> tListe;
LazyListe<int>::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;
}