Aufzugsanzeige
-
Enno schrieb:
Zeig doch mal dein Code.

das sieht eher schlecht aus, weil ich momentan noch in der Schule bin und der Code daheim ist. Aber ich kann dir so viel sagen: Ich habe jedem Button einen Timer aktivieren lassen, welcher dafür sorgt, dass eine switch/case anweisung eine Variable verändert, welche wiederum die mit einem weiteren timer dafür sorgt, dass die position mit einem panel ausgegeben wird.
-
SeppJ schrieb:
Es gibt passenderweise in der Standardbibliothek bereits fix und fertig den Container std::queue).
was meinst du mit standartbibliothek?
-
Barnibas schrieb:
was meinst du mit standartbibliothek?
Über verschiedene Arten zu Stehen habe ich nichts gesagt. Standardbibliothek. Die unterstützende Bibliothek, die bei der Sprache C++ standardmäßig immer dabei ist, damit man gleich loslegen kann und nicht erst jedes Kinkerlitzchen selber programmieren muss. Ein- und Ausgabe (iostream & Co.). Zeitmessung (ctime & chrono). Zeichenkettenverarbeitung (string). Komplexe Zahlen und Brüche (complex & ratio). Fertige Standardalgorithmen für allerlei Aufgaben (algorithm & numeric). Container zum Speichern für alle Arten von Daten (ganz, ganz viele verschiedene). Nebenläufige Programmierung (thread, mutex, & Co.). Und vieles andere mehr.
Eine riesige Welt.
Guckst du zum Beispiel hier:
http://www.cplusplus.com/reference/
Oder hier:
http://en.cppreference.com/w/Lass mich raten: Euer Lehrer hat davon bisher nicht ein einziges Wort erwähnt?
-
SeppJ schrieb:
Standardbibliothek.
Sorry normalerweise mach ich solche fehler nicht

SeppJ schrieb:
Lass mich raten: Euer Lehrer hat davon bisher nicht ein einziges Wort erwähnt?
Ne hat er nicht. Wir haben bisher nur Komponenten auf die Oberfläche gelegt und diese dann mit einfachen Befehlen versehen und so sachen wie if/else switch/case und zur Zeit noch Punkte und Linien auf Images.
-
Dann ist dir schwer zu helfen. Eine queue oder ähnliches selber programmieren ist viel zu schwer für deinen Kenntnisstand. Benutzen darfst du die fertige std::queue vermutlich auch nicht.
Überhaupt: Wahrscheinlich macht ihr gar kein C++. Ihr benutzt ja schon mindestens einmal irgendeine Art von GUI-Framework. Welches? Vielleicht findet sich dort Hilfe.
-
SeppJ schrieb:
Benutzen darfst du die fertige std::queue vermutlich auch nicht.
Doch doch, wir dürfen alles benutzen, so lange wir auch verstehen, wie es funktioniert.
SeppJ schrieb:
Wahrscheinlich macht ihr gar kein C++.
was kann man denn mit TurboC++ bzw. C++builder 6 noch programmieren?
-
Barnibas schrieb:
Kennt da zufällig jemand eine Möglichkeit, die dafür sorgt, dass erst die ereignisroutune des einen Knopfes und dann die des nächsten Knopfes ausgeführt wird?
Soll das wirklich so gemacht werden?
Wenn du in Stockwerk 1 bist und 3 und dann 2 drückst, soll er dann wirklich erst nach 3 und dann zurück nach 2?
Ein guter Aufzug würde wohl in 2 halten und dann erst nach 3.
Das könntest du dann auch ohne Standardbibliothek über ein Stockwerk-Array oder sowas machen.
-
Barnibas schrieb:
Der Grundquellcode steht schon, das heist der "Aufzug" fährt hoch und runter.
Hast du eine Variable, die die aktuelle Position des Aufzugs repräsentiert? Falls nicht, fährt da gar nichts. Dann hast du keine Aufzugsteuerung modelliert, sondern die Simulation einer Aufzugsteuerung.
-
Jockelx schrieb:
Das könntest du dann auch ohne Standardbibliothek über ein Stockwerk-Array oder sowas machen.
Ich hab mir gedacht so wie du es sagst wär es schwieriger, aber wenn du mir das erklären kannst, oder mir tipps geben kannst, mach ichs natürlich so

MFK schrieb:
Hast du eine Variable, die die aktuelle Position des Aufzugs repräsentiert?
Ja hab ich. Sobald ich daheim bin, poste ich hier den kompletten wa uellcode rein. Soll ich den einfach hier rein kopieren oder gibts hier ein tool oder sowas dafür?
-
Je nach Größe einfach Copy&Paste. Aber mehr als naja 200-300 Zeilen sind zuviel.
Dann musst du aufs Wesentliche reduzieren.
-
So hier kommt dann mal der bisherige Quellcode (ich hab immer von linie zu linie genommen, da ich glaube, das liest sich besser) :
Die Variable, die die höhe des Aufzugs anzeigt:
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;int h;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
h = 1; //Damit der Aufzug im EG startet
}
//---------------------------------------------------------------------------Der Timer, der die Position anzeigen lässt:
//---------------------------------------------------------------------------
void __fastcall TForm1::TimerAllgTimer(TObject *Sender)
{
pnlUG->Visible = false;
pnlEG->Visible = false;
pnl1->Visible = false;
pnl2->Visible = false;
pnl3->Visible = false;
pnl4->Visible = false;switch ((h)) {
case 0: pnlUG->Visible = true;
break;
case 1: pnlEG->Visible = true;
break;
case 2: pnl1->Visible = true;
break;
case 3: pnl2->Visible = true;
break;
case 4: pnl3->Visible = true;
break;
case 5: pnl4->Visible = true;
break;
default:
break;
}
}
//---------------------------------------------------------------------------Einer der Buttons (es ändert sich immer nur der Timername) :
//---------------------------------------------------------------------------void __fastcall TForm1::btn3Click(TObject *Sender)
{
timer3->Enabled = true;
}
//---------------------------------------------------------------------------Der dazugehörige Timer (hier ändern sich ebenfalls nur die Namen der Komponente und an welcher case-Position sie stehen):
//---------------------------------------------------------------------------void __fastcall TForm1::timer3Timer(TObject *Sender)
{
switch ((h)) {
case 0: h = h + 1;
break;
case 1: h = h + 1;
break;
case 2: h = h + 1;
break;
case 3: h = h + 1;
break;
case 4: timer3->Enabled = false;
break;
case 5: h = h - 1;
break;
default:
break;
}
}
//---------------------------------------------------------------------------Ich hoffe, ihr könnt alles daraus lesen, wenn nicht, sagt bescheind!!
-
Ehrlich gesagt: Das ist Mist. Gaaaaaaanz großer Mist. Da fehlt Abstraktion. Gaaaaaanz viel Abstraktion. Dann könnte man auch einfach neue Features einbauen. Aber wenn du jede einzelne Aktion von jedem einzelnen Button einzeln programmiert hast und sogar jede einzelne Änderung von h für jeden Einzelfall einzeln programmiert ist, dann muss auch jedes neue Feature an jeder dieser Stellen einfließen.
Daher ein allererster Plan zur Verbesserung:
- Schreib Funktionen! Allgemeine Funktionen! Anstatt 5 verschiedene Funktionen um den Aufzug in 5 verschiedene Stockwerke fahren zu lassen, hast du nur noch eine Funktion, die den Aufzug in das N'te Stockwerk fahren lässt. Anstatt in dieser Funktion jeden Einzelfall zu switch'en betrachtest du nur noch die Fälle "muss hochfahren", "muss runterfahren", "ist da".
- Entsprechend vereinfachen sich die Reaktionen auf die Ereignisse: Anstatt 5 verschiedene Reaktionen einzeln zu Programmieren gibt es eine zentrale Reaktion auf das Drücken eines Fahrstuhlknopfes, die dann den Fahrstuhl in das entsprechende Stockwerk schickt.
- Wenn du dann irgendwann so weit bist (das obige ist eine Menge Arbeit und du wirst sicherlich eine Menge über Programmierung dabei lernen), dann kannst du in dieser Ereignisverwaltung ansetzen und dort die verschiedenen Knopfdrücke in einer Queue sammeln. Oder dir später sogar mal Gedanken machen, wie der Aufzug cleverer gesteuert werden kann (siehe Jockelx' Hinweis auf der ersten Seite).
-
An funktionen habe ich bisher noch gar nicht gedacht. Danke für den tipp! Ich setzt mich gleich mal ran und versuch es so zu machen, wie du es gesagt hast. Aber was meinst du mit abstraktion?
-
Barnibas schrieb:
Aber was meinst du mit abstraktion?
Anstatt für jedes Problem eine einzelne Lösung zu entwickeln, denkst du über die Gemeinsamkeiten der Probleme nach und entwickelst eine Allumfassende Lösung für alle Problemstellungen gleichzeitig.
Hier hattest du beispielsweise die Probleme
-"Fahre in das erste Stockwerk"
-"Fahre in das zweite Stockwerk"
-"Fahre in das dritte Stockwerk"
-"Fahre in das vierte Stockwerk"
-"Fahre in das fünfte Stockwerk"In dem Code, den du uns gezeigt hast, hast du für alle diese Probleme eine einzelne Lösung erzeugt: timer1Timer, timer2Timer, timer3Timer, timer4Timer und timer5Timer. Genauer noch hast du sogar jeweils innerhalb dieser Teilproblemlösungen noch kleinere Teilprobleme gehabt, zum Beispiel innerhalb von timer3Timer:
-"Fahre vom 1. Stockwerk in das 3.Stockwerk"
-"Fahre vom 2. Stockwerk in das 3.Stockwerk"
-"Fahre vom 3. Stockwerk in das 3.Stockwerk"
-"Fahre vom 4. Stockwerk in das 3.Stockwerk"
-"Fahre vom 5. Stockwerk in das 3.Stockwerk"
Die hast du auch alle einzeln gelöst (deine switch-Konstruktion).Meinst du nicht, dass man das auch hätte allgemeiner lösen können? Zum Beispiel indem man das Problem
"Fahre in das N. Stockwerk"
löst? Dann bräucht man nämlich nur noch diese eine Lösung, weil diese alle 5 Teilprobleme oben umfasst. Besser noch: Wenn jemals ein 6. Stockwerk oder ein Keller hinzukommt, dann funktioniert die allgemeine Lösung für das N. Stockwerk immer noch unverändert! Wenn du jedoch die 5 Speziallösungen benutzt, dann müsstest du in diesem Fall eine weitere Speziallösung für den 6.Stock oder den Keller hinzufügen.
-
Den grundgedanken von deinem vorschlag verstehe ich, allerding hab ich so gar keine ahnung wie ich das umsetzen soll, zu mindest mit meinem wissensstand. Am anfang wollte ich z.b. eine funktion machen, die einfach so lange -1 oder +1 macht, bis der gewünschte wert erreicht ist. Allerdings hab ich dann das problem: wie mach ich es, dass der computer nicht in seiner rechengeschwindig rechnet, sondern nach jedem abziehen oder hinzufügen 1sec wartet und wie sag ich dem computer, dass er hinzufügen oder abziehen soll?
Und stockwerke hab ich im moment von UG - 4.OG
-
Ich hab das ganze jetzt mal Probiert und nach einigen Problemen auch hingekriegt.
das ganze sieht dann jetzt so aus:
//--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "Test_u.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; int z, p; //Position und Ziel des Aufzugs //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { z = 1; //Damit der Aufzug im EG anfängt p = 1; //Damit der Aufzug im EG anfängt } //--------------------------------------------------------------------------- int plus_eins(int p) { p = p + 1; return p; } //--------------------------------------------------------------------------- int minus_eins(int p) { p = p - 1; return p; } //--------------------------------------------------------------------------- void __fastcall TForm1::timerFahrtTimer(TObject *Sender) { if (z == p) { timerFahrt->Enabled = false; } else if (z > p) { p = plus_eins(p); } else p = minus_eins(p); } //--------------------------------------------------------------------------- void __fastcall TForm1::timerAnzeigeTimer(TObject *Sender) { pnlUG->Visible = false; pnlEG->Visible = false; pnl1->Visible = false; pnl2->Visible = false; pnl3->Visible = false; pnl4->Visible = false; switch ((p)) { case 0: pnlUG->Visible = true; break; case 1: pnlEG->Visible = true; break; case 2: pnl1->Visible = true; break; case 3: pnl2->Visible = true; break; case 4: pnl3->Visible = true; break; case 5: pnl4->Visible = true; break; default: break; } } //--------------------------------------------------------------------------- void __fastcall TForm1::btnUGClick(TObject *Sender) { z = 0; timerFahrt->Enabled = true; } //--------------------------------------------------------------------------- void __fastcall TForm1::btnEGClick(TObject *Sender) { z = 1; timerFahrt->Enabled = true; } //--------------------------------------------------------------------------- void __fastcall TForm1::btn1Click(TObject *Sender) { z = 2; timerFahrt->Enabled = true; } //--------------------------------------------------------------------------- void __fastcall TForm1::btn2Click(TObject *Sender) { z = 3; timerFahrt->Enabled = true; } //--------------------------------------------------------------------------- void __fastcall TForm1::btn3Click(TObject *Sender) { z = 4; timerFahrt->Enabled = true; } //--------------------------------------------------------------------------- void __fastcall TForm1::btn4Click(TObject *Sender) { z = 5; timerFahrt->Enabled = true; } //---------------------------------------------------------------------------Das ist jetzt der komplette code von oben bis unten. kann man damit jetzt mehr anfangen? Oder fehlt da noch was?
Edit:
Theoretisch könnte ich die Funktionen auch weglassen und bei//--------------------------------------------------------------------------- void __fastcall TForm1::timerFahrtTimer(TObject *Sender) { if (z == p) { timerFahrt->Enabled = false; } else if (z > p) { p = plus_eins(p); } else p = minus_eins(p); } //---------------------------------------------------------------------------p = p + 1;bzw.
p = p - 1;schreiben oder?
-
Zum Erhöhen und Erniedrigen um 1:
Ja, das ist ungeheuer umständlich bei dir.x = x + 1; x += 1; ++x;machen alle das gleiche. Nimm das letzte.
Zum Code:
Ja, damit kann man doch was anfangen. Jetzt machen wir mal in Babyschritten weiter:
-Das Abschicken des Fahrstuhls ist nicht sehr schön (Zeile 75 bis Ende). Da hast du wieder 6x den gleichen Code. Abstraktion! Schreibe eine Funktion, die ein Stockwerk als Argument entgegen nimmt und den Aufzug losschickt. Deine Ereignisbehandlungsfunktionen rufen dann diese Funktion mit dem passenden Stockwerk auf. (Letzteres darfst du meinetwegen 6x schreiben, wenn du noch nicht weißt, wie das besser geht)
-Prüfe, ob dein Programm noch funktioniert.
-Du kannst derzeit ja prüfen, ob der Aufzug fährt oder nicht (wenn dein timer enabled ist oder nicht). Prüfe in deiner Fahrstuhlabschickfunktion, die du oben geschrieben hast, ob der Aufzug derzeit fährt oder nicht. Falls er fährt, ignoriere das Kommando.
-Prüfe, ob dein Programm noch funktioniert. Nun sollte es nicht mehr möglich sein, während der Fahrstuhl fährt ein neues Kommando zu geben.
-Jetzt wird es kompliziert, weil jetzt etwas neues kommt. Ich nehme mal an, dass du dir die Grundlagen der queue (push, pop, front, size) mal angesehen hast. Ersetze dein Zielstockwerk z durch eine std::queue<int> (die queue ist zu Anfang leer, entferne also Zeile 17). Denk dran, dass du den Header <queue> einbinden musst.
-Nun müssen an der Programmlogik Änderungen vorgenommen werden:
* Wenn ein Knopf gedrückt wird, wird das Zielstockwerk an die queue angefügt (push). Dein Fahrstuhl wird ggf. aktiviert, falls er es noch nicht ist.
* Wenn der Fahrstuhl aktiviert ist, dann fährt er zum vordersten Element (front) der queue.
* Wenn der Fahrstuhl angekommen ist, dann löscht er das vorderste Element (pop). Falls noch Elemente in der queue sind (size), dann fährt er weiter, ansonsten deaktiviert er sich
-Vermutlich wirst du für den Schritt eine ganze Weile brauchen. Und zwischendurch viel falsch machen. Frag zur Not nach (aber erst, nachdem du nicht mehr weiter kommst. Selber versuchen Probleme zu lösen, lehrt Probleme selber lösen zu können
. Guck dir meine Tipps an, lies die verlinkten Referenzen zur queue, schau dir die Beispiele an.)
-Prüfe dein Programm, es sollte nun so funktionieren, wie du es in deinem allerersten Beitrag gefragt hast.
-
Ich werde jetzt deine Liste Schritt für Schritt abarbeitn. Danke schonmal dafür!
allerdings hab ich schon wieder keine ahnung wie ich den Teil umsetzen soll:
SeppJ schrieb:
Schreibe eine Funktion, die ein Stockwerk als Argument entgegen nimmt und den Aufzug losschickt. Deine Ereignisbehandlungsfunktionen rufen dann diese Funktion mit dem passenden Stockwerk auf.
Ich verseth das Ganze so:
Ich soll eine Funktion schrieben, die den Wert "z" entgegen nimmt und den "timerFahrt" startet. Aller dings sehe ich darin keinen großen sinn, weil ich dann in der Ereignisroutine jedes Buttons die Funktion aufrufen müsste, welche dann nichts weiter macht als den Timer zu starten. Oder hab ich dass schon wieder falsch verstanden?Und wie der Teil gemeint ist, weis ich auch nicht:
SeppJ schrieb:
Du kannst derzeit ja prüfen, ob der Aufzug fährt oder nicht (wenn dein timer enabled ist oder nicht). Prüfe in deiner Fahrstuhlabschickfunktion, die du oben geschrieben hast, ob der Aufzug derzeit fährt oder nicht. Falls er fährt, ignoriere das Kommando.
Wie Prüfe ich, ob der Aufzug fährt? Während der Laufzeit oder wie ist das gemeint?
-
Barnibas schrieb:
Ich soll eine Funktion schrieben, die den Wert "z" entgegen nimmt und den "timerFahrt" startet. Aller dings sehe ich darin keinen großen sinn, weil ich dann in der Ereignisroutine jedes Buttons die Funktion aufrufen müsste, welche dann nichts weiter macht als den Timer zu starten. Oder hab ich dass schon wieder falsch verstanden?
Doch das hast du richtig verstanden. Das gibt dir hinterher einen zentralen Angriffspunkt, da du die intelligente Aufzugsteuerung nur noch an einem Punkt einbringen brauchst, anstatt an sechs verschiedenen Punkten. Ja, deine Buttoneventhandler rufen dann alle diese Funktion auf die gleiche Weise auf. Es wäre daher natürlich wesentlich eleganter, wenn die Events gleich die richtige Funktion aufrufen würden. Aber da ich dein Framework nicht kenne, kann ich dir nicht sagen ob und wie das geht. Wenn du weißt, wie es geht, dann tu es, ansonsten musst du eben für jeden Button einen leicht veränderten Funktionsaufruf schreiben.
Und wie der Teil gemeint ist, weis ich auch nicht:
SeppJ schrieb:
Du kannst derzeit ja prüfen, ob der Aufzug fährt oder nicht (wenn dein timer enabled ist oder nicht). Prüfe in deiner Fahrstuhlabschickfunktion, die du oben geschrieben hast, ob der Aufzug derzeit fährt oder nicht. Falls er fährt, ignoriere das Kommando.
Wie Prüfe ich, ob der Aufzug fährt? Während der Laufzeit oder wie ist das gemeint?
Wenn der Aufzug fahren soll, dann aktivierst du doch deinen Timer:
timerFahrt->Enabled = true;Und wenn der Aufzug angekommen ist, schaltest du ihn aus:
if (z == p) { timerFahrt->Enabled = false; }Daraus folgt: Wenn der Timer aktiviert ist, fährt der Aufzug gerade. Du kannst natürlich auch noch eine zusätzliche bool-Variable "bereit" oder "faehrt" einführen, falls dir das lieber ist.
-
Jetzt kapier ich gar nichts mehr.
1. Die Funktion ist also nur da, um das ganze etwas eleganter wirken zu lassen....so hab ich das verstanden.
2. Brauch ich doch im Moment gar nichts prüfen, weil es doch eigentlich funktioniert (dass der Aufzug fährt oder nicht).
3. Was ist ein Framework, bzw. wo finde ich das bei mir?