Entwickler-Ecke

Sonstiges (Delphi) - Schleife Tic Tac Toe


Felix7 - Sa 18.02.17 15:23
Titel: Schleife Tic Tac Toe
Hallo,

habe ein laufendes Tic Tac Toe Spiel programmiert und es funktioniert auch alles. Da mein Quelltext aber arg lang ist, möchte ich die Gewinnprüfung mittels einer Schleife durchführen. Hat jemand eine Idee wie ich das am einfachsten umsetzen kann?

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:
procedure TTicTacToe.Feld1Click(Sender: TObject);  //Ereignis beim Klicken eines Buttons
begin
Countererhoehung;
  if Spieler=1 then
   begin
   Feld1.Caption:=('X');
   Codespielfeld [1,1] := 'X';     //Eintragen der Stellung in ein Codespielfeld
   Feld1.Enabled:=false;
   Spieler:=2;     //nächster Spieler ist dran
   end
  else
  if Spieler=2 then
   begin
   Feld1.Caption:=('O');
   Codespielfeld [1,1] := 'O';
   Feld1.Enabled:=false;
   Spieler:=1;
   end;
Gewinnpruefung;
end;

procedure TTicTacToe.Gewinnpruefung;
begin
 
 // Ab hier die Siegerstellungen
 if (Feld1.Caption='X'and  (Feld2.Caption='X'and (Feld3.Caption='X'then //Möglichkeit 1
  begin
   Feld4.visible:= false;
   Feld5.visible:= false;
   Feld6.visible:= false;
   Feld7.visible:= false;
   Feld8.visible:= false;
   Feld9.visible:= false;
   Hintergrund.visible:= false;
   showmessage ('Spieler 1 hat gewonnen!');
   Spielstand1 := Spielstand1+1;
   NeuesSpielstarten.Click;
   Counter := 0;
  end;

Die Gewinnprüfung ist derzeit für jede Gewinnstellung so aufgebaut wie oben zu sehen.

Kann ich hier irgendwie direkt den Quelltext hineinstellen? Ist so ein wenig unübersichtlich :D


Liebe Grüße :)

Moderiert von user profile iconNarses: Delphi-Tags hinzugefügt


Delphi-Laie - Sa 18.02.17 15:40

Das hier:
user profile iconFelix7 hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
Feld4.visible:= false;
Feld5.visible:= false;
Feld6.visible:= false;
Feld7.visible:= false;
Feld8.visible:= false;
Feld9.visible:= false;


läßt sich mit einer Schleife und FindComponent etwas kürzer realisieren.


jfheins - Sa 18.02.17 16:19

Ich habe mal ein vier-gewinnt programmiert, da ist die Gewinnprüfung ja ähnlich. Ich hatte damals ein Array von Feldern. ("Feld" war ein eigenes GUI-Element)

Die Gewinnprüfung sah dann so 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:
function TAboutForm.Gewonnen: Boolean;
var
  i, j: Integer;
begin
  Result := False;

  for i := 0 to 6 do
    for j := 0 to 4 do
      if Felder[i, j].Tag = CurrPlayer then
        if CheckForVictory(i, j) then
        begin
          Result := True;
          Exit;
        end;
end;

function TAboutForm.CheckForVictory(Col, Row: Integer): Boolean;
begin
  Result := False;

  // Prüfung auf waagerechte Reihe nach rechts
  if (Col + 3 in [0..6]) and (Row + 0 in [0..4]) and
     (Felder[Col + 1, Row + 0].Tag = CurrPlayer) and
     (Felder[Col + 2, Row + 0].Tag = CurrPlayer) and
     (Felder[Col + 3, Row + 0].Tag = CurrPlayer) then
  begin
    Result := True;
    Exit;
  end;

  // Prüfung auf schräge Reihe nach rechts unten
  if (Col + 3 in [0..6]) and (Row + 3 in [0..4]) and
     (Felder[Col + 1, Row + 1].Tag = CurrPlayer) and
     (Felder[Col + 2, Row + 2].Tag = CurrPlayer) and
     (Felder[Col + 3, Row + 3].Tag = CurrPlayer) then
  begin
    Result := True;
    Exit;
  end;

  // Prüfung auf senkrechte Reihe nach unten
  if (Col + 0 in [0..6]) and (Row + 3 in [0..4]) and
     (Felder[Col + 0, Row + 1].Tag = CurrPlayer) and
     (Felder[Col + 0, Row + 2].Tag = CurrPlayer) and
     (Felder[Col + 0, Row + 3].Tag = CurrPlayer) then
  begin
    Result := True;
    Exit;
  end;

  // Prüfung auf schräge Reihe nach links unten
  if (Col - 3 in [0..6]) and (Row + 3 in [0..4]) and
     (Felder[Col - 1, Row + 1].Tag = CurrPlayer) and
     (Felder[Col - 2, Row + 2].Tag = CurrPlayer) and
     (Felder[Col - 3, Row + 3].Tag = CurrPlayer) then
  begin
    Result := True;
    Exit;
  end;
end;


Aber das ist schon lange her ^^ Man sollte die Bedingung am Besten auch noch in eine eigene Funktion auslagern.

Der Grundgedanke ist hier, dass man ja nur vier der möglichen acht Richtungen untersuchen muss, weil die anderen ja vom anderen Ende aus geprüft werden.


Fiete - Mo 20.02.17 12:38

Moin Felix7,
hier findest Du einige Infos http://www.entwickler-ecke.de/viewtopic.php?t=77741&highlight=strategiespielen
Im folgendem ist noch eine Version aus dem Jahre 1990 in Turbo-Pascal:

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:
{$R+,G+,Q+}
Program TIC_TAC_TOE;
 Uses Crt;
 VAR T:ARRAY[1..9of INTEGER;
   j,b,i,p:INTEGER;
      flag:BOOLEAN;
      C:Char;

 FUNCTION F(x:INTEGER):INTEGER;
  BEGIN F:=x-8*((x-1DIV 8END;

 PROCEDURE AUSGABE;
  BEGIN
   T[b]:=0;
   WRITELN(T[1]:2,T[2]:2,T[3]:2);
   WRITELN(T[8]:2,T[9]:2,T[4]:2);
   WRITELN(T[7]:2,T[6]:2,T[5]:2);
   WRITELN
  END;

 PROCEDURE EINGABE;
  BEGIN
   REPEAT
    WRITE('Dein Zug : ');READLN(p);
   UNTIL (p>0AND (p<10AND (T[p]<>0AND (T[p]<>-1);
   T[p]:=-1;
  END;

 BEGIN { Hauptprogramm }
  Clrscr;
  FOR i:=1 TO 9 DO T[i]:=i;
  flag:=false;b:=9;{ erster Zug, immer auf 9! }
  AUSGABE;J:=1;EINGABE;b:=F(p+1);
  REPEAT
   AUSGABE;
   j:=j+1;EINGABE;
   IF p=F(b+4THEN b:=F(p+1ELSE flag:=true;
  UNTIL (j=4OR flag;
  IF j=4 THEN BEGIN b:=F(p+5);AUSGABE;WRITELN('Remis!'END
  ELSE BEGIN b:=F(b+4);AUSGABE;WRITELN('MS-DOS GEWINNT !'END;
  C:=Readkey
 END.

Gruß Fiete