| Autor |
Beitrag |
bf109g.01
      
Beiträge: 84
|
Verfasst: Do 11.02.10 20:36
Hallo, ich habe ein Programm geschrieben, mit dem man das bekannte Spiel "Schiffe versenken" zu zweit spielen kann. An einer Stelle passiert allerdings etwas komisches:
Text, den ich in die Prozedur zum Schießen auf das Feld des Gegners reinschreibe, wird einfach ignoriert. Delphi gibt keinen Hinweis, keine Fehlermeldung, sondern liest einfach nicht weiter.
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:
|
procedure TForm6.Feuern; var vX,vY:integer; Typ:string; Versenkt,Verloren:boolean;
begin
if Spielfeld[strtoint(Form6.EX.text),strtoint(Form6.EY.text)].Treffer=true then showmessage('Feld bereits beschossen.') else begin BTreffen.Enabled:=false; BWechsel.Enabled:=true; inc(Zugzaehler); Form6.LZug.caption:='Züge: '+InttoStr(Zugzaehler);
Spielfeld[strtoint(Form6.EX.text),strtoint(Form6.EY.text)].Treffer:=true;
showmessage('Schuss auf ('+Form6.EX.text+') | ('+Form6.EY.text+'). Getroffen: '+Spielfeld[strtoint(Form6.EX.text),strtoint(Form6.EY.text)].Typ);
Typ:=Spielfeld[strtoint(Form6.EX.text),strtoint(Form6.EY.text)].Typ;
for vX := 1 to 10 do for vY := 1 to 10 do if Spielfeld[vX,vY].typ=typ then if Spielfeld[vX,vY].treffer=false then begin Versenkt:=false; if Spielfeld[vX,vY].Typ<>'Wasser' then showmessage(Typ+' schwimmt noch...'); abort; end;
if Versenkt then begin for vX := 1 to 10 do for vY := 1 to 10 do if Spielfeld[vX,vY].typ=typ then Spielfeld[vX,vY].versenkt:=true;
showmessage(Typ+' zerstört.'); end;
Verloren:=true; for vX := 1 to 10 do for vY := 1 to 10 do if Spielfeld[vX,vY].typ<>'Wasser' then if Spielfeld[vX,vY].versenkt=false then begin Verloren:=false; abort; end;
if Verloren then begin case Aktiv of 1: showmessage('Flotte vernichtet. Spieler 1 hat das Spiel gewonnen!'); 2: showmessage('Flotte vernichtet. Spieler 2 hat das Spiel gewonnen!'); end;
application.terminate; end;
end; end; |
Komisch ist dabei, dass nicht nur prozedurintern nachfolgender Text ignoriert wird, sondern auch alles was dem Prozeduraufruf folgt.
Die Nachrichten "Flotte vernichtet blabla" erscheinen noch und application.terminate funktioniert asuch noch, wenn die if-Fallunterscheidung wahr ist.
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| procedure TForm6.BTreffenClick(Sender: TObject); begin Feuern; Reload_Grafik; end; |
Insgesamt ist das ziemlich nervig und ich habe nicht die leiseste Ahnung, warum das so ist. Bitte schaut mal, ob ihr was findet.
|
|
Flamefire
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Do 11.02.10 23:52
Fehler ist dein Abort!
Guck dir mal die Hilfe an, was das macht!
wenn dann meintest du break (schleife verlassen) bzw exit (prozedure verlassen)
ist aber alles NICHT zu epmfehlen und sollte durch entsprechende ifs und variablen ersetzt werden.
Außerdem würde ich das design ändern:
1) Feuern sollte als parameter (x,y:Integer) erhalten, spart konvertierungen und unnötige zugriffe auf die edits
2) Die Doppelschleifen (was auch immer die machen sollen) als extra prozeduren anlegen. also z.b. (function IsVersenkt(x,y,typ):Boolean )
3) Mal die Dopelschleifen angucken. ich glaube die machen nicht, was sie sollen. Oder ist der typ eindeutig? (also keine 2 schiffe haben den gleichen typ?)
|
|
bf109g.01 
      
Beiträge: 84
|
Verfasst: Sa 13.02.10 15:37
Flamefire hat folgendes geschrieben : | | 1) Feuern sollte als parameter (x,y:Integer) erhalten, |
1) x,y gleich an Feuern zu übergeben ist eine gute Idee. An welcher stelle muss ich das schreiben? Geht das so?
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure TForm6.BTreffenClick(Sender: TObject); var x,y:integer; begin x:=Ex.text; y:=Ey.text; Feuern (x,y:Integer); Reload_Grafik; end; |
Flamefire hat folgendes geschrieben : | | 3) Mal die Dopelschleifen angucken. ich glaube die machen nicht, was sie sollen. Oder ist der typ eindeutig? (also keine 2 schiffe haben den gleichen typ?) |
3) Die Doppelschleifen sind richtig und notwendig, damit das komplette Feld abgescannt wird: 10 x 10 Felder werden so spaltenweise (von oben nach unten) überprüft.
Der Typ ist eindeutig, es gibt jedes Schiff nur 1 mal.
Flamefire hat folgendes geschrieben : | | wenn dann meintest du break (schleife verlassen) bzw exit (prozedure verlassen) |
break kann ich deswegen auch nicht benutzen, weil dadurch nur eine, nämlich die innere Schleife verlassen wird.
Flamefire hat folgendes geschrieben : | | 2) Die Doppelschleifen (was auch immer die machen sollen) als extra prozeduren anlegen. also z.b. (function IsVersenkt(x,y,typ):Boolean ) |
2) Das Prinzip der Funktion hab ich verstanden. Hab aber im Mom keinen Plan, wie ich die Function schreiben müsste und weiß auch nicht, wie ich die Abrufen soll.
Delphi-Quelltext 1: 2:
| if function IsVersenkt(x,y,typ)=false then |
|
|
Flamefire
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Sa 13.02.10 18:25
Dann als erstes: Delphi-Tutorials lesen.
Wenn du nicht weißt, was man mit Parametern macht, hat der Rest keinen Sinn
Nicht böse gemeint, ist aber einfach so.
Alle Infos stehen in meinem Post.
Wenn du weiß, was prozeduren und Funktionen sind, wie und wo man die verwendet, verstehst du auch meinen Post und die Lösung ist klar 
|
|
elundril
      
Beiträge: 3747
Erhaltene Danke: 123
Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
|
Verfasst: Sa 13.02.10 20:27
Flamefire hat folgendes geschrieben : | | Dann als erstes: Delphi-Tutorials lesen. |
Huch, mein Stichwort.  Am bestern sind Christian's Crashkurs und Delphi-Wikibook.
lg elundril
_________________ This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.
|
|
|