AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Sieger-Prüfung "Vier gewinnt"

Ein Thema von Luckie · begonnen am 28. Jun 2004 · letzter Beitrag vom 30. Jun 2004
Antwort Antwort
Seite 2 von 7     12 34     Letzte »    
w3seek
(Gast)

n/a Beiträge
 
#11

Re: Sieger-Prüfung "Vier gewinnt"

  Alt 29. Jun 2004, 01:13
Code:
result := cnt = 4;
das sollte >= 4 sein, hab das wort mindestens vergessen. Ich glaub nicht dass man das in eine funktion ohne es total unuebersichtlich zu machen, zusammenfassen kann. Ich wuerde jede zeile und jede spalte checken, und dann noch die diagonalen bei denen mind 4 felder sind. das sollte eigentlich genuegen.

Allerdings find ich auch den Ansatz von StefanDP ganz gut, setzt allerdings voraus dass man dies beim aendern eines Feldes immer prueft, wenn ein fertiges spielfeld vor liegt, wird man das nicht erkennen.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#12

Re: Sieger-Prüfung "Vier gewinnt"

  Alt 29. Jun 2004, 01:16
Äh, ja. Aber wenn in der zweiten Reihe von unten dann 3 sind hat Spieler eins auch gewonnen. Probier es mal aus.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
w3seek
(Gast)

n/a Beiträge
 
#13

Re: Sieger-Prüfung "Vier gewinnt"

  Alt 29. Jun 2004, 01:23
Code:
    for i := 0 to COLUMNS-1 do
    begin
      if Field[i, r] = 1 then
        Inc(cnt)
      else
        cnt := 0;
    end;
wie gesagt musst du den counter auf null setzen wenn das feld nicht vom gesuchten spieler ist
[edit]
und natuerlich auch fuer jede zeile und spalte wieder auf null setzen
[/edit]
  Mit Zitat antworten Zitat
Benutzerbild von dizzy
dizzy

Registriert seit: 26. Nov 2003
Ort: Lünen
1.932 Beiträge
 
Delphi 7 Enterprise
 
#14

Re: Sieger-Prüfung "Vier gewinnt"

  Alt 29. Jun 2004, 01:23
Ein Problem sehe ich: Eine Zeile/Spalte der Form: 0 1 1 0 0 1 1 würde zu cnt=4 = true führen, obwohl das ja kein Sieg wäre. Es müssen ja nicht nur 4 Steine in einer Zeile/Spalte/Diag. sein, sondern die müssen auch noch lückenlos sein.

Delphi-Quellcode:
function CheckRows: Boolean;
  var
    c, r: Integer;
  begin
    cnt := 0;
    for c := 0 to COLUMNS-1 do
    begin
      for r := 0 to ROWS-1 do
      begin
        if (Field[c, r] = 0) and (cnt > 0) then // bei Unterbrechung durch '0' zurück setzen!
          cnt := 0
        else if Field[c, r] = 1 then
          Inc(cnt);
      end;
    end;
    result := cnt = 4;
  end;

\\edit: *gnarf* 1.: zu langsam; 2.: nicht so elegant wie w3seek... naja
Fabian K.
INSERT INTO HandVonFreundin SELECT * FROM Himmel
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#15

Re: Sieger-Prüfung "Vier gewinnt"

  Alt 29. Jun 2004, 01:27
@dizzy: jetzt funktioniert gar nichts mehr. Ich habe ja das Projekt angehangen, ihr könnte da ja eure Idee ausprobieren. Ich lass das erstmal liegen für heute und gehe ins Bett, glaube ich.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von dizzy
dizzy

Registriert seit: 26. Nov 2003
Ort: Lünen
1.932 Beiträge
 
Delphi 7 Enterprise
 
#16

Re: Sieger-Prüfung "Vier gewinnt"

  Alt 29. Jun 2004, 01:49
SO! Jetzt aber. Das Problem war, dass die Schleife immer bis zum Ende durchlief. Daher fand sie auch NUR Siegbedingungen im letzten Durchgang. Lösung: Ein nicht so schönes, aber wirkungsvoll angebrachtes "exit".

Delphi-Quellcode:
  function CheckRows: Boolean;
  var
    c, r: Integer;
  begin
    for r := 0 to ROWS-1 do
    begin
      cnt := 0;
      for c := 0 to COLUMNS-1 do
      begin
        if Field[c, r] <> 1 then cnt := 0
        else inc(cnt);
        if cnt = 4 then
        begin
          result := true;
          exit;
        end; // if cnt=4
      end; // for c...
    end; // for r...
    result := false;
  end; // CheckRows
(Getestet!)

Für CheckColumns einfach die beiden Schleifenköpfe gegeneinander austauschen, und für Diagonal reicht mein Hirnschmalz heute auch net mehr
btw: für ein CheckRows waren die Schleifen ohnehin schon falsch herum verschachtelt! Eigentlich war's schon die CheckColumns .
btw2: das "exit" könnte man jetzt noch umgehen, in dem man das ganze in repeat-until-Schleifen packt, und bei cnt=4 nen Flag setzt. Ist aber imho in diesem Fall nicht viel leichter lesbar, und zu dem weniger performant.

n8i,
dizzy
Fabian K.
INSERT INTO HandVonFreundin SELECT * FROM Himmel
  Mit Zitat antworten Zitat
w3seek
(Gast)

n/a Beiträge
 
#17

Re: Sieger-Prüfung "Vier gewinnt"

  Alt 29. Jun 2004, 01:57
Ok, hier mein Algorithmus:

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 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;
Ich habs nicht ausgiebig getestet, aber sollte funktionieren

[edit]
kleiner fix, es sollte glaub ich "while (Cardinal(Pos) <= Cardinal(Ende)) and (Cardinal(Pos) >= Cardinal(Anfang)) do" statt "while (Cardinal(Pos) < Cardinal(Ende)) and (Cardinal(Pos) >= Cardinal(Anfang)) do" sein
[/edit]
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#18

Re: Sieger-Prüfung "Vier gewinnt"

  Alt 29. Jun 2004, 02:00
Oh Gott, wie kommt das den bei mir da jetzt rein? Ich glaube, das muss ich mir noch mal richtig zu Gemühte führen.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von dizzy
dizzy

Registriert seit: 26. Nov 2003
Ort: Lünen
1.932 Beiträge
 
Delphi 7 Enterprise
 
#19

Re: Sieger-Prüfung "Vier gewinnt"

  Alt 29. Jun 2004, 02:04
Zitat von Luckie:
Oh Gott, wie kommt das den bei mir da jetzt rein? Ich glaube, das muss ich mir noch mal richtig zu Gemühte führen.
Nimm meins - das hab ich in deinem Projekt gebaut und getestet
Fabian K.
INSERT INTO HandVonFreundin SELECT * FROM Himmel
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#20

Re: Sieger-Prüfung "Vier gewinnt"

  Alt 29. Jun 2004, 02:06
Hm, w3seeks Code kompiliert, tut nur nicht das, was ich will.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 7     12 34     Letzte »    


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:47 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz