So ich habe ja ein reversi-Spieler programmiert. Es funktioniert auch alles ganz wunderbar. Nun gibt es bei reversi jedoch das problem, dass es passieren kann, dass kein spieler mehr setzen kann oder, dass der spieler der an der reihe ist nicht mehr setzen kann. Das zweite hätte zur folge, dass auf den anderen spieler gewechselt wird und das erste, dass das spiel vorbei ist. Nun habe ich mir dazu die passenden prüfungen ausgedacht und bin eigentlich davon überzeugt, dass sie gehe müssten (tun sie natürlich nicht) Es gibt bei dem spiel nämlich immernoch situtionen, wo der spieler nicht mehr setzen kann und dann auch nicht auf den anderen gesetzt wird. aber nun ersteinmal zu meinem code den ich mir ueberlegt habe.
da haben wir einmal die function die prüft, ob ein zug erlaubt ist. sie überschreibt dne gesetzen und die eingekesselten spielsteine im array. zur erklärung: das spiel läuft komplett ind einem 2d array names feld ab. im ondrawcell ereigenis uebertrage ich dann die steine in ein stringgrid.
Delphi-Quellcode:
function TForm1.setSteinAllowed(col,row:integer;uebermalen:boolean):boolean;
var
i,j,k,l,m,n: integer;
abort: boolean;
moeglichkeiten: integer;
token: TSteinFarbe;
begin
if Spieler = SpielerSchwarz then
begin
token := schwarz;
if uebermalen then
feld[col,row] := token;
end
else
begin
token := weiss;
if uebermalen then
feld[col,row] := token;
end;
moeglichkeiten := 0; // moeglichkeiten fuer jeden zug auf 0 setzen
for k := -1 to 1 do // in jede Richtung waagerecht
for l := -1 to 1 do // in jede Richtung senkrecht
begin
if (k <> 0) or (l <> 0) then
i := col;
j := row;
abort := false;
if (Feld[i+k,j+l] <> feld[i,j]) and (Feld[i+k,j+l] <> leer) then // ersten Stein darf nicht leer sein und nicht gleich dem gesetzen
begin
i := i+k; // eine col weiter
j := j+l; // eine row weiter
while (abort = false) and (i>-1) and (i<8) and (j>-1) and (j<8) do
begin
i := i+k; // eine col weiter
j := j+l; // eine row weiter
if (Feld[i,j] = token) then // wenn das feld nun gleich des gesetzen ist...
begin
inc(moeglichkeiten); // moeglichkeiten um 1 erhoehen
{nun die steine ueberschreiben}
if uebermalen then
begin
m := col;
n := row;
repeat
m := m+k;
n := n+l;
feld[m,n] := token;
until
(m=i) and (n=j);
end;
abort := true; // ...dann aufhoeren nach moeglichkeit zu suchen
end
else
if Feld[i,j] = leer then // sollte die erste bedingung nicht zutrffen und das feld sogar leer sein...
abort := true; //... dann suchvorgang abbrechen, da keine loesung vorhandne sein kann
end;
end;
end;
if moeglichkeiten > 0 then // wenn wenigstens eine moeglichkeit zutrifft...
result := true // ...dann ist der zug moeglich
else // sonst
result := false; // ist der zug nicht moeglich
if result = false then // wenn kein zug moeglich, dann das feld leeren
feld[col,row] := leer;
end;
so dann habe ich noch die methode die die spieler wechselt:
Delphi-Quellcode:
procedure TForm1.ChangePlayer;
begin
if Spieler = SpielerWeiss then
begin
Spieler := SpielerSchwarz;
Labelspieler.caption := 'Spieler 1 ist an der Reihe';
image1.visible := true;
image2.visible := false;
end
else
if Spieler = SpielerSchwarz then
begin
Spieler := Spielerweiss;
Labelspieler.caption := 'Spieler 2 ist an der Reihe';
image1.visible := false;
image2.visible := true;
end;
end;
zu guter letzt ist dann da noch die function die guckt ob ueberhaupt noch zugmöglichkeiten vorhanden sind, welche bei meinem problem auch mit die hauptrolle spielt.
Delphi-Quellcode:
function TForm1.NextSetPossible: boolean;
var
i,j: integer;
begin
result := false;
for i := 0 to 7 do
for j := 0 to 7 do
if (feld[i,j] = leer) and (SetSteinAllowed(i,j,false)) then
begin
result := true;
exit; // sobald result brauch er nicht mehr weitersuchen
end;
end;
Diese ganzen prozeduren und Funktionen benutze ich eigentlich im OnSelectCellEreigniss des stringgrids. Ich frage also ab ob die zelle in die ich geklickt habe leer ist und ob ein zug in dieses feld erlaubt ist (falls ja werden auch gleich die eingekesselten steine und der gesetze Stein uebermalt). Nun werden die Spieler gewechselt und es wird abgefragt ob nun ein naechster zug möglich ist. Wenn nein, dann werden nochma die spieler gewechselt ( der selbe spieler ist also beim naechsten zug nochmal dran). Nun wird nochmal abgefragt ob praktisch mit diesem spieler noch ein zug möglich ist, wenn wieder nein, dann ist das spiel logischerweise vorbei. falls ein zug möglich ist, geht das spiel logischerweise normal weiter. hier die methode:
Delphi-Quellcode:
procedure TForm1.StringGridFeldSelectCell(Sender: TObject; ACol,
ARow: Integer; var CanSelect: Boolean);
begin
if (feld[acol,arow] = leer) and (SetSteinAllowed(acol,arow,true)) then
begin
//SetStein(Acol,Arow);
ChangePlayer;
if not nextSetPossible then
begin
ChangePlayer;
if not nextSetPossible then
begin
if SpielerPkt[0] > SpielerPkt[1] then
showmessage('Game Over! Spieler 1 hat gewonnen!')
else
if SpielerPkt[1] > SpielerPkt[0] then
showmessage('Game Over! Spieler 2 hat gewonnen!')
else
if SpielerPkt[0] = SpielerPkt[1] then
showmessage('Game Over! Unentschieden!')
end;
end;
stringgridfeld.repaint;
CountPoints;
end;
end;
So ich weiß, dass das alles ziemlich viel ist. Es wäre nur einfach nett, wenn jemand die zeit mir zu helfen den fehler zu suchen. Ich bin jetzt schon 2 tage dabei und ich find ih einfach nicht Embarassed . Und eh ich komplett durchdrehe, dachte ich mir, dass vielleicht ma fremde und qualifizierte augen da einen blick drauf werfen können. Thx schonmal im vorraus. mfg Furby!