Einzelnen Beitrag anzeigen

Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#2

Re: draw poker, hand erkennung

  Alt 12. Jan 2007, 10:47
Hi und herzlich Willkommen in der DP

Was deine Frage angeht, so bin ich mir ehrlich gesagt nicht ganz sicher, was Du eigentlich genau gefragt hast. Versteh mich nicht falsch! Ich möchte damit nur sagen, dass die meisten Leute hier Dir gerne helfen werden, wenn sie können! Nur solltest Du dabei immer daran denken, dass keiner dein Problem so gut kennt wie Du. Damit andere also verstehen, was Du eigentlich machen möchtest, solltest Du dir immer ein paar Minuten mehr Zeit nehmen (die schnelleren und gezielteren Antworten machen den Aufwand schnell wett) und dein Problem einfach und ausführlich schildern.
Satzzeichen sind da schon mal ein guter Anfang (sehe nur eins hinter "tach")

Aber mal zum Problem, erstmal schauen ob ich das richtig verstanden habe:
Du programmierst ein Pokerspiel (soweit so klar). Hier möchtest Du den Wert eines Blatts/einer Hand ermittlen? Das verstehe ich jetzt unter Handerkennung, aber wie Du vielleicht schon raushörst, so richtig sicher bin ich mir nicht. Da wäre es dann (für's nächste mal) schöner, wenn Du solche Begriffe ruhig erklärst (nur als Tipp gemeint, erhöht die Wahrscheinlichkeit, dass Dir jmd. hilft).
Die Frage die Du hier stellst ist, ob man diese Erkennung vereinfachen kann. Ob etwas nun einfacher ist oder nicht, dass kann kaum Pauschal gesagt werden, da müsste man schon Deinen bisherigen Ansatz als Relation betrachten. Den hast Du aber nicht wirklich klar geschildert.

Du hast (bisher) eine Karte, die bei Dir als JPEG repräsentiert wird? Das ist eher schlecht. Du solltest hier ganz klar die Darstellung (JPEG) von der Logik (Karte, Blatt, ...) trennen. Das ermöglicht Dir einfach, dass Du die Bilder beliebig austauschen kannst, ohne dass Du dafür dein Spiel verändern musst. Aber auch umgekehrt kannst Du die Kartenbilder für ganz andere Programme verwenden, die vielleicht ihre Karten ganz anders speichern. Ersteres ist dabei durchaus üblicher, i.d.R. ändert sich eher die Darstellung (z.B. mittels Skins o.Ä.).
Wie gesagt, wie eine Karte bei Dir aussieht ändert nichts daran, dass 5 mal die gleiche Farbe ein Flush ist.

Deswegen kannst Du für die Logik einen einfachen Datentypen erstellen, der einfach die Farbe und den Wert einer Karte speichert. Für die Spieler merkst Du dir dann einfach nur in dieser Form ihr Blatt. Für die Anzeige kannst Du dann einfach auf eine Klasse zurückgreifen, die dir zu einer Karte ein Bild zeichnet. Hier kann dann später die graphische Repräsentation ausgetauscht werden.

Für die Logik, was für einen Wert das Blatt hat, kannst du jetzt ganz einfach mit den Karten arbeiten. Geh einfach das Blatt durch und überprüfe (von oben nach unten) was Du im Blatt findest. Du kannst z.B. einfach schauen, ob viermal der gleiche Wert im Blatt ist, natürlich wird das Blatt auch einen Drilling und sogar zwei Zwillinge enthalten, aber das braucht dich nicht mehr zu interessieren!

Die Werte kannst Du dabei dann einfach direkt vergleichen, mal ein wenig im Beispiel:
Delphi-Quellcode:
type
  TKartenWert = 1..13; // 1 = AS, 11 = Bube, 12 = Dame, 13 = König
  TKartenFarbe = (kfKaro, kfHerz, kfPik, kfKreuz);

  TKarte = class(TObject)
    private
      FWert: TKartenWert;
      FFarbe: TKartenFarbe;
    ...
    public
      ...
      property Wert: TKartenwert read FWert;
      property Farbe: TKartenFarbe read FFarbe;
  end;

....
Für die eigentliche Auswertung hast Du dann zwei Möglichkeiten. Du kannst zwei Blätter paarweise in einer Methode vergleichen und hier einfach das stärkere zurückgeben oder Du lässt Dir den Wert einer Hand zurückgeben und vergleichst woanders (was dann aber die Unterscheidung zwischen einzelnen Päarchen, Drillingen, ...) nötig macht.
Der erste Weg sollte also der einfachere sein. Hier kannst Du einfach die Properties Wert und Farbe vergleichen (der Einfachheit halber gehe ich mal von nach Wert Sortierten Blättern aus, kannst Du ja leicht machen):

Delphi-Quellcode:
TBlatt = Array[1..5] of TKarte;

function isFlush(const Blatt: TBlatt): Boolean;
begin
  result := (Blatt[1] = Blatt[2]) and (Blatt[2] = Blatt[3]) and
            (Blatt[3] = Blatt[4]) and (Blatt[4] = Blatt[5]);
end;

function isStraight(const Blatt: TBlatt): Boolean;
begin
  // Zur Erinnerung, es wird von Sortierten Blättern ausgegangen!
  result := (Blatt[2].Wert = succ(Blatt[1].Wert)) and
            (Blatt[3].Wert = succ(Blatt[2].Wert)) and
            (Blatt[4].Wert = succ(Blatt[3].Wert)) and
            (Blatt[5].Wert = succ(Blatt[4].Wert)) and
end;

function isStraightFlush(const Blatt: TBlatt): Boolean;
begin
  result := isFlush(Blatt) and isStraight(Blatt);
end;

function isRoyalFlush(const Blatt: TBlatt): Boolean;
begin
  result := isStraightFlush(Blatt) and (Blatt[1] = 10);
end;

// usw.
So könntest Du jetzt völlig unabhängig von den eigentlichen Werten und Farben feststellen, was Du hier für eine Wertigkeit hast. Natürlich ist das hier noch nicht der vollständige Vergleich. Der müsste daraus bestehen, dass Du die Blätter paarweise prüfst und hier das höchste extrahierst. Sind zwei Blätter nach den Kriterien hier gleichwertig (z.B. zweimal ein Flush), dann muss hier noch zusätzlich geprüft werden, ob eines der Blätter eine höhere Karte besitzt als das andere.
Aufpassen musst Du auch noch beim FullHouse, die Prüfung nach Päarchen und Drilling würde natürlich auch beim Drilling/Vierling wahr sein (da die beides erfüllen!), hier muss also wirklich auf unterschiedliche Werte geprüft werden.

Hoffe aber, dass die Idee grob klar ist (kann aber nicht sagen, ob das einfacher ist als Du es bisher machst).

Gruß Der Unwissende
  Mit Zitat antworten Zitat