Frage

Für eine Hausaufgabe bekam ich eine Kartenklasse, die Typen für Rang und Farbe aufzählte.Ich muss zwei Pokerhände vergleichen (jede Hand ist eine ArrayList von 5 Karten) und ermitteln Sie den Gewinner.

Der isStraight() Funktion stört mich wirklich, weil ich nach dem Ass von vorne beginnen muss.Zum Beispiel,

KÖNIGIN, KÖNIG, AS, ZWEI, DREI

Gilt immer noch als Straight.Was ist der beste Weg, diese Funktionalität zu codieren?

Hier ist der aufgezählte Typcode für Rang/Anzug, falls das hilfreich ist.

public enum Rank
{
    TWO(2), THREE(3), FOUR(4), FIVE(5), SIX(6), SEVEN(7), EIGHT(8), NINE(9),
    TEN(10), JACK(11), QUEEN(12), KING(13), ACE(14);

    private final int points;

    private Rank(int points)
    {
        this.points = points;
    }

    public int points()
    {
        return this.points;
    }
}

public enum Suit
{
    DIAMONDS, CLUBS, HEARTS, SPADES;
}
War es hilfreich?

Lösung

Sie erkennen, dass ich nach den Regeln von jedem Pokerspiel jemals von einer geraden gespielt oder gehört nicht einwickeln oder? Ass kann niedrig sein [A, 2,3,4,5] oder hoch [10, J, Q, K, A], aber es kann nicht umgebrochen. diese Regeln nach (nicht verkaufen) Ich habe etwas ähnliches vor implementiert. Grundsätzlich Sie das Array sortieren und es gehen, dafür, dass die aktuelle Karte ist eine höher als die vorherige. In der ersten Iteration, wenn es ein Ass ist, dann überprüfen Sie explizit für [A, 2,3,4,5]. Wenn es Sie zurück wahr und wenn es nicht ist, dass Sie mit der normalen geraden Logik weiter. Dies sollten Sie in die richtige Richtung gesetzt.

Andere Tipps

Ein guter Ansatz zum Auflösen von Pokerblättern im Allgemeinen besteht darin, jeder Karte einen Bitwert zuzuweisen, wobei sowohl das Bit ((Rang-2)*2) als auch das Bit (Farbe+28) gesetzt sind (also 2=1, 3=4). , 4=16 usw.bis A=0x1000000).Addieren Sie dann alle Karten (nennen Sie das Ergebnis „Summe“).Berechnen Sie V1=(Summe & 0x2AAAAAA)>>1, V0=(Summe & 0x1555555) und V2=V1 & V0.Verknüpfen Sie außerdem die Werte für die fünf Karten mit ODER und berechnen Sie V3=OrValue & 0xF0000000;

  1. Für ein Paar ist bei V1 ein einzelnes Bit gesetzt, bei V0 sind mehrere Bits gesetzt und bei V2 ist Null.
  2. Bei zwei Paaren sind für V1 zwei Bits gesetzt und für V2 ist der Wert Null.
  3. Bei einem Drilling ist in V1 ein einzelnes Bit gesetzt und in V2 ist V1 gleich.
  4. Für eine Gerade ist V0 entweder 0x1000055 oder ein Zweierpotenz-Vielfaches von 0x155.
  5. Für einen Flush ist in V2 genau ein Bit gesetzt.
  6. Für ein Full House sind in V1 zwei Bits gesetzt und in V2 ist ein Wert ungleich Null.
  7. Bei einem Vierling ist entweder V1 doppelt so groß wie v0, wobei beide ein Bit gesetzt haben, oder V0 hat genau zwei gesetzte Bits und V1 ist Null.
  8. Für einen Straight Flush werden die Bedingungen für Straight und Flush erfüllt.

Die für diesen Ansatz erforderlichen Tests sollten schnell und mit minimalem Verzweigungsaufwand umsetzbar sein.

Sie könnten einen Phantasie-Algorithmus schreiben trotz der Anzahl der möglichen Karten zurückgeben wahr, aber wenn Sie es realisieren sind nur 10 gültige Kombinationen auf einer sortierten Hand, können Sie nur für diese aussehen:

2-6, 3-7, 4-8, 5-9, 6-T, 7-J, 8-Q, 9-K, T-A, (2-5,A)

Da es nur 5 Karten in Ihnen Liste ist, können Sie es sortieren und die Differenz zwischen zwei aufeinanderfolgenden Karten bestimmen. Wenn es ein Ass enthält, müssen Sie es als eine niedrige Karte zu betrachten. wenn alle Differenzen sind 1 (oder -1, auf der Sortierreihenfolge abhängig), haben Sie Ihre gerade.

Ich würde, dass diese Definition von RANK gegeben argumentieren, dass Straights nur mit einem Maximum von ACE.points () beginnen -. 4

Also, wenn Sie Ihre Hand sortieren und die niedrigste Ebene> ACE.points () - 4, dann können Sie nicht gerade haben, sonst nur Sie über die Hand laufen zu sehen, dass jede Karte vorheriger RANK ist + 1

Wenn ACE hoch oder niedrig sein kann dann mit dem, was SHS beantwortet.

Mit einer inneren Schleife es ziemlich trivial ist, würde die Herausforderung sein, es zu tun, ohne eine innere Schleife ...

Auch hängt es davon ab, ob Sie Ihren Lehrer oder Ihre Lehrer falsch verstanden (oder falsch dargestellt), um die Regeln des Spiels zu verstehen.

Ich glaube, ich versucht sein, würde nur ein Array erstellen [2..14] und legen Sie die Karten in der Lage, die ihren Rang entspricht. Wenn Sie ein Duplikat getroffen, es ist nicht eine gerade, und wenn Sie fertig sind, sollten Sie 8 Leerzeichen in einer Reihe haben. Wenn Sie weniger als 8 Felder in einer Reihe, es ist nicht ein gerade.

Alle anderen Lösungen, die ich mit oben kommen kann erfordern eine innere Schleife - und inneren Schleifen sind eine jener schlampig Programmierung Dinge, die Sie vermeiden müssen, wenn Sie können, wenn Sie ein anständiger Programmierer jemals sein werden

edit: Auch wenn Sie die Lehrer und die einzigen Umwicklungszustand falsch verstanden wird „10, j, q, k, a“ (wie in den realen Regeln), dann müssen Sie einen zusätzlichen Test, dass, wenn alle 2, 13 und 14 gesetzt sind, ist es auch ein Fehler (2-ak Wraparound).

(Edited wieder 1 mit 14 für ace zu ersetzen, nachdem Re-Lektüre der Frage)

Ich benutze nicht Enum viel, ich benannte Konstanten bevorzugen aber ich werde von „ACE“ Annehmen, dass Sie auf „14“ ist trivial

ich bin zu faul, echten Java-Code zu schreiben (neben Sie tatsächlich Ihre Hausaufgaben zu tun haben ^^)

check if the list has 5 cards
convert card names to a card number list named array
sort the list array
for i=1 to 4
if not (array[i] + 1) % 13 == (array[i+1]) % 13
then it is not a straight

Der Operator% wird so genannt, Modulo (15% 13) == 2 Ich benutze diesen Operator, wenn ich die „wrap über“ Herausforderung

Edit: Nach dem erneuten Lektüre Ihrer Frage meiner Lösung kann nicht aus dem Kasten heraus arbeiten. Sie sollten Ihre Enum, so dass zwei == 0

Nachbestellung

Ich empfehle einen Bitvektor mit den Karten darzustellen. Dadurch wird vermieden, sortieren zu müssen. Sie können das Ass zweimal hinzufügen (einmal als 1 die anderen Zeiten als König) oder Sie kann Sonderfall die Ausgangssituation durch Prüfen, ob das Ass Bit vor der Kontrolle gesetzt, wenn die 2 gesetzt ist). Sie können eine große Verweistabelle, wenn die Geschwindigkeit Dinge bauen. Dieser Ansatz auch Skalen Reinigung den Rest der Hände zu finden (Wallungen, 2 Paar, volle Häuser, Ausflüge, usw.). Es macht es auch einfach, wenn eine gegebene gerade herauszufinden, höher ist als eine andere. Und es erweitert sauber zu 7 Card Auswerter

In Pseudo-Code, um es so etwas wie dies für einen sehr allgemeinen Fall sieht (Sie eine beliebige Anzahl von Karten haben können. Es gibt die erste gerade)

 long cardBitMask
 for each card in hand
   setBit in cardBitMask

 hearts = mask(cardBitMask)
 diamonds = mask(cardBitMask)
 clubs = mask(cardBitMask)
 spades = mask(cardBitMask)

 // find straight
 uniqueCards = hearts|diamonds|clubs|spades
 int cardsInaRow = 0
 if uniqueCards&AceCardMask:
    cardsInaRow = 1
 for card = 2...King
   if uniqueCards&(1<<card)
      cardsInARow++
   else 
      if cardsInARow == 5
         break
      cardsInARow = 0
 if cardsInARow==5:
     return true
 return false

Fügen Sie alle Reihen, um eine Liste, zweimal. Dann zu überprüfen, ob eine Hand ein gerade ist, die Hand nach Rang sortieren und dann prüfen, ob die Hand ist eine Unterliste von dieser Liste.

Sie könnten eine Klasse schreiben, die jede Karte zu einem bestimmten Kartenwert umwandelt

Joker = 11 Königin = 12 König = 13 Ace = 0 oder 14

es wird viel einfache Karte Handhabung machen und sucht nach möglichen Händen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top