function Gewonnen(Spieler: Byte): Boolean;
const
N_ZEILEN = 6;
N_SPALTEN = 7;
N_GEWINNT = 4;
Spielfeld: array[0..N_ZEILEN-1] of array[0..N_SPALTEN-1] of Cardinal =
(
(0, 0, 0, 0, 0, 0, 0),
(0, 0, 0, 0, 0, 0, 0),
(0, 0, 0, 0, 0, 0, 0),
(0, 0, 0, 0, 0, 0, 0),
(0, 0, 0, 0, 0, 0, 0),
(0, 0, 0, 0, 0, 0, 0)
);
function GewinntReihe(Zeile, Spalte, Delta, Max: Integer): Boolean;
var
Anfang, Pos, Ende: PCardinal;
c, i: Integer;
begin
Result := false;
// wir holen uns die adresse des punktes von dem aus wir das spielfeld betrachten, das ist der linke bzw obere spielrand
Pos := @Spielfeld[Zeile, Spalte];
// wir holen uns die adressen der punkte ueber bzw unter die wir nicht gehen duerfen
Anfang := @Spielfeld[0, 0];
Ende := @Spielfeld[N_ZEILEN - 1][N_SPALTEN - 1];
c := 0;
i := 0;
// diese schleife so lange ausfuehren bis die aktuelle position ausserhalb des spielfelds gesetzt wurde
while (Cardinal(Pos) <= Cardinal(Ende)) and (Cardinal(Pos) >= Cardinal(Anfang)) do
begin
// ist der gesuchte spieler an der aktuellen stelle?
if Pos^ = Spieler then
begin
// wir zaehlen hoch, wie viele punkte hintereinander schon ohne unterbrechnung waren
Inc(c);
if c = N_GEWINNT then
begin
// ok, wir haben genau N_GEWINNT punkte in folge, der spieler hat gewonnen!
Result := true;
Exit;
end;
end
else
begin
// ok, der punkt ist nicht gesetzt oder gehoert nicht zu dem gesuchten spieler, wir setzen den counter zurueck
c := 0;
end;
// wir springen zum naechsten punkt der getestet wird. je nachdem in welche richtung wir gehen und wie weit, gibt delta an.
Inc(Pos, Delta);
// fuer zeilen und spalten brauchen wir ein maximum um nicht in die naechste zeile/spalte zu gelangen!
if Max > 0 then
begin
Inc(i);
// Schleife unterbrechen, wenn wir das Maximum ueberschritten haben
if i >= Max then
begin
Exit;
end;
end;
end;
end;
var
i: Integer;
begin
Result := false;
// wir laufen von der linken oberen spielecke zur linken unteren spielecke
for i := 0 to N_ZEILEN - 1 do
begin
// sind in dieser zeile 4 aufeinanderfolgende punkte des spielers?
// der abstand zum naechsten punkt in der zeile ist 1, wir pruefen maximal N_SPALTEN punkte in der zeile
if GewinntReihe(i, 0, 1, N_SPALTEN) or
// -(N_SPALTEN - 1) ist der abstand zum naechsten punkt der rechts oben (diagonal) liegt, der abstand ist
// also negativ und um 1 geringer als das spielfeld spalten hat, wir setzen keine maximale anzahl an punkten die zu pruefen sind, also Max=0
GewinntReihe(i, 0, -(N_SPALTEN - 1), 0) or
// N_SPALTEN + 1 ist der abstand zum naechsten punkt rechts unten (diagonal), der abstand ist also positiv
// und um 1 groesser als das spielfeld spalten hat, wir setzen keine maximale anzahl an punkten die zu pruefen sind, also Max=0
GewinntReihe(i, 0, N_SPALTEN + 1, 0) then
begin
Result := true;
Exit;
end;
end;
// wir laufen von der linken oberen zur rechten oberen spielecke
for i := 0 to N_SPALTEN - 1 do
begin
// sind in dieser spalte 4 aufeinanderfolgende punkte des spielers?
// der abstand zum naechsten punkt (der direkt unter dem ausgangspunkt liegt)
// ist die anzahl der punkte in einer zeile. Wir pruefen nur N_ZEILEN punkte in der spalte!
if GewinntReihe(0, i, N_SPALTEN, N_ZEILEN) or
// N_SPALTEN + 1 ist der abstand zum naechsten punkt unterhalb und rechts von diesem punkt, also um 1 groesser
// als das spielfeld spalten hat, wir setzen keine maximale anzahl an punkten die zu pruefen sind, also Max=0
GewinntReihe(0, i, N_SPALTEN + 1, 0) or
// N_SPALTEN - 1 ist der abstand zum naechsten punkt unterhalb und links von diesem punkt, also um genau 1 kleiner
// als das spielfeld spalten hat, wir setzen keine maximale anzahl an punkten die zu pruefen sind, also Max=0
GewinntReihe(0, i, N_SPALTEN - 1, 0) then
begin
Result := true;
Exit;
end;
end;
end;