striker159
Lt. Junior Grade
- Registriert
- Dez. 2008
- Beiträge
- 327
ohne KI funktioniert das spiel ohne probleme.
mit KI kommt es hin und wieder zu zügen, die weder so gewollt sind, noch die ich "absichtlich" reproduzieren kann.
einfach gesagt: es kommt vor, dass die KI 2 steine setzt. und warum sie das macht, kann ich nicht herausfinden und brauche dabei eure hilfe
erstmal meinen (einfachen) algorithmus für die KI
die Klasse ( der übersicht halber hab ich die sachen weggelassen, die nicht von der ki benutzt werden):
hier noch ein bild zu einer situation, als 2 steine gesetzt wurden. ich habe immer wieder die prozedure KI aufgerufen, also im prinzip haben 2 KIs unendlich lang gegeneinander gespielt:
http://striker159.bplaced.net/4fehler.jpg
rot hat den schwarz markierten stein gesetzt, geld daraufhin die 2 steine mit X
mit KI kommt es hin und wieder zu zügen, die weder so gewollt sind, noch die ich "absichtlich" reproduzieren kann.
einfach gesagt: es kommt vor, dass die KI 2 steine setzt. und warum sie das macht, kann ich nicht herausfinden und brauche dabei eure hilfe
erstmal meinen (einfachen) algorithmus für die KI
1 für alle felder prüfen: Kann man in dieses Feld setzen und dadurch gewinnen?
1.1 wenn ja, dieses feld besetzen => KI siegt.
1.2 wenn nicht , dann weiter mit Punkt 2
2 für alle felder prüfen: Kann der Gegner(der Mensch)in das Feld setzen und dadurch gewinnen ?
2.1 wenn ja: Gewinnt der Gegner (der Mensch) im nächsten Zug, wenn KI seine jetzige Siegmöglichkeit besetzt, und der Mensch auf diesen gesetzten Stein einen weiteren setzt?
2.1.1 wenn nein, gegnerische (menschliche) Siegmöglichkeit durch eigenen Stein verhindern.
2.1.2 wenn ja , gewinnt der Gegner (der Mensch) zu 100% => führt Punkt 2.1.1 aus
2.2 wenn nein, weiter mit Punkt 3.
3. Ist das unterste Feld der mittleren Spalte ( Spielfeld[3,0]) frei?
3.1 wenn ja, dorthin setzen.
3.2 wenn nein , zufällige spalte auswählen und weiter mit Punkt 4
4 Für zufällige Spalte prüfen: Wenn KI in diese Spalte einen Stein setzt, könnte der Gegner auf den Stein setzen und gewinnen?
4.1 wenn ja, dann andere zufällige Spalte auswählen; Wiederhole Punkt 3
4.2 wenn nein, setzt KI den Spielstein in diese Spalte
die Klasse ( der übersicht halber hab ich die sachen weggelassen, die nicht von der ki benutzt werden):
Code:
unit Class_TSpiel;
interface
type
TSpiel = class
private
Spielfeld : array[0..6] of array[0..5] of integer; // 7*6 Spielfeld : 0=leer, 1 = spieler 1, 2=spieler 2
Spieler: integer; // 1= spieler 1, 2= spieler 2
GesetzteReihe:integer; // speichert die Nummer der Reihe, in welche der letzte Stein gesetzt wurde
GesetzteSpalte:integer; // speichert die Nummer der Spalte, in welche der letzte Stein gesetzt wurde
KI_Sieg:boolean; // hat KI gewonnen ?
FeldVoll:boolean; // kein Zug mehr möglich ?
SpalteVoll:array[0..6] of boolean; // ist Spalte X voll ?
function Esiegmgl(x:integer;y:integer):boolean; // Prüft, ob KI durch Setzen eines Steines in Feld[x,y] gewinnen würde
function Gsiegmgl(x:integer;y:integer):boolean; // Prüft, ob der Gegner durch Setzen eines Steines in Feld[x,y] gewinnen würde
function links(x:integer;y:integer):integer; //
function linksO(x:integer;y:integer):integer; //
function linksU(x:integer;y:integer):integer; //
function rechts(x:integer;y:integer):integer; //
function RechtsO(x:integer;y:integer):integer; //
function rechtsU(x:integer;y:integer):integer; //
function unten(x:integer;y:integer):integer; //
public
procedure setzeStein(Spalte:integer); // Setzt einen Stein des aktiven Spielers in eine bestimmte Spalte.
procedure setzeZufallStein{(var x:integer;var y:integer)}; // Setzt einen Stein des aktiven Spielers in eine zufällige Spalte.
procedure spielerwechsel; // Wechelt den aktiven Spieler
procedure KI;
end;
implementation
function TSpiel.Esiegmgl(x:integer;y:integer):boolean;
begin
result:=false;
if Spielfeld[x,y]=0 then
if ((y-1>=0) and (Spielfeld[x,y-1]>0))or (y=0) then begin
Spielfeld[x,y]:=spieler;
if (unten(x,y)>=3) or (links(x,y)+rechts(x,y)>=3) or (linksO(x,y,)+rechtsU(x,y)>=3) or (linksU(x,y)+rechtsO(x,y)>=3) then
result:=true;
Spielfeld[x,y]:=0;
end;
end;
function TSpiel.Gsiegmgl(x:integer;y:integer):boolean;
begin
result:=false;
if (y>=6) then begin
SpalteVoll[x]:=true;
exit;
end;
if Spielfeld[x,y]=0 then
if ((y-1>=0) and (Spielfeld[x,y-1]>0))or (y=0) then begin
spielerwechsel;
Spielfeld[x,y]:=spieler;
spielerwechsel;
if (unten(x,y)>=3) or (links(x,y)+rechts(x,y)>=3) or (linksO(x,y,)+rechtsU(x,y)>=3) or (linksU(x,y)+rechtsO(x,y)>=3) then
result:=true;
Spielfeld[x,y]:=0;
end;
end;
function TSpiel.links(x:integer;y:integer):integer;
begin
result:=0;
if x>0 then
if Spielfeld[x,y]=Spielfeld[x-1,y] then
result:=1+links(x-1,y);
end;
function TSpiel.linksO(x:integer;y:integer):integer;
begin
result:=0;
if (x>0) and (y<5) then
if Spielfeld[x,y]=Spielfeld[x-1,y+1] then
result:=1+linksO(x-1,y+1);
end;
function TSpiel.linksU(x:integer;y:integer):integer;
begin
result:=0;
if (x>0) and (y>0) then
if Spielfeld[x,y]=Spielfeld[x-1,y-1] then
result:=1+linksU(x-1,y-1);
end;
function TSpiel.rechts(x:integer;y:integer):integer;
begin
result:=0;
if x<6 then
if Spielfeld[x,y]=Spielfeld[x+1,y] then
result:=1+rechts(x+1,y);
end;
function TSpiel.rechtsO(x:integer;y:integer):integer;
begin
result:=0;
if (x<6) and (y<5) then
if Spielfeld[x,y]=Spielfeld[x+1,y+1] then
result:=1+rechtsO(x+1,y+1);
end;
function TSpiel.rechtsU(x:integer;y:integer):integer;
begin
result:=0;
if (x<6) and (y>0) then
if Spielfeld[x,y]=Spielfeld[x+1,y-1] then
result:=1+rechtsU(x+1,y-1);
end;
function TSpiel.unten(x:integer;y:integer):integer;
begin
result:=0;
if y>0 then
if Spielfeld[x,y]=Spielfeld[x,y-1] then
result:=1+unten(x,y-1);
end;
procedure TSpiel.setzeStein(Spalte:integer);
var i:integer;
begin
for i:=0 to 5 do
if Spielfeld[Spalte,i]=0 then begin
if Spieler=1 then Spielfeld[Spalte,i]:=1
else Spielfeld[Spalte,i]:=2;
GesetzteReihe:=i;
GesetzteSpalte:=Spalte;
exit;
end;
end;
procedure TSpiel.setzeZufallStein;
var i,j,volleSpalten:integer;
begin
randomize;
volleSpalten:=0;
for i:=0 to 6 do begin
if Spielfeld[i,5]<>0 then begin
SpalteVoll[i]:=true ;
volleSpalten:=volleSpalten+1;
end
else
SpalteVoll[i]:=false;
end;
if (volleSpalten>=7) or (volleSpalten<0) then exit
else if volleSpalten=6 then
begin
FeldVoll:=false;
for i:=0 to 6 do
if SpalteVoll[i]=false then break;
end
else if (volleSpalten<6) and (volleSpalten>=0) then
repeat
i:=random(7);
until SpalteVoll[i]=false;
j:=0;
while j<6 do
begin
if Spielfeld[i,j]=0 then
begin
SetzeStein(i);
if j=5 then
SpalteVoll[i]:=true;
if SpalteVoll[0] and SpalteVoll[1] and SpalteVoll[2] and SpalteVoll[3] and SpalteVoll[4] and SpalteVoll[5] and SpalteVoll[6] then
FeldVoll:=true;
exit;
end
else
begin
if j<5 then
j:=j+1
else
begin
j:=0;
repeat
i:=random(7);
until SpalteVoll[i]=false;
end;
end;
if FeldVoll then
break;
end;
end;
procedure TSpiel.spielerwechsel;
begin
if spieler=1 then spieler:=2
else spieler:=1;
end;
procedure TSpiel.KI;
var i,j,Gsiegmglzaehler,spaltevollzaehler:integer;
a:boolean;
begin
// Punkt 1
for i:=0 to 6 do
for j:=0 to 5 do
if Esiegmgl(i,j) then begin
// 1.1
KI_Sieg:=true;
setzestein(i);
exit;
end;
// Punkt 2
for i:=0 to 6 do
for j:=0 to 5 do
if Gsiegmgl(i,j) then begin
Spielfeld[i,j]:=0;
setzestein(i);
exit;
end;
// Punkt 3
if Spielfeld[3,0]=0 then begin
setzestein(3);
exit;
end;
// Punkt 4
a:=false;
Gsiegmglzaehler:=0;
repeat
spaltevollzaehler:=0;
setzeZufallStein;
if FeldVoll then exit;
for i:=0 to 6 do
if spaltevoll[i] then
spaltevollzaehler:=spaltevollzaehler+1;
if (spaltevoll[gesetzteSpalte]=false )and ( spaltevollzaehler=6) then
a:=false;
if (spaltevoll[gesetzteSpalte]=false )and ( spaltevollzaehler<6) then
begin
if Gsiegmgl(gesetzteSpalte,gesetzteReihe+1) then
begin
if Gsiegmglzaehler<7-spaltevollzaehler then
begin
a:=true;
Spielfeld[gesetztespalte,gesetzteReihe]:=0;
Gsiegmglzaehler:=Gsiegmglzaehler+1
end
else
a:=false;
end
else
a:=false;
end;
until a=false;
end;
end.
hier noch ein bild zu einer situation, als 2 steine gesetzt wurden. ich habe immer wieder die prozedure KI aufgerufen, also im prinzip haben 2 KIs unendlich lang gegeneinander gespielt:
http://striker159.bplaced.net/4fehler.jpg
rot hat den schwarz markierten stein gesetzt, geld daraufhin die 2 steine mit X