Entwickler-Ecke
Sonstiges (Delphi) - Getränkeautomat
Lazarusboy - Mo 30.05.11 19:07
Titel: Getränkeautomat
Hallo Leute,
Ich sollte einen getränke Automaten konstruieren, so dass er es einen 50 Cent, 1Euro, Cola, Fanta, Limo und Korrektur Button gibt
Die Getränke kosten alle 1,50€
Wenn der Benutzer zu viel einwirft wird es unten wiedeer hinausgeschmissen ....
Mein Problem, sobald ich auf den 0,50 Euro Button klicke, sagt er mir ich habe 1,50 Euro in der Machine und 0,50 wieder unten raus: SO siehts aus:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172:
| procedure TForm1.Automat (var Zustand:char; Eingabe:char); begin EAusgabe.text:=' '; case Zustand of '-': case Eingabe of 'F': begin Ebereit.text:= '0,50 Euro'; Zustand:='F'; end; 'E': begin EBereit.text:= '1,00 Euro'; Zustand:= 'E'; end; 'C': begin EAusgabe.text:= ' zu wenig Geld'; Zustand:='-'; end; 'W': begin EAusgabe.text:= ' zu wenig Geld'; Zustand:='-'; end; 'L': begin EAusgabe.text:= ' zu wenig Geld'; Zustand:='-'; end; 'K': begin EAusgabe.text:=' kein Geld'; Zustand:='-'; end; end; end; Case Zustand of 'F': case Eingabe of 'F':begin Ebereit.text:='1,00 Euro'; Zustand:='E'; end; 'E': begin EBereit.text:='1,50 Euro'; Zustand:='G'; end; 'C': begin Ebereit.text:='0,50 Euro'; EAusgabe.text:= ' zu wenig Geld'; Zustand:='F'; end; 'W': begin Ebereit.text:='0,50 Euro'; EAusgabe.text:= ' zu wenig Geld'; Zustand:='F'; end; 'L': begin Ebereit.text:='0,50 Euro'; EAusgabe.text:= ' zu wenig Geld'; Zustand:='F'; end; 'K':begin Ebereit.text:='Bereit'; EAusgabe.text:='0,50 Euro Back'; Zustand:='-'; end; end; end; Case Zustand of 'E': case Eingabe of 'F': begin EBereit.text:='1,50 Euro'; Zustand:='G'; end; 'E': begin EBereit.text:= '1,00 Euro'; Zustand:='E'; EAusgabe.text:='1,00 Euro back'; end; 'C': begin Ebereit.text:='1,00 Euro'; EAusgabe.text:= ' zu wenig Geld'; Zustand:='E'; end; 'W': begin Ebereit.text:='1,00 Euro'; EAusgabe.text:= ' zu wenig Geld'; Zustand:='E'; end; 'L': begin Ebereit.text:='1,00 Euro'; EAusgabe.text:= ' zu wenig Geld'; Zustand:='E'; end; 'K':begin Ebereit.text:='Bereit'; EAusgabe.text:='1,00 Euro back'; Zustand:='-'; end; end; end; Case Zustand of 'G': case Eingabe of 'F': begin EBereit.text:='1,50 Euro'; EAusgabe.text:='0,50 Euro back'; Zustand:='G'; end; 'E': begin EBereit.text:='1,50 Euro'; EAusgabe.text:='1,00 Euro back'; Zustand:='G'; end; 'C': begin Ebereit.text:='Bereit'; EAusgabe.text:= 'Cola'; Zustand:='-'; end; 'W': begin Ebereit.text:='Bereit'; EAusgabe.text:= 'Fanta'; Zustand:='-'; end; 'L': begin Ebereit.text:='Bereit'; EAusgabe.text:= 'Limo'; Zustand:='-'; end; 'K':begin Ebereit.text:='Bereit'; EAusgabe.text:='1,50 Euro back'; Zustand:='-'; end; end; end;
end;
procedure TForm1.FormCreate(Sender: TObject); begin Zustand:='-'; end;
procedure TForm1.BKorrekturClick(Sender: TObject); begin Automat(Zustand,'K'); end;
procedure TForm1.B50centClick(Sender: TObject); begin Automat(Zustand,'F'); end;
procedure TForm1.B1EuroClick(Sender: TObject); begin Automat(Zustand,'E'); end;
procedure TForm1.BColaClick(Sender: TObject); begin Automat(Zustand,'C'); end;
procedure TForm1.BLimoClick(Sender: TObject); begin Automat(Zustand,'L'); end;
procedure TForm1.BFantaClick(Sender: TObject); begin Automat(Zustand,'W'); end; |
HenryHux - Mo 30.05.11 19:16
Kein Wunder, dass dabei Fehler passieren, ist ja nicht besonders einfach da durchzublicken.
Überleg dir am besten mal wie du das mit weniger Code erledigen kannst.
Du könntest eine Variable für den aktuellen Geldstand haben, die sich erhöht wenn man auf ein Geldknopf drückt.
Wenn man dann auf ein Getränk klickt, übergibst du den Preis des Getränkes an eine Prozedur, die dann prüft ob das Geld passt und dann entsprechend handelt.
lg
Lazarusboy - Mo 30.05.11 19:32
Ich würde trotzdem gerne wissen was ich da falsch gemacht habe,
ich habe festgestellt, dass sobald ich einmal 50 cent button drücke,das Projekt feststell, dass nun Zustand 'f' herrscht, und noch einmal 50 Cent dazumacht und nun feststellt dass Zustand 'e' herrscht und nun wieder 50 cent dazu macht usw....#
was kann ich dagegen machen, damit nicht alle case verknüpft sind.
Yogu - Mo 30.05.11 20:21
Wenn ich deinen Code soweit überblicke, sieht das in etwa so aus:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| case Zustand of 'a': begin case Eingabe of 'a': blah; 'b': blah; end; end; end;
case Zustand of 'b': begin case Eingabe of 'a': blah; 'b': blah; end; end; end; |
Du hast also für jeden Zustand ein eigenes
case-Konstrukt. Du solltest auf jeden Fall mal deinen Code richtig einrücken, so ähnlich wie ich es oben getan habe, und dann die Zweige der äußersten
case-Abfrage in einer einzigen vereinigen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| case Zustand of 'a': begin case Eingabe of 'a': blah; 'b': blah; end; end;
'b': begin case Eingabe of 'a': blah; 'b': blah; end; end; end; |
Dann wird auch abgebrochen, sobald er Zweig für
'a' durchgeführt wurde.
Ist es eigentlich eine Informatikleherer-Krankheit, erstens Zustände als
char zu speichern und zweitens eine riesige Zustand-wechsle-dich-Funktion zu basteln, die Geld wechseln, Kaffe kochen, Wohnungen saugen und Kartoffeln anbauen kann, je nach dem, welchen Parameter (wohlgemerkt vom Typ
char) man ihr übergibt? Kenn ich von meinem Lehrer.
Jann1k - Mo 30.05.11 22:07
| Zitat: |
| Ist es eigentlich eine Informatikleherer-Krankheit, erstens Zustände als char zu speichern und zweitens eine riesige Zustand-wechsle-dich-Funktion zu basteln, die Geld wechseln, Kaffe kochen, Wohnungen saugen und Kartoffeln anbauen kann, je nach dem, welchen Parameter (wohlgemerkt vom Typ char) man ihr übergibt? Kenn ich von meinem Lehrer. |
Also wenn man vorher endliche Automaten o.ä. im Unterricht durchgesprochen hat, ergibt das doch Sinn.
Yogu - Di 31.05.11 15:32
Moderiert von
Narses: Komplett-Zitat des letzten Beitrags entfernt.
Das haben wir in der Tat, aber ich sehe trotzdem keinen Sinn darin, einzelne Zeichen als Zustandsindikatoren zu verwenden. Und ein Getränkeautomat hat normalerweise auch nicht einen Knopf, den man in eine bestimmte Richtung oder unterschiedlich tief drücken kann, sondern einfach mehrere davon.
>M@steR< - Di 31.05.11 15:53
Gelöscht
Jann1k - Di 31.05.11 16:26
| Zitat: |
| Das haben wir in der Tat, aber ich sehe trotzdem keinen Sinn darin, einzelne Zeichen als Zustandsindikatoren zu verwenden. |
Da gebe ich dir recht, das kann man besser machen.
| Zitat: |
| Und ein Getränkeautomat hat normalerweise auch nicht einen Knopf, den man in eine bestimmte Richtung oder unterschiedlich tief drücken kann, sondern einfach mehrere davon. |
Aber ein endlicher Automat hat aber eben nur genau eine Zustandsüberführungsfunktion.
beastofchaos - Di 31.05.11 16:28
Jep bei meinem Informatiklehrer ist das auch so ungefähr :P
@Lazarusboy - Tipp für dich, deinen Lehrer missachtend: sag doch z.B. einfach, bei OnClick auf Cola:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| begin Kosten := 1,50; if Kosten > Bezahlt then Edit1.Text := 'Sie haben zu wenig bezahlt !' else begin Rückgabe := Bezahlt - Kosten; Edit1.Text := 'Sie erhalten eine leckere Cola und ' + FloatToStr(Rückgabe) + ' € als Rückgeld !'; end; end; |
Das wäre die Prozedur für das eine Click-Ereignis. Wenn du mehrere Buttons (Cola, Fanta, Sprite) machst, dann nimmst du für alle eine Prozedur (ButtonClick(Sender: TObject)) und fragst per case-Schleife, welcher Button gedrpckt ist:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| procedure TMainForm.ButtonClick(Sender: TObject); var Kosten, Rückgabe: Integer; begin case Sender of BCola: Kosten := 1,50; BFanta: Kosten := 1,00; BSprite: Kosten := 1,20; end;
Rückgabe := Bezahlt - Kosten; Edit1.Text := 'Sie erhalten ein leckeres Getränk und ' + FloatToStr(Rückgabe) + ' € als Rückgeld !'; end; |
Genial, ne?
Gruß, Thomas
buster - Mi 01.06.11 12:29
Kein Pädagoge im Saal? :)
Ich schätze mal, die Aufgabe lautete, Lösen Sie das Problem mit Hilfe des im Unterricht besprochenen Algorithmus ...
Es wird dem Lehrer sicher nicht um die (irgendeine) bestmögliche Lösung gehen (mir ist schon klar, dass sowas wesentlich effizienter gelöst werden kann), sondern darum, den vermittelten Stoff irgendwie in einem (mehr oder weniger passenden) Anwendungsbeispiel zu verbasteln... um zu sehen, ob es auch verstanden wurde. Also nicht das Ergebnis zählt, sondern der Weg ist hier das Ziel ;) ...Abweichungen enden da schnell mal in 'Thema verfehlt' und schlechten Noten...
LG, Basti
Xearox - Mi 01.06.11 12:38
Nichts destotrotz würde ich Lazarusboy empfehlen, seinen oben geschrieben Code zu formatieren.
Wie oben auch geschrieben wurde von jemanden, damit man mal einen Überblick erhält.
Weil 3 x end; untereinander ist ziemlich schwer mit Anhieb herauszufinden, welchen End; zu welchem begin gehört.
Vllt. kann dann Lazarusboy in seinem Code selber den Fehler finden.
anubis2k5 - Do 02.06.11 18:25
Hallo Leute!
Ich habe von dieser Materie nicht viel Ahnung, aber wäre das Problem nicht gelöst, wenn man die Schleife einfach mittels "exit;" verlässt?
Yogu - Do 02.06.11 19:19
anubis2k5 hat folgendes geschrieben : |
| Ich habe von dieser Materie nicht viel Ahnung, aber wäre das Problem nicht gelöst, wenn man die Schleife einfach mittels "exit;" verlässt? |
In dem Quellcode gibt es keine Schleife, also würde
Exit; die Prozedur abbrechen.
Damit wäre möglicherweise das beschriebene Problem gelöst. Den Quelltext verstanden hätte trotzdem niemand, und der nächste Fehler würde nicht lange auf sich warten lassen.
beastofchaos - So 05.06.11 19:00
Genau, da ist von Anfang an keine Hoffnung :P
Nebenbei: "Exit" unterbricht immer die Funktion/Prozedur. "Break" unterbricht die Schleife (was wenn keine da ist?).
Sowas ist aber ein bisschen unbeliebt - schließlich siehst du so nicht bei einem Blick, wo die Prozedur/Funktion endet.
Man nennt das, glaub ich, auch "Spaghetti-Code" :)
Gruß, Thomas
Fiete - Mo 06.06.11 09:51
Moin Lazarusboy,
zu jedem endlichen Automaten gehört ein Zustandsdiagramm, das sich gut programmieren läßt.
Die Planungsarbeit ist die wichtigste!
Vielleicht hilt der Anhang. :les:
Gruß Fiete
Delete - Mo 06.06.11 10:14
Wo um Himmels Willen kommt nur die Unsitte her, Verzweigungen als Schleife zu bezeichnen? Man spricht ja auch nicht von einer for-Verzweigung. :twisted:
beastofchaos - Mo 06.06.11 23:12
okay! Case-Verzweigung, For/While/Repeat-Schleife, If-Abfrage ;)
Also was macht nun "Break", wenn man sich in keiner dieser Arten befinde? Fehlermeldung oder wie "Exit" die Prozedur/Funktion beenden?
Delete - Di 07.06.11 09:08
Was spricht dagegen es einfach mal auszuprobieren? Dein Computer wird schon nicht explodieren:
Delphi-Quelltext
1: 2: 3:
| ShowMessage('Vor break'); break; ShowMessage('Nach break'); |
beastofchaos - Di 07.06.11 09:26
Luckie hat folgendes geschrieben : |
Was spricht dagegen es einfach mal auszuprobieren? Dein Computer wird schon nicht explodieren:
Delphi-Quelltext 1: 2: 3:
| ShowMessage('Vor break'); break; ShowMessage('Nach break'); | |
Genau das befürchte ich :'( xD
der organist - Di 07.06.11 21:34
wer machts?
EDIT: Ich. Heraus kommt bei F9 folgendes:
[DCC Fehler] UMain.pas(29): E2097 BREAK oder CONTINUE außerhalb der Schleife
schon irgendwie lustig :D
EDIT No2: Dann aus Sinnfreiigkeit das ausgetestet:
Delphi-Quelltext
1: 2: 3: 4:
| ShowMessage('Vor Break'); while True do break; ShowMessage('Nach Break'); |
Wenigstens funktioniert es...
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!