AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Fehler (warsch.) eine Abfrage. In Tic Tac Toe KI. HelpPlease
Thema durchsuchen
Ansicht
Themen-Optionen

Fehler (warsch.) eine Abfrage. In Tic Tac Toe KI. HelpPlease

Ein Thema von M4ST3R86 · begonnen am 3. Jul 2004 · letzter Beitrag vom 5. Jul 2004
Antwort Antwort
Seite 1 von 2  1 2      
M4ST3R86

Registriert seit: 1. Mai 2004
23 Beiträge
 
#1

Fehler (warsch.) eine Abfrage. In Tic Tac Toe KI. HelpPlease

  Alt 3. Jul 2004, 23:23
das ist eine demo zu Tic tac toe mit zufallssetzung des pc'S. Mit 2d array, Das problem ist wenn ich starte und ein X setze dann sagt der direkt X hat gewonnen und hört auf den pc zu setzen aber wieso frage ich mich. Ich hoffe hier kann mir einer helfen bin kurz vor dem verzweifeln.

Zum Programm: ich habe ein leeres image ein x image und ein o image die lade ich dann in die image ja nach fall.

Hier meine ICQ: 261738606 wenn einer die exe haben will.




Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, jpeg, ExtCtrls, StdCtrls;

type
  TFieldType = ( ftX, ftO, ftNone );

  TForm1 = class(TForm)
    ImageK0: TImage;
    ImageK8: TImage;
    ImageK4: TImage;
    ImageK1: TImage;
    ImageK2: TImage;
    ImageK5: TImage;
    ImageK3: TImage;
    ImageK6: TImage;
    ImageK7: TImage;
    Label1: TLabel;
    ImageO: TImage;
    ImageX: TImage;
    Memo1: TMemo;
    Button1: TButton;
    ImageBlank: TImage;
    procedure ImageK0Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    bMovePlayerX : boolean;
    bGameOver : boolean;
    GameBoard : array[ 0..2,0..2 ] of TFieldType;

    function CheckForFreeField( nFieldIdx : integer ) : boolean;
    procedure SetField( img : TImage; nFieldIdx : integer; fieldType : TFieldType );
    procedure ResetGameBoard();
    procedure SimpleKI();
    function FindField( nIdx : integer ) : TImage;
    function CheckForWinner( ft : TFieldType ) : boolean;
    function HasWinner() : TFieldType;
    procedure ProcessWinnerFunc();
    function IsGameOver() : boolean;
    procedure ClearImages;
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//Sucht ein TImage Objekt, aus der Objektliste von Form1, mit dem Tag 'nIdx'
function TForm1.FindField( nIdx : integer ) : TImage;
var
  i : integer;
begin
  //Durchlauf aller Komponenten auf Form1
  for i := 0 to Form1.ComponentCount - 1 do begin
    //Falls Komponente 'i' von Typ TImage ist UND Komponente 'i' den Tag 'nIdx' hat, diese
    //als Funktionsrückgabewert festlegen und aus der Schleife springen
    if ( Form1.Components[ i ] is TImage ) and ( ( Form1.Components[ i ] as TImage ).Tag = nIdx ) then begin
      result := Form1.Components[ i ] as TImage;

      break;
    end;
  end;
end;

//Resetet das Spielfeld
procedure TForm1.ResetGameBoard();
var
  i,x,y : integer;
begin
   for x := 0 to 2 do
   begin
   for y := 0 to 2 do
   begin
  //Setzt alle Einträge des Arrays 'GameBoard' auf den Wert ftNone
   GameBoard[x,y] := ftNone;
  //Setzt die globale Variable 'bGameOver' auf false
  bGameOver := false;
  end;
  end;
end;

//Prüft ob das Spielfeld 'nFieldIdx' noch frei ist
function TForm1.CheckForFreeField( nFieldIdx : integer ) : boolean;
var x,y : integer;
begin
  //Result standardmäßig auf false
  result := false;

  //Wenn 'nFieldIdx' größer als 8 ist false zurückgeben
  if ( nFieldIdx > 8 ) then
    result := false;

   for x := 0 to 2 do
   begin
   for y := 0 to 2 do
   begin
  //Wenn das Spielfeld 'nFielIdx' den Wert ftNone hat, true zurückgeben
  if ( GameBoard[ x,y ] = ftNone ) then
   result := true;
   end;
   end;
end;

//Setzt das Spielfeld 'nFieldIdx' auf den wert 'fieldType' und weist 'img' das passende Bild zu
procedure TForm1.SetField( img : TImage; nFieldIdx : integer; fieldType : TFieldType );
var x,y : integer;
begin
  //Ist das Feld 'nFieldIdx' noch frei?
  if ( CheckForFreeField( nFieldIdx ) ) then begin
    //Setzt das Feld 'nFieldIdx' auf den Wert 'fieldType'
    for x := 0 to 2 do
   begin
   for y := 0 to 2 do
   begin
    GameBoard[ x,y ] := fieldType;
    end;
    end;
    //Je nach 'fieldType' das passende Bild an 'img' übergeben
    case fieldType of
      ftX : img.Picture.Assign( ImageX.Picture );
      ftO : img.Picture.Assign( ImageO.Picture );
    end;
  end;
end;

//Event der allen Spielfeldern( Visell: TImage ) zugewießen wurde
procedure TForm1.ImageK0Click(Sender: TObject);
var
  nFieldNum : integer;
  nCurrImg : TImage;
begin
  //Falls der Sender nicht von Typ TImage ist abbrechen
  if not ( Sender is TImage ) then
    exit;

  //Wenn 'bGameOver' auf true gesetzt ist, ebenfalls abbrechen
  if bGameOver then
    exit;

  //Den Sender einer Hilfvariable übergeben
  nCurrImg := ( Sender as TImage );
  //Den Tag (Feldnummer) des Senders einer Hilfvariable übergeben
  nFieldNum := nCurrImg.Tag;

  //Überprüfen ob das geklickte Feld frei ist, falls nicht aus der
  //Funktion springen
  if ( not CheckForFreeField( nFieldNum ) ) then begin
    Label1.Caption := 'Move again';
    exit;
  end;

  //Passendes Bild bzw. passender Feldtype auswählen
  if ( bMovePlayerX ) then
    SetField( nCurrImg, nFieldNum, ftX )
  else
    SetField( nCurrImg, nFieldNum, ftO );

  //Prüfen ob jemand gewonnen hat oder alle Felder belegt sind (unendschieden)
  ProcessWinnerFunc();

  //Wenn 'bGameOver' auf true gesetzt wurde aus der Funktion springen
  if ( bGameOver ) then
    exit;

  //'bMovePlayerX' negieren'???
  bMovePlayerX := not bMovePlayerX;
  //Zufallszug für den Computer ausführen
  SimpleKI();
  //Nochmals Prüfen ob jemand gewonnen hat
  ProcessWinnerFunc();
end;

//Create Event von Form1
procedure TForm1.FormCreate(Sender: TObject);
begin
  //PlayerX fängt an
  bMovePlayerX := true;
  //Spielfeld reseten
  ResetGameBoard;
  Randomize;
end;

//Gane billige ZufallsKI
procedure TForm1.SimpleKI();
var
  x,y,rndIdx : integer;
  nCurrField : TImage;
begin
  //Zufallswert zwischen 0 und 8
  x := random (2);
  y := random (2);

  //Solang kein freies Feld für den jeweiligen Zufallswert gefunden wurde...

   while not CheckForFreeField( rndIdx ) do begin
    //...Neuen Zufallswert ermitteln
    x := random (2);
    y := random (2);
    end;



  //Finden des entprechenden TImage Objektes für den Index 'rndIdx'
  nCurrField := FindField(rndIdx);

  //Setzten des entsprechenden Wertes
  if ( bMovePlayerX ) then
    SetField( nCurrField,rndIdx, ftX )
  else
    SetField( nCurrField,rndIdx, ftO );

  //Negieren von 'bMovePlayerX' (heisst das echt negieren???)
  bMovePlayerX := not bMovePlayerX;
end;

//Prüft ob einer der beidem Player gewonnen hat
function TForm1.CheckForWinner( ft : TFieldType ) : boolean;
var
  y,x,i : integer;
begin
  {//Standardgemäß hat mal keiner gewonnen
  result := false;

  //Zähler auf 0
  x := 0;
  y :=0;
  i:=0;

  //Folgende zwei Schleifen könnte man in eine Funktion zusammenfassen

  //Kleiner test
  {while i < 8 do begin
    if ( GameBoard[ y,x ] = ft ) and ( GameBoard[ y,x + 1 ] = ft ) and ( GameBoard[ y,x + 2 ] = ft ) then begin
      result := true;
      break;
    end;
    end;
    end;
    inc( i, 3 );
  end;

  //Zähler auf 0
  i := 0;

  //Nochmal ein kleiner test
  while i <> 3 do begin
    if ( GameBoard[ y,x  ] = ft ) and ( GameBoard[ y,x  + 3 ] = ft ) and ( GameBoard[ y,x  + 6 ] = ft ) then begin
      result := true;
      break;
    end;

    inc( i, 1 );
  end; 

  //Diagonale Reihen überpüfen
  if ( GameBoard[ 0,0 ] = ft ) and ( GameBoard[ 1,1 ] = ft ) and ( GameBoard[ 2,2 ] = ft ) then
    result := true;

  //Ebenfalls diagonal
  if ( GameBoard[ 0,2 ] = ft ) and ( GameBoard[ 1,1 ] = ft ) and ( GameBoard[ 2,0 ] = ft ) then
    result := true; }

end;

//Checkt ob es einen Gewinner gibt, wenn ja wird der entsprechende Typ zurückgegeben
function TForm1.HasWinner() : TFieldType;
begin
  //Standard auf ftNone
  result := ftNone;

  //Hat SpielerX gewonnen? Falls ja Rückgabewert auf ftX setzen
  if ( CheckForWinner( ftX ) ) then
    result := ftX
  //Falls nicht, hat vielleicht SpielerO gewonnen?
  else if ( CheckForWinner( ftO ) ) then
    result := ftO;


end;

///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////



//Hilfsfunktion, auswerten des Gewinners
procedure TForm1.ProcessWinnerFunc();
var
  winner : TFieldType;
begin
  //Gewinnertyp zuweisen
  winner := HasWinner();

  //Wenn SpielerX gewonnen hat, das dem Spieler deutlich machen
  if ( winner = ftX ) then begin
    label1.Caption := 'Player ''x'' has won';
    bGameOver := true;
  end
  //Wenn SpielerO gewonnen hat, ebenfalls ausgeben
  else if ( winner = ftO ) then begin
    label1.Caption := 'Player ''o'' has won';
    bGameOver := true;
  end;

  //Wenn jemand gewonnen hat, können wir uns den Rest sparen
  if ( bGameOver ) then exit;

  //Prüfen ob alle Felder belegt wurden
  bGameOver := IsGameOver();

  //Wenn 'bGameOver' auf true gesetzt wurde UND keiner gewonnen hat,
  //ist unentschieden angesagt.
  if ( bGameOver ) and ( winner = ftNone ) then
    label1.Caption := 'Nobody has won';
end;

//Prüft ob alle Spielfelder mit einem Wert (nicht ftNone) belegt sind
function TForm1.IsGameOver() : boolean;
var
  i,x,y : integer;
begin
  //Standard mal auf true
  result := true;

  //Schleife die immer Feld 'i' überprüft
  for x := 0 to 2 do begin
  for y := 0 to 2 do begin
    //Falls ein Feld auf ftNone gesetzt ist, false zurückgeben
    //und aus der Schleife springen
    if ( GameBoard[ x,y ] = ftNone ) then begin
      result := false;
      break;
    end;
    end;
  end;
end;

//Belegt alle TImage Objekte mit dem weisen Standardbild
procedure TForm1.ClearImages();
var
  currImg : TImage;
  i : integer;
begin
  for i := 0 to 8 do begin
    currImg := FindField( i );

    //Falls currImg nicht nil ist
    if ( currImg <> nil ) then
      currImg.Picture := ImageBlank.Picture;
  end;
end;

//Event für Button1 (New game)
procedure TForm1.Button1Click(Sender: TObject);
begin
  //Board reseten
  ResetGameBoard;
  //Images mit Standardbild versehen
  ClearImages;
end;

end.
  Mit Zitat antworten Zitat
M4ST3R86

Registriert seit: 1. Mai 2004
23 Beiträge
 
#2

Re: Fehler (warsch.) eine Abfrage. In Tic Tac Toe KI. HelpPl

  Alt 4. Jul 2004, 13:10
kann mir keiner helfen?
  Mit Zitat antworten Zitat
scp

Registriert seit: 31. Okt 2003
1.120 Beiträge
 
Delphi 7 Personal
 
#3

Re: Fehler (warsch.) eine Abfrage. In Tic Tac Toe KI. HelpPl

  Alt 4. Jul 2004, 13:27
So, jetzt hatte ich mal Zeit den etwas längeren Code-Schnipsel zu überblicken. Was mir zunächst auffällt:

In TForm1.ResetGameBoard wird bGameOver 9x auf false gesetzt, macht zwar keinen Fehler ist aber unnötig.

In TForm1.CheckForFreeField wird nFieldIdx in der Schleife nicht verwendet, das heisst er prüft alle Felder und es kommt nie das richtige Ergebnis raus

In TForm1.SetField das gleiche: nFieldIdx wird in der Schleife nicht verwendet, also setzt er ALLE Felder auf den gewünschten Spieler. Ausserdem ist case fieldType of NICHT mehr in der Schleife drin, auch wenn es nach deinem Code-Aufbau so aussieht.
  Mit Zitat antworten Zitat
xineohp

Registriert seit: 29. Jan 2004
Ort: Heusenstamm
420 Beiträge
 
Delphi 2005 Professional
 
#4

Re: Fehler (warsch.) eine Abfrage. In Tic Tac Toe KI. HelpPl

  Alt 4. Jul 2004, 13:34
moin,

hier liegt der Hund begraben:

formal:
1. Warum hast du das alles auskommentiert?
2. die markierten end;'s sind zuviel!

logisch:
1. Gameboard ist ein zweidimensionales array auf das mit den Koordinaten[x,y] zugegriffen wird nicht per durchlaufendem Index!
-->Für was hast du die Zählervariable (i) wenn du sie nie einsetzt! Die Schleife "//Kleiner test" führt dreimal exakt die gleichen Abfragen durch! Wenn dann müsste i y heißen und von 0 bis 2 laufen.
-->"//Nochmal ein kleiner test" müsste analog aufgebaut sein, mit x als Laufvariable und y,y+1,y+2


Zitat von M4ST3R86:
Delphi-Quellcode:
//Prüft ob einer der beidem Player gewonnen hat
function TForm1.CheckForWinner( ft : TFieldType ) : boolean;
var
  y,x,i : integer;
begin
  {//Standardgemäß hat mal keiner gewonnen
  result := false;

  //Zähler auf 0
  x := 0;
  y :=0;
  i:=0;

  //Folgende zwei Schleifen könnte man in eine Funktion zusammenfassen

  //Kleiner test
  {while i < 8 do begin
    if ( GameBoard[ y,x ] = ft ) and ( GameBoard[ y,x + 1 ] = ft ) and ( GameBoard[ y,x + 2 ] = ft ) then begin
      result := true;
      break;
    end;
    end;    <--- überflüssig/falsch
    end;    <--- überflüssig/falsch
    inc( i, 3 );
  end;

  //Zähler auf 0
  i := 0;

  //Nochmal ein kleiner test
  while i <> 3 do begin
    if ( GameBoard[ y,x  ] = ft ) and ( GameBoard[ y,x  + 3 ] = ft ) and ( GameBoard[ y,x  + 6 ] = ft ) then begin
      result := true;
      break;
    end;

    inc( i, 1 );
  end; 

  //Diagonale Reihen überpüfen
  if ( GameBoard[ 0,0 ] = ft ) and ( GameBoard[ 1,1 ] = ft ) and ( GameBoard[ 2,2 ] = ft ) then
    result := true;

  //Ebenfalls diagonal
  if ( GameBoard[ 0,2 ] = ft ) and ( GameBoard[ 1,1 ] = ft ) and ( GameBoard[ 2,0 ] = ft ) then
    result := true; }

end;
Peter Enenkel
blubb
  Mit Zitat antworten Zitat
M4ST3R86

Registriert seit: 1. Mai 2004
23 Beiträge
 
#5

Re: Fehler (warsch.) eine Abfrage. In Tic Tac Toe KI. HelpPl

  Alt 4. Jul 2004, 14:29
gutt mit den 2 ends habe ich es jetzt verbessert. aber bei den anderen sachen die ihr sagt, währe nett wenn ihr gerade ein kleines beispiel geben würdet bitte.

gehts das?
  Mit Zitat antworten Zitat
Benutzerbild von Mirilin
Mirilin

Registriert seit: 21. Dez 2002
Ort: Lenzburg
861 Beiträge
 
Delphi 6 Professional
 
#6

Re: Fehler (warsch.) eine Abfrage. In Tic Tac Toe KI. HelpPl

  Alt 4. Jul 2004, 14:39



So als kleines Beispiel, wie Du es umschreiben könntest
Delphi-Quellcode:
function TForm1.CheckForFreeField(x,y : Byte):Boolean;
begin
  Result := GameBoard[x,y] = ftNone;
end;
mfg Tobias

[Edit]
Das Feld (GameBoard) sieht ja so aus :
Code:
y _ _ _ 
0|_|_|_|
1|_|_|_|
2|_|_|_|
  0 1 2 x
Tobias
Die Physik ist für die Physiker eigentlich viel zu schwer.
  Mit Zitat antworten Zitat
M4ST3R86

Registriert seit: 1. Mai 2004
23 Beiträge
 
#7

Re: Fehler (warsch.) eine Abfrage. In Tic Tac Toe KI. HelpPl

  Alt 4. Jul 2004, 14:50
nö das klappt nicht der meckert wegen boolean da rum, glaube nicht das das von dir was bringt?

das kann doch nicht alles sein oder?
  Mit Zitat antworten Zitat
xineohp

Registriert seit: 29. Jan 2004
Ort: Heusenstamm
420 Beiträge
 
Delphi 2005 Professional
 
#8

Re: Fehler (warsch.) eine Abfrage. In Tic Tac Toe KI. HelpPl

  Alt 4. Jul 2004, 16:15
moin,

Du mischst deine Darstellungselement mit den logischen Elementen. Soll heißen:
Warum prüfst du in "CheckForFreeField" ob ImageKx = ImageX? es ist doch viel einfacher zu prüfen ob Gameboard[x,y]=ftnone ist! ( siehe Mirilin )
Peter Enenkel
blubb
  Mit Zitat antworten Zitat
M4ST3R86

Registriert seit: 1. Mai 2004
23 Beiträge
 
#9

Re: Fehler (warsch.) eine Abfrage. In Tic Tac Toe KI. HelpPl

  Alt 4. Jul 2004, 23:14
das prob ist das der kein boolean will. der zeigt da nen fehler an
  Mit Zitat antworten Zitat
scp

Registriert seit: 31. Okt 2003
1.120 Beiträge
 
Delphi 7 Personal
 
#10

Re: Fehler (warsch.) eine Abfrage. In Tic Tac Toe KI. HelpPl

  Alt 4. Jul 2004, 23:35
Zitat von M4ST3R86:
das prob ist das der kein boolean will. der zeigt da nen fehler an
Wieso "will" er kein boolean? Kannst du mal die genaue Fehlermeldung sagen? Schliesslich steht ja bei der Funktion, das der Rückgabewert boolean ist.

Probiers mal mit Klammern:

Delphi-Quellcode:
function TForm1.CheckForFreeField(x,y : Byte):Boolean;
begin
  Result := (GameBoard[x,y] = ftNone);
end;
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:16 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz