Einzelnen Beitrag anzeigen

ferby

Registriert seit: 15. Aug 2004
Ort: Wien
841 Beiträge
 
Delphi 2010 Enterprise
 
#8

Re: TicTacToe mit mittlerer KI und für 1vs1

  Alt 16. Okt 2005, 08:10
Hallo,

Die KI funktioniert so:

die ersten zwei Züge sind fix und alle weiteren werden per random ermittlet, der Quellcode hat sicher noch viele Fehler und wird zur Zeit von mir überarbeitet. Ich möchte auch mehrer KI-Levels machen, also die KI die jetzt ist (normal) und noch eine bessere (schwer).

Hier der Quellcode:

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, ImgList, Menus, Ferby;

type
  TForm1 = class(TForm)
    feld: TImage;
    Image1: TImage;
    Image2: TImage;
    Image3: TImage;
    Image4: TImage;
    Image8: TImage;
    Image9: TImage;
    Image5: TImage;
    Image7: TImage;
    Image6: TImage;
    ImageList: TImageList;
    menue: TMainMenu;
    NeuesSpiel: TMenuItem;
    Einstellung1: TMenuItem;
    Hilfe: TMenuItem;
    Info: TMenuItem;
    aus: TMenuItem;
    an: TMenuItem;
    procedure AufFeldClick(Sender: TObject);
    procedure check;
    procedure NeuesSpielClick(Sender: TObject);
    procedure KIClick(Sender: TObject);
    procedure HilfeClick(Sender: TObject);
    procedure InfoClick(Sender: TObject);
    procedure KI_Zug;
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  feldwert:array [1..9] of byte;
  spieler:boolean;
  KI_var:boolean=true;
  zug:byte;
  BM:TBitmap;
  wahl: byte;

implementation

{$R *.dfm}

procedure KI_S(feld, w: byte);
begin
  if feldwert[feld]=1 then wahl:=w;
end;


procedure TForm1.KI_Zug;
var
unentschieden:boolean;
i:byte;
begin
  bm := TBitmap.create;
  inc(zug);

  wahl:=0;

  // ZUG 1
  if zug=1 then
  begin
    if feldwert[5]=1 then wahl:=1 else wahl:=5;
  end;

    // ZUG 2
  if zug=2 then
  begin
    if feldwert[1]=1 then
    begin
      KI_S(2,3);
      KI_S(3,2);
      KI_S(4,7);
      KI_S(6,2);
      KI_S(7,4);
      KI_S(8,4);
      KI_S(9,2);
    end;

    if feldwert[2]=1 then
    begin
      KI_S(3,1);
      KI_S(4,1);
      KI_S(6,3);
      KI_S(7,4);
      KI_S(8,4);
      KI_S(9,6);
    end;

    if feldwert[3]=1 then
    begin
      KI_S(4,2);
      KI_S(6,9);
      KI_S(7,2);
      KI_S(8,6);
      KI_S(9,6);
    end;

    if feldwert[4]=1 then
    begin
      KI_S(6,2);
      KI_S(7,1);
      KI_S(8,7);
      KI_S(9,8);
    end;
                                                     
    if feldwert[5]=1 then
    begin
      KI_S(2,8);
      KI_S(3,7);
      KI_S(4,6);
      KI_S(6,4);
      KI_S(7,3);
      KI_S(8,2);
      KI_S(9,3);
    end;

    if feldwert[6]=1 then
    begin
      KI_S(7,8);
      KI_S(8,9);
      KI_S(9,3);
    end;

    if feldwert[7]=1 then
    begin
      KI_S(8,9);
      KI_S(9,8);
    end;

    if feldwert[8]=1 then KI_S(9,7);

  end;

  end;

  unentschieden:=true;
  if wahl=0 then
  repeat
    wahl:=random(9)+1;
    for i:=1 to 9 do if feldwert[i]=0 then unentschieden:=false;
    if unentschieden then exit;
  until feldwert[wahl]=0;


  Imagelist.getbitmap(1,Bm);
  feldwert[wahl]:=2;
  TImage(FindComponent('Image' + inttostr(wahl))).Picture.Bitmap := BM;
end;

procedure TForm1.AufFeldClick(Sender: TObject);
var
i,nr:byte;
begin
  bm := TBitmap.create;

  // No KI
  if not ki_var then
  for i:= 1 to 9 do if (Sender = TImage(FindComponent('Image' + inttostr(i)))) then
  if (feldwert[i]=0) then
  begin
    spieler:=not spieler;
    if spieler then nr:=0 else nr:=1;
    Imagelist.getbitmap(nr,Bm);
    feldwert[i]:=nr+1;
    TImage(FindComponent('Image' + inttostr(i))).Picture.Bitmap := BM;
  end
  else
  ShowMessage('Dieses Feld ist berreits besetzt');

  // With KI
  if ki_var then
  for i:= 1 to 9 do if (Sender = TImage(FindComponent('Image' + inttostr(i)))) then
  if (feldwert[i]=0) then
  begin
    Imagelist.getbitmap(0,Bm);
    feldwert[i]:=1;
    TImage(FindComponent('Image' + inttostr(i))).Picture.Bitmap := BM;
    KI_Zug;
  end
  else
  ShowMessage('Dieses Feld ist berreits besetzt');

  check;

end;

//////////////////////////////////////////////////////////////////////////////// CHECK
function check2(wert1,wert2,wert3,art:integer): boolean;
begin
 result:=false;
 if (feldwert[wert1]=art) and (feldwert[wert2]=art) and (feldwert[wert3]=art) then result:=true;
end;

procedure tform1.check;
var
i : byte;
unentschieden:boolean;
begin

  // Abfrage ob ein Spieler gewonnen hat
  for i:=1 to 2 do
  if
  check2(1,2,3,i) or
  check2(4,5,6,i) or
  check2(7,8,9,i) or
  check2(1,4,7,i) or
  check2(2,5,8,i) or
  check2(3,6,9,i) or
  check2(1,5,9,i) or
  check2(3,5,7,i)
  then
  begin
    if (i=2) and (ki_var) then showmessage('Die KI hat gewonnen') else
    showmessage('Spieler '+inttostr(i)+' hat gewonnen');
    NeuesSpielClick(nil)
  end;

  // Unentschieden?
  unentschieden:=true;
  for i:=1 to 9 do if feldwert[i]=0 then unentschieden:=false;
  if unentschieden then
  begin
    showmessage('Das Spiel ist Unentschieden ausgegangen');
    NeuesSpielClick(nil)
  end;

end;

//////////////////////////////////////////////////////////////////////////////// MENÜ
// Neues Spiel
procedure TForm1.NeuesSpielClick(Sender: TObject);
var
i:byte;
begin
  for i:=1 to 9 do
  begin
    feldwert[i]:=0;
    TImage(FindComponent('Image' + inttostr(i))).Picture.Bitmap := nil;
  end;

  spieler:=false;
  zug:=0;
end;

// KI Klick
procedure Tform1.KIClick(Sender: TObject);
begin
  an.checked:=false;
  aus.checked:=false;

  if sender=an then an.checked:=true
  else aus.checked:=true;

  ki_var:=an.checked;
end;

// Hilfe
procedure TForm1.HilfeClick(Sender: TObject);
begin
showmessage('Hilfe:' +#10#10+ '1) Die KI ist ausgeschalten:' +#10+ 'Zwei menschliche Spieler drücken immer abwechselnd auf ein leeres Feld.' +#10+ 'Sobald jemand drei X bzw drei O übereinander, nebeneinander, oder quer hat, hat dieser Spieler gewonnen.' +#10#10+ '2) Die KI ist eingeschalten:' +#10+ 'Jetzt spielt nur ein menschlicher Spieler gegen den Computer' +#10#10+ 'Viel Spaß!');
end;

// Info
procedure TForm1.InfoClick(Sender: TObject);
begin
  copyright('TicTacToe','2.00');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  randomize;
end;

end.

Das der Quellcode noch nicht perfekt ist weiß ich selbst ,
solltet ihr Rechtschreibfehler finden dann bitte melden!
  Mit Zitat antworten Zitat