Autor Beitrag
Lazarusboy
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 28



BeitragVerfasst: Mo 30.05.11 19:07 
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:

ausblenden volle Höhe 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 542
Erhaltene Danke: 33

Windows 7 Premium
Delphi XE, Eclipse
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 28



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: Mo 30.05.11 20:21 
Wenn ich deinen Code soweit überblicke, sieht das in etwa so aus:

ausblenden 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:

ausblenden 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.

Für diesen Beitrag haben gedankt: BenBE
Jann1k
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 866
Erhaltene Danke: 43

Win 7
TurboDelphi, Visual Studio 2010
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: Di 31.05.11 15:32 
Moderiert von user profile iconNarses: 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.

Für diesen Beitrag haben gedankt: BenBE
>M@steR<
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 288
Erhaltene Danke: 3



BeitragVerfasst: Di 31.05.11 15:53 
Gelöscht


Zuletzt bearbeitet von >M@steR< am Di 17.09.13 01:52, insgesamt 1-mal bearbeitet
Jann1k
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 866
Erhaltene Danke: 43

Win 7
TurboDelphi, Visual Studio 2010
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 247
Erhaltene Danke: 4



BeitragVerfasst: 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:

ausblenden 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;
  // hier evtl. einige variablen wieder auf Null setzen für den nächsten Durchlauf oder so ;) 
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:

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 66
Erhaltene Danke: 7

WIN 7
Delphi 2010 Prof
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 260
Erhaltene Danke: 3



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 23

Windows 7
Delphi 2010
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: Do 02.06.11 19:19 
user profile iconanubis2k5 hat folgendes geschrieben Zum zitierten Posting springen:
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 247
Erhaltene Danke: 4



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 617
Erhaltene Danke: 364

W7
Delphi 6 pro
BeitragVerfasst: 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
Einloggen, um Attachments anzusehen!
_________________
Fietes Gesetz: use your brain (THINK)
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 06.06.11 10:14 
user profile iconbeastofchaos hat folgendes geschrieben Zum zitierten Posting springen:
case-Schleife

Wo um Himmels Willen kommt nur die Unsitte her, Verzweigungen als Schleife zu bezeichnen? Man spricht ja auch nicht von einer for-Verzweigung. :twisted:
Regan
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 2157
Erhaltene Danke: 72


Java (Eclipse), Python (Sublimetext 3)
BeitragVerfasst: Mo 06.06.11 10:18 
Kennst du die if-Schleife noch nicht?

Für diesen Beitrag haben gedankt: beastofchaos, MDX
beastofchaos
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 247
Erhaltene Danke: 4



BeitragVerfasst: 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?
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 07.06.11 09:08 
Was spricht dagegen es einfach mal auszuprobieren? Dein Computer wird schon nicht explodieren:
ausblenden Delphi-Quelltext
1:
2:
3:
ShowMessage('Vor break');
break;
ShowMessage('Nach break');
beastofchaos
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 247
Erhaltene Danke: 4



BeitragVerfasst: Di 07.06.11 09:26 
user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
Was spricht dagegen es einfach mal auszuprobieren? Dein Computer wird schon nicht explodieren:
ausblenden Delphi-Quelltext
1:
2:
3:
ShowMessage('Vor break');
break;
ShowMessage('Nach break');


Genau das befürchte ich :'( xD