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 1 von 7  1 23     Letzte »    
Benutzerbild von Luckie
Luckie

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

Sieger-Prüfung "Vier gewinnt"

  Alt 28. Jun 2004, 23:44
Hier im Forum kursieren ja die einige Lösungen. Aber keine befriedigt mich so recht.

Ich habe ein 2D Integer Array mit 7 Spalten und 6 Reihen. 0 steht für leer, 1 für Spieler eins und 2 für Spieler zwei. Dürfte Klar sein, denke ich. Mein Problem, wie überprüfe ich am geschicktesten, ob vier einsen oder vier zweien in einer Reihe sind (auch diagonal)?

Mein Code Rumpf sieht bisher so aus:
Delphi-Quellcode:
function TFourInARow.CheckWinner: Boolean;

  function CheckRow(r: Cardinal): Boolean;
  var
    i: Integer;
    Prev: Integer;
  begin
    result := False;
    for i := ROWS-1 downto 0 do
    begin
      
    end;
  end;

  function CheckColumn(c: Cardinal): Boolean;
  begin
    result := False;
  end;

  function CheckDiagonal: Boolean;
  begin
    result := False;
  end;
  
var
  c, r: Integer;
  FourInARow, FourInAColumn, FourInADiagonal: Boolean;
begin
  for c := 0 to COLUMNS - 1 do
  begin
    FourInAColumn := CheckColumn(c);
  end;
  for r := 0 to ROWS - 1 do
  begin
    FourInARow := CheckRow(r);
  end;
  FourInADiagonal := CheckDiagonal;
  result := FourInAColumn or FourInARow or FourInADiagonal;
end;
Hat irgendjemand eine clevere Idee, wie man die Inline-Funktionen mit Code füllen könnte?
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
 
#2

Re: Sieger-Prüfung "Vier gewinnt"

  Alt 28. Jun 2004, 23:51
Ein Schnellschuss: Die Aktuelle Reihe in einen String konvertieren, und nach den Substrings '1111' oder '2222' mit Pos suchen. Das für je alle möglichen Reihen (bei diagonal fallen ja ein paar weg, wo nicht 4 in eine Reihe passen )

Weiss nicht wie gut das ist; war die Idee die mir grad spontan kam.

gruss,
dizzy
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
 
#3

Re: Sieger-Prüfung "Vier gewinnt"

  Alt 28. Jun 2004, 23:54
Das ist gar nicht mal soooo dumm. Aber irgendwie unelegant, finde ich. Da muss es doch was mathematisches geben.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
w3seek
(Gast)

n/a Beiträge
 
#4

Re: Sieger-Prüfung "Vier gewinnt"

  Alt 29. Jun 2004, 00:02
wie waers damit?

folgendes mach fuer spieler 1 und 2 getrennt:
du laeufst jede zeile ab, hast einen counter den du anfangs auf null setzt. findest du den spieler, erhoehst du die zahl um 1, ansonsten setz sie zurueck auf 0. wenn am ende 4 rauskommt hast du 4 in einer reihe. das gleiche kannst mit jeder spalte machen und noch diagonal.
  Mit Zitat antworten Zitat
Basilikum

Registriert seit: 9. Aug 2003
389 Beiträge
 
Delphi 7 Professional
 
#5

Re: Sieger-Prüfung "Vier gewinnt"

  Alt 29. Jun 2004, 00:12
ich würde etwas in dieser Art verwenden:

Delphi-Quellcode:
Function CheckField(Const Field : Array Of Array Of Byte;Const SameCoinCount : Byte) : Byte;
// Return value: 0 or ID of winning player

Function CheckRow(Const Row : Byte) : Byte;
Var
  X,
  Coin,
  Count : Byte;
Begin
  X:=0;
  While (X <= Length(Field[Row]) - SameCoinCount) Do Begin
    Coin:=Field[Row,X];
    If (Coin = 0) Then Begin
      Inc(X);
      Continue;
    end;

    Count:=1;
    While (X + Count < Length(Field[Row])) and (Field[Row,X + Count] = Coin) Do Inc(Count);

    If (Count >= SameCoinCount) Then Begin
      Result:=Coin;
      Exit;
    end;

    Inc(X,Count);
  end;

  Result:=0;
end;

Var
  X : Byte;
Begin
  For X:=1 To Length(Field) Do Begin
    Result:=CheckRow(X - 1);
    If (Result > 0) Then Exit;
  end;

  Result:=0;
end;
(Analog dazu CheckColumn)
  Mit Zitat antworten Zitat
Benutzerbild von dizzy
dizzy

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

Re: Sieger-Prüfung "Vier gewinnt"

  Alt 29. Jun 2004, 00:23
Hmmm mathematisch... Hab grad ein wenig meinen Kopf um Vektoren und Matrizen schwirren lassen... aber das einzige was mir einfiel ist gleich der Spielsteinzählung, bzw. noch einiges aufwändiger. (Hatte gedacht: Jede Zeile/Spalte als Vektor betrachten und seine Länge berechnen. Ist die = 2 ... aber halt... ne ist auch Quatsch. Dann würde auch 010111 gewinnen... neee neee.)

Hab auch im Netz nichts gefunden wo sich jemand über die Gewinnbedingung explizit auslässt. Ich mutmaße jetzt einfach mal, dass es keine implizite mathematische Lösung dafür gibt, sondern dass da wohl doch ein uneleganter Algorithmus herhalten muss.
So lange du die KI nicht mit verketteten if..then..else machst ist das ja noch locker vertretbar
(Habe auch für mein Tic Tac Toe die Gewinnbedingung für jede Zeile/Spalte/Diagonale einzeln geprüft - weil ich damals schon nix fand )

gruss,
dizzy
Fabian K.
INSERT INTO HandVonFreundin SELECT * FROM Himmel
  Mit Zitat antworten Zitat
StefanDP

Registriert seit: 11. Apr 2004
294 Beiträge
 
#7

Re: Sieger-Prüfung "Vier gewinnt"

  Alt 29. Jun 2004, 00:24
hi luckie!

ich bin jetzt mal ganz radikal:
mach das alles in EINE prozedur!
alles war du brauchst ist eine weitere information: der ZULETZT gesetzte spielstein!

dnhand diesen spielsteins kannst du dann prüfen ob
- auf einer seite 3 gleiche
- auf einer seite 2 gleiche auf der anderen seite 1 gleicher
("seite" stellvertretend für links/rechts/oben/unten/diagonal

--> fertig!

Delphi-Quellcode:
// Z: Zeile, S: Spalte
function Ist(Spalte, Zeile, Wer: Integer): TRUE;
begin
  // prüfen ob es das Feld gibt und ob es "Wer" (das gleiche) ist
end;

procedure NeuerSpielsteinGesetzt(S, Z, W);
begin
...
  if (Ist(S-3,Z,W) and Ist(S-2,Z,W) and Ist(S-1,Z,W)) or // nach links
     (Ist(S+3,Z,W) and Ist(S+2,Z,W) and Ist(S+1,Z,W)) or // nach rechts
     ... // nach oben/unten/linksoben/rechtsoben...
     (Ist(S-2,Z,W) and Ist(S-1,Z,W) and Ist(S+1,Z,W)) or // 2 links 1 rechts
     ... // 2 rechts 1 links, 2 oben 1 unten usw
     then
       ShowMessage('Gewonnen mit freundlicher Grüßen von Stefans zugroß geratener If Abfrage ;-)');
end;
ich hoff ihr versteht wie ich das mein
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

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

Re: Sieger-Prüfung "Vier gewinnt"

  Alt 29. Jun 2004, 00:30
Zitat von StefanDP:
ich hoff ihr versteht wie ich das mein
Also ich nicht.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

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

Re: Sieger-Prüfung "Vier gewinnt"

  Alt 29. Jun 2004, 00:40
So, ich habe jetzt mal w3seeks methode genommen, scheint mir noch am geschicktesten. ASber irgendwo ist da der Wurm drinne. Er findet nur einen Sieger bei der untersten Reihe bzw. bei der recghtesten Spalte. Ich sehe den Wald vor lauter Bäumen nicht mehr:

Delphi-Quellcode:
function TFourInARow.CheckWinnerPlayerOne: Boolean;
var
  c, r: Integer;
  FourInARow, FourInAColumn, FourInADiagonal: Boolean;
  cnt: Integer;

  function CheckRow(r: Cardinal): Boolean;
  var
    i: Integer;
  begin
    cnt := 0;
    for i := 0 to COLUMNS-1 do
    begin
      if Field[i, r] = 1 then
        Inc(cnt)
    end;
    result := cnt = 4;
  end;

  function CheckColumn(c: Cardinal): Boolean;
  var
    i: Integer;
  begin
    cnt := 0;
    for i := 0 to ROWS-1 do
    begin
      if Field[c, i] = 1 then
        Inc(cnt)
    end;
    result := cnt = 4;
  end;

  function CheckDiagonal: Boolean;
  begin
    result := False;
  end;

begin
  for c := 0 to COLUMNS - 1 do
  begin
    FourInAColumn := CheckColumn(c);
  end;
  for r := 0 to ROWS - 1 do
  begin
    FourInARow := CheckRow(r);
  end;
  FourInADiagonal := CheckDiagonal;
  result := FourInAColumn or FourInARow or FourInADiagonal;
end;
Und wenn man das noch etwas vereinfachen könnte, wäre ich auch glücklich.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

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

Re: Sieger-Prüfung "Vier gewinnt"

  Alt 29. Jun 2004, 01:08
Ich habe es jetzt versucht zu vereinfachen, aber ich habe das Gefühl es ist schlimmer geworden und so langsam verliere ich auch die Übersicht. Ich sollte ins Bett gehen.

Delphi-Quellcode:
function TFourInARow.CheckWinnerPlayerOne: Boolean;
var
  cnt: Integer;

  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] = 1 then
          Inc(cnt)
      end;
    end;
    result := cnt = 4;
  end;

  function CheckDiagonal: Boolean;
  begin
    result := False;
  end;

begin
  result := CheckRows;
end;
Und im Anhang mal das ganze Projekt.
Angehängte Dateien
Dateityp: zip viergewinnt_544.zip (6,1 KB, 28x aufgerufen)
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 7  1 23     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 10:08 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