Aufzugsanzeige



  • 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?


  • Mod

    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?


  • Mod

    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?


  • Mod

    Barnibas schrieb:

    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.

    Nicht nur etwas eleganter. Jetzt hast du als Steuerungslogik bloß zwei Zeilen:

    void __fastcall TForm1::btn2Click(TObject *Sender)
    {
    z = 3;
    timerFahrt->Enabled = true;
    }
    

    Und diese Zeilen hast du 6x. Jetzt willst du deine Steuerlogik aber erweitern. Dazu müsstest du 6x Änderungen vornehmen. Nicht sehr gut. Daher lagerst du die Steuerlogik besser aus und erweiterst sie dann bloß noch an einer Stelle.

    2. Brauch ich doch im Moment gar nichts prüfen, weil es doch eigentlich funktioniert (dass der Aufzug fährt oder nicht).

    Das ist ein Zwischenschritt. Du willst schließlich dass der Aufzug in Zukunft anders reagiert, je nachdem, ob er schon fährt (dann soll er erst ankommen und dann zum neuen Ziel weiterfahren) oder ob er wartet (dann soll er gleich losfahren). Ein erster Schritt ist daher überhaupt erst die Unterscheidung auf "fährt" und "wartet" einzubauen.

    3. Was ist ein Framework, bzw. wo finde ich das bei mir?

    Na, dein C++-Builder Krams. Also deine ganzen Buttons und Forms. Dafür gibt es hier auch ein Forum, wenn du Fragen hast, wie man das benutzt:
    http://www.c-plusplus.net/forum/f2
    Die wenigsten hier im Forum für reines C++ (so auch ich), werden sich damit auskennen. An sich hatte deine Frage aber auch nicht mit der Benutzung des C++-Builders zu tun, daher war es schon richtig, hier zu fragen.



  • Ahhhh jetzt hab ich es verstanden...glaub ich zu mindestens. Du bist nicht zufällig ein Lehrer oder? 😃

    SeppJ schrieb:

    Ein erster Schritt ist daher überhaupt erst die Unterscheidung auf "fährt" und "wartet" einzubauen.

    Wenn ich das richtig verstanden habe, meinst du so etwas:

    //-----------------------------------
    void funktion_sowieso(bool zustand, int z, int p)
          if (z == p)
                zustand = false;         //Aufzug steht
          else
                zustand = true;          //Aufzug fährt
    

    wobei "zustand" eine neue Variable ist und anzeigt, ob der Aufzug fährt oder steht.


  • Mod

    Ich dachte eher so:

    void __fastcall TForm1::timerFahrtTimer(TObject *Sender)
    {
    if (z == p) {
        timerFahrt->Enabled = false;
        faehrt = false;
    }
    else
        if (z > p) {
            p = plus_eins(p);
        }
        else
            p = minus_eins(p);
    }
    
    // ...
    
    void __fastcall TForm1::lassAufzugFahren(int wohin)
    {
      z = wohin;
      faehrt = true;
      timerFahrt->Enabled = true;
    }
    
    // ...
    
    void __fastcall TForm1::btnUGClick(TObject *Sender)
    {
      lassAufzugFahren(0);
    }
    
    // und noch 5x das gleiche mit anderen Stockwerken
    

    Das sollte (ungetestet) noch das gleiche tun wie dein derzeitiger Code (du musst natürlich noch den bool faehrt und die Memberfunktion lassAufzugFahren zu TForm1 hinzufügen). Dann wäre der nächste Schritt mit der Prüfung:

    void __fastcall TForm1::lassAufzugFahren(int wohin)
    {
      if (! faehrt)
      {
        z = wohin;
        faehrt = true;
        timerFahrt->Enabled = true;
      }
    }
    

    Damit sollte dann der Effekt eintreten, dass der Aufzug blockiert, während er fährt und man nur Kommandos geben kann, wenn er steht. Der nächste Schritt wäre dann der komplizierte Schritt, bei dem die blockierten Kommandos stattdessen zwischengespeichert werden und dann nach der Ankunft ausgeführt werden.



  • SeppJ schrieb:

    Ich dachte eher so:

    das leuchtet mir ein.

    allerdings fehlt da:

    SeppJ schrieb:

    void __fastcall TForm1::lassAufzugFahren(int wohin)
    {
      if (! faehrt)
      {
        z = wohin;
        faehrt = true;
        timerFahrt->Enabled = true;
      }
    }
    

    nicht noch ein else?


  • Mod

    Barnibas schrieb:

    fehlt da [...] nicht noch ein else?

    Kommt drauf an. Wenn die Kommandos während der Fahrt einfach nur ignoriert werden sollen, dann Nein. Wenn du sie hingegen im nächsten Schritt in einer queue zwischenspeichern möchtest, dann Jain. Man kann das dann durch einen else-Fall erledigen oder auch so wie hier beschrieben:

    SeppJ schrieb:

    * 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

    Aber mach das erst später. Guck mal erst einmal, ob du den blockierenden Aufzug zum Laufen bekommst und ob er funktioniert. Das heißt, der Fahrstuhl soll nur Kommandos annehmen, während er wartet.


Anmelden zum Antworten