Einzelnen Beitrag anzeigen

w3seek
(Gast)

n/a Beiträge
 
#29

Re: Sieger-Prüfung "Vier gewinnt"

  Alt 29. Jun 2004, 01:51
so, ich hoffe das ist ausreichend kommentiert Man koennte alle 3 funktionen sogar in eine funktion legen, das sieht dann so aus:

Delphi-Quellcode:
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;
  Mit Zitat antworten Zitat