![]() |
AW: zweidimensionale Arrays
Debuggen und schauen was passiert?
@Michael: Das ist der Unterschied(e) zwischen ![]() ![]() ![]() |
AW: zweidimensionale Arrays
@Michael: Das ist der Unterschied(e) zwischen
![]() ![]() ![]() Danke ;-) himitsu. Dann würde mich spontan auf den Rest dieser Zeile - zum Beispiel den Wert von eingabe - konzentrieren. mo du schreibst gueltig oder cancel seien true. Woher hast du diese Werte? Du weisst, ![]() |
AW: zweidimensionale Arrays
Zitat:
P.S.: Eigentlich müsste der Compiler hier eine Warnung ausgeben. |
AW: zweidimensionale Arrays
Ich habe ein kleines Problem und zwar das falls eine Bombe eingetragen werden soll einfach nichts geschieht.
Sieht vielleicht jemand von euch wo der Fehler ist, der Debugger hilft mir da auch nicht weiter. :drunken:
Delphi-Quellcode:
{$APPTYPE CONSOLE} {$R+,Q+,X-} uses System.SysUtils, Windows; const FIELDSIZE : Byte = 7; type TSize = 1..7; TSTATE = (leer, Bombe); TDIR = (Nord, NordOst, Ost, SüdOst, Süd, SüdWest, West, NordWest); TFIELD = array[TSIZE, TSIZE] of TSTATE; TVISIBLE = array[TSIZE, TSIZE] of Boolean; const OFFSET_X : array[TDIR] of integer = (0,1,1,1,0,-1,-1,-1); OFFSET_Y : array[TDIR] of integer = (1,1,0,-1,-1,-1,0,1); //Setzt die Ausgabeposition der Konsole auf die angegebene Koordinate. //@param //x,y - zu setzende Position in der Konsole an 0/0 = oben links procedure setConsolePosition(x,y : byte); var coord : _COORD; begin coord.X := x; coord.Y := y; if SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord) then; end; //Setzt die Textfarbe der Konsole //@param //color - zu setzender Farbwert procedure setTextColor(color : word); begin if SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color) then end; //Initialisiert das Feld leer und das Sichbarkeitsfeld mit 'false' //Setzt in gerundet 10% aller Zellen eine Bombe //@param //field - Feld, welches initialisiert wird //visible - zu setzendes Sichtbarkeitsfeld procedure initField(var field : TFIELD ; var visible : TVISIBLE); var x, y, r, s : integer; begin for x := 1 to FIELDSIZE do begin for y := 1 to FIELDSIZE do begin visible[x, y] := FALSE; field[x,y] := leer; end; end; r := (FIELDSIZE * FIELDSIZE) div 10; s := (FIELDSIZE * FIELDSIZE) mod 10; if s >= 5 then inc(r); // Bomben platzieren randomize; while r > 0 do begin x := Random(FIELDSIZE) + 1; // Random liefert einen Wert 0..(FIELDSIZE - 1) y := Random(FIELDSIZE) + 1; if field[x, y] = leer then begin field[x, y] := Bombe; Dec(r); end; end; end; //Prüft, ob eine Koordinate gültig ist //@param // x,y - zu überprüfende Koordinatenwerte //@out //Überprüfung ob Koordinate im Bereich des Spielfeldes liegt //@return // true, wenn Koordinaten gültig sind function isValidCoord(x,y : integer): boolean; begin if ((x <= FIELDSIZE) and (x >= 1)) then if ((y <= FIELDSIZE) and (y >= 1)) then isValidCoord := TRUE else isValidCoord := FALSE; end; //Zeigt an, wie viele Bomben sich auf den Nachbarzellen, der übergebenen //Koordinate befinden //@param //field - Spielfeld, welches geprüft wird //x,y - Koordinaten //@out //Bestimmung der Nachbarzellen //@return // byte-Wert, wie viele Bomben in den Nachbarzellen existieren function countBombs(field : TFIELD; x,y : TSIZE) : byte; var dir : TDIR; xNachbar, yNachbar : integer; n : byte; begin n := 0; for dir := low(TDir) to high(TDir) do begin xNachbar := x + OFFSET_X[dir]; yNachbar := y + OFFSET_Y[dir]; if field[x,y] = Bombe then inc(n); end; countBombs := n; end; //Textausgabe des Spielfeldes in der Konsole //@param //field - Spielfeld, welches ausgegeben werden soll //visible - augedeckte Zellen procedure printField(field : TFIELD; visible : TVISIBLE); var x, y : byte; s: string; n: Integer; begin for x := 1 to FIELDSIZE do begin for y := 1 to FIELDSIZE do begin if not visible[x, y] then s := '▓' else if visible[x,y] and (field[x, y] = Bombe) then s := 'ð' else begin n := countBombs(field, x, y); if n = 0 then s := ' ' else s := IntToStr(n); end; write(s,' '); end; writeln; end; end; //liest vom Benutzer Spalte und Zeile ein und prüft diese. Außerdem wird der //Benutzer gefragt ob die gewählte Zelle aufgedeckt oder als Bombe markiert //oder das Programm mit der Eingabe von x beendet werden soll //@param //x,y - x- und y-Koordinate des Spielfeldes //cancel - soll das Spiel verlassen werden? //bomb - soll eine Bombe markiert werden? //@out // //@return function readInput(var x, y: TSize; var cancel, bomb: Boolean): Boolean; var gueltig: Boolean; eingabeX, eingabeY, eingabeZ: Char; field : TFIELD; visible : TVISIBLE; begin eingabeX := upcase(eingabeX); gueltig := FALSE; cancel := FALSE; readInput := gueltig or cancel; writeln('Bitte eine Spalte von 1 bis 7 eingeben oder ''X'' für Abbruch: '); readln(eingabeX); case eingabeX of 'X': cancel := TRUE; '1'..'7': begin gueltig := TRUE; x := StrToInt(eingabeX); end; else readInput := FALSE; end; if gueltig then begin writeln('Bitte eine Zeile von 1 bis 7 eingeben oder ''X'' für Abbruch: '); readln(eingabeY); case eingabeY of 'X': cancel := TRUE; '1' .. '7': begin gueltig := TRUE; y := StrToInt(eingabeY); end else readInput := FALSE; end; end; if isValidCoord(x,y) then begin writeln('Bitte ein ''B'' eingeben, wenn dort eine Bombe markiert werden '+ 'soll, leer lassen zum Aufdecken oder ''X'' für Abbruch: '); readln(eingabeZ); case eingabeZ of 'B' : field[x,y] := Bombe; 'X' : cancel := TRUE; else readInput := FALSE; end; visible[x,y] := TRUE; end; end; // Prüft, ob das gesamte Spielfeld mit Ausnahme der Bomben aufgedeckt ist // @param // field - Spielfeld, in dem geprüft werden soll // visible -Sichtbarkeit der Zellen // @out // // @return // true, wenn alle Zellen außer die Bomben aufgedeckt sind (* function isFieldSolved(field : TFIELD; visible :TVISIBLE) : boolean; begin while visible or (field = Bombe) do end; *) var field: TFIELD; visible: TVISIBLE; cancel, bomb: Boolean; x, y: TSize; eingabe: char; eingabeX: integer; eingabeY: integer; begin initField(field, visible); printField(field, visible); while readInput(x,y,cancel, bomb) do begin writeln('haha'); printField(field,visible); end; readln; end. |
AW: zweidimensionale Arrays
Zitat:
Setze einen Breakpoint am Ende von readInput. Starte das Programm. Wähle Spalte und Zeile und setze mit B eine Bombe. Der Debugger hält nun am Ende von readInput an. Jetzt kannst du weiter steppen mit Funktionstaste F8 und siehst, was passiert. (Deine Funktion readInput gibt offenbar false zurück.) Nebenbei: eingabeX := upcase(eingabeX); macht dort wo's steht immer noch gleich wenig Sinn; siehe #10 und #13. Tipp: Beim Kompilieren werden dir Warnungen angezeigt. Lies diese... Bei dieser Zeile steht zum Beispiel: W1036 Variable 'eingabeX' ist möglicherweise nicht initialisiert worden. Und das stimmt auch ;-): eingabeX hat in dieser Zeile noch keinen definierten Wert. Erst NACH dem Einlesen mittels readln(eingabeX); macht upcase() Sinn. Nach readln(eingabeY) und auch bei ...z solltest du wieder upcase() nutzen oder aber so: TIPP: Anstatt upcase() zu nutzen kannst du im case 'X' und 'x' angeben:
Delphi-Quellcode:
case eingabeX of
'X', 'x' : cancel := TRUE; '1'..'7': begin gueltig := TRUE; x := StrToInt(eingabeX); end; Soweit ich mich erinnere soll gemäss Aufgabenstellung dein Spielfeld auch grösser oder kleiner als 7x7 sein dürfen. Wen dem so ist: In deinem Programm sollte nur hier
Delphi-Quellcode:
die Zahl 7 stehen. Suche via IDE nach 7 und ersetze... - Was passiert bei deinen case Abfragen, wenn der Wert FELDSIZE zweistellig ist? (In der Aufgabenstellung wird zur Validierung der Eingabe val(..) empfohlen.)
const
FIELDSIZE : Byte = 7; Viel Spass. |
AW: zweidimensionale Arrays
Da kommt durchgehend nicht verfügbarer Wert für readInput raus :pale:
|
AW: zweidimensionale Arrays
Zitat:
Aber: Den Funktionswert solltest du auch in "Result" finden. Tipp: Du kannst den Funktionswert auch immer als Result := <wert> zurückgeben. Also so:
Delphi-Quellcode:
function readInput(var x, y: TSize; var cancel, bomb: Boolean): Boolean;
... ... Result := ... end; |
AW: zweidimensionale Arrays
Ich hab das mit Result nie wirklich verstanden, ist das eine Funktion ?
Bei mir sagt er dann undeklarierter Bezeichner "Result". |
AW: zweidimensionale Arrays
Beispiel:
Statt
Delphi-Quellcode:
einfach
function isValidCoord(x,y : integer): boolean;
begin if ((x <= FIELDSIZE) and (x >= 1)) then if ((y <= FIELDSIZE) and (y >= 1)) then isValidCoord := TRUE else isValidCoord := FALSE; end;
Delphi-Quellcode:
Für die Rückgabe eines Funktionsergebnisses kann man dem Funktionsnamen einen Wert zuweisen oder eben statt des Funktionsnamens Result schreiben.
function isValidCoord(x,y : integer): boolean;
begin if ((x <= FIELDSIZE) and (x >= 1)) then if ((y <= FIELDSIZE) and (y >= 1)) then Result := TRUE else Result := FALSE; end; Result ist quasi ein Synonym für den Funktionsnamen.
Delphi-Quellcode:
entspricht
Funktionsname := Wert;
Delphi-Quellcode:
Result := Wert;
|
AW: zweidimensionale Arrays
Zitat:
genau... wenn du den Wert von Result abfragst, dann zeigt dein Delphi an E2003 Undeklarierter Bezeichner: 'result' Das liegt am Compilerschalter $X- ganz oben in deinem Code. Nimm diesen Schalter raus. Wahrscheinlich wurde diese Übung im 7. Jahrhundert geschrieben und von Generation zu Generation weitergegeben. Zitat:
![]() Kompiliere dein Programm neu. Setze wieder einen Haltepunkt in readInput. Jetzt wird dir im Fenster "Lokale Variablen" (Menu Ansicht > Debug Fenster > Lokale Variablen) neu auch Result (mit Wert <Wert>) angezeigt. Es ist egal, ob du in deinem Code <Wert> über Result:=<Wert> oder readInput:=<Wert> zugewiesen hast. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:20 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz