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 GewinntZeile(Zeile: Integer): Boolean;
var
c, i: Integer;
begin
Result := false;
c := 0;
// wir pruefen alle punkte in dieser zeile
for i := 0 to N_SPALTEN - 1 do
begin
// hat der spieler hier einen punkt?
if Spielfeld[Zeile][i] = Spieler then
begin
// wir zaehlen unseren counter hoch
Inc(c);
if c = N_GEWINNT then
begin
// wir haben N_GEWINNT aufeinanderfolgendende punkte des spielers, er hat somit gewonnen!
Result := true;
Exit;
end;
end
else
begin
// dieser punkt ist nicht gesetzt oder gehoert nicht dem spieler! Wir setzen den counter auf 0
// da die reihe unterbrochen wurde
c := 0;
end;
end;
end;
function GewinntSpalte(Spalte: Integer): Boolean;
var
c, i: Integer;
begin
Result := false;
c := 0;
// wir pruefen alle punkte in dieser spalte
for i := 0 to N_ZEILEN - 1 do
begin
// hat der spieler hier einen punkt?
if Spielfeld[i][Spalte] = Spieler then
begin
Inc(c);
if c = N_GEWINNT then
begin
// wir haben N_GEWINNT aufeinanderfolgendende punkte des spielers, er hat somit gewonnen!
Result := true;
Exit;
end;
end
else
begin
// dieser punkt ist nicht gesetzt oder gehoert nicht dem spieler! Wir setzen den counter auf 0
// da die reihe unterbrochen wurde
c := 0;
end;
end;
end;
function GewinntDiagonal(Zeile, Spalte, Delta: Integer): Boolean;
var
Anfang, Pos, Ende: PCardinal;
c: 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;
// 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);
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?
if GewinntZeile(i) 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
GewinntDiagonal(i, 0, -(N_SPALTEN - 1)) 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
GewinntDiagonal(i, 0, N_SPALTEN + 1) 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?
if GewinntSpalte(i) 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
GewinntDiagonal(0, i, N_SPALTEN + 1) 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
GewinntDiagonal(0, i, N_SPALTEN - 1) then
begin
Result := true;
Exit;
end;
end;
end;