Question

Pour un devoir à la maison m'a donné une classe de carte qui a énuméré types pour le rang et la couleur. Je suis obligé de comparer deux mains de poker (chaque main est un ArrayList de 5 cartes) et décider du vainqueur.

La fonction isStraight() me tracasse vraiment, parce que je dois recommencer le décompte après l'As. Par exemple,

QUEEN, ROI, ACE, DEUX, TROIS

est toujours considéré comme un droit. Quelle est la meilleure façon de coder cette fonctionnalité?

Voici le code de type énuméré Grade / Costume habillé, si cela aide.

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;
}
Était-ce utile?

La solution

Vous vous rendez compte que les règles de tout jeu de poker que j'ai jamais joué ou entendu parler d'un droit ne peut pas envelopper droite? As peut être faible [A, 2,3,4,5] ou élevée [10, J, Q, K, A], mais il ne peut pas envelopper. Selon ces règles (pas le vôtre) J'ai mis quelque chose de semblable auparavant. Fondamentalement, vous trier le tableau et aller à pied, en vous assurant de la carte actuelle est un plus élevé que le précédent. Dans la première itération, si elle est un as, vous vérifiez explicitement [A, 2,3,4,5]. S'il est vrai que vous revenez et si ce n'est pas vous continuez avec la logique normale droite. Cela devrait vous mettre dans la bonne direction.

Autres conseils

Une approche agréable pour résoudre les mains de poker en général est d'attribuer à chaque carte une valeur binaire avec le bit ((rang 2) * 2) bit set ainsi que bit (costume + 28) ensemble, (donc 2 = 1, 3 = 4, 4 = 16, etc. jusqu'à A = 0x1000000). Puis additionner toutes les cartes (appel à ce résultat 'Somme'. Compute V1 = (Somme & 0x2AAAAAA) >> 1, V0 = (Somme & 0x1555555) et V2 = V1 et V0. De plus ou ensemble les valeurs des cinq cartes et calculer V3 = OrValue & 0xF0000000;

  1. Pour une paire, V1 aura un ensemble unique de bits, V0 aura plusieurs bits définis et V2 sera égal à zéro.
  2. Pour deux paires, V1 aura deux bits fixés et V2 sera égal à zéro.
  3. Pour trois de son genre, V1 aura un ensemble unique bit et V2 sera égale à V1.
  4. Pour un droit, sera soit V0 0x1000055 ou bien une puissance de deux enfants de multiples 0x155.
  5. Pour une chasse d'eau, V2 aura précisément un bit.
  6. Pour une maison pleine, V1 aura deux bits réglés et V2 sera non nulle.
  7. Pour quatre d'une sorte, V1 sera deux fois v0, avec les deux ayant un bit ou V0 auront exactement deux bits positionnés et V1 seront nuls.
  8. Pour une quinte flush, les conditions seront atteints quinte et couleur.

tests requis pour cette approche devrait être rapidement implémentable avec une quantité minimale de ramification.

Vous pouvez écrire un algorithme de fantaisie pour revenir vrai malgré le nombre de cartes possibles, mais si vous vous rendez compte il n'y a que 10 combinaisons valides sur une main triée, vous pouvez simplement chercher ces:

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

Comme il n'y a que 5 cartes en vous liste, vous pourriez trier et déterminer la différence entre les 2 cartes consécutives. Si elle contient un as, vous devez le considérer comme une carte faible aussi. si toutes les différences sont 1 (ou -1, selon l'ordre de tri), vous avez votre droit.

Je dirais que, étant donné que la définition de RANK, que les lignes droites ne peuvent commencer par un maximum de ACE.points () -. 4

Donc, si vous triez votre main et le plus bas RANK> ACE.points () - 4 alors vous ne pouvez pas avoir un droit, sinon vous venez d'itérer sur la main pour voir que chaque carte est RANG précédente + 1.

Si ACE peut être élevée ou faible puis aller avec ce que SHS a répondu.

Avec une boucle intérieure il est assez trivial, le défi serait de le faire sans une boucle intérieure ...

En outre, cela dépend si vous avez compris votre professeur ou votre incompris des enseignants (ou déformé) les règles du jeu.

Je pense que je serais tenté de créer simplement un tableau [2..14] et placez les cartes dans l'emplacement qui correspond à leur rang. Si vous frappez un double, ce n'est pas un droit, et quand vous avez terminé, vous devriez avoir 8 places dans une rangée. Si vous avez moins de 8 places dans une rangée, ce n'est pas un droit.

Toutes les autres solutions que je peux venir avec besoin d'une boucle interne - et boucles internes sont une de ces choses de programmation bâclée vous devez éviter chaque fois que vous pouvez si vous allez jamais être un programmeur respectable

edit: Aussi, si vous avez mal compris l'enseignant et la seule condition d'emballage est « 10, j, q, k, un » (comme dans les vraies règles), alors vous avez besoin d'un test supplémentaire que si tous 2, 13 et 14 sont réglés, il est aussi un échec (enveloppant 2-ak).

(Sous la direction de nouveau pour remplacer 1 à 14 avec ace après re-lecture de la question)

Je n'utiliser ENUM beaucoup, je préfère des constantes nommées mais je vais supposer allant de « ACE » à « 14 » est trivial

Je suis trop paresseux pour écrire vrai code java (à côté vous avez réellement à faire vos devoirs ^^)

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

L'opérateur% est appelé modulo de sorte (15% 13) == 2 J'utilise cet opérateur chaque fois que je fais face au défi « envelopper sur »

Edit: Après la relecture de votre question ma solution ne peut pas fonctionner hors de la boîte. Vous devez réorganiser votre ENUM de sorte que deux == 0

Je recommande d'utiliser un vecteur de bits pour représenter les cartes. Cela évite d'avoir à trier. Vous pouvez ajouter l'as deux fois (une fois en 1, les autres fois comme un roi) ou vous pouvez cas particulier la situation de départ en vérifiant si le bit est réglé avant ace vérifier si le 2 est réglé). Vous pouvez construire une grande table de consultation si les questions de vitesse. Cette approche aussi le nettoyage des échelles pour trouver le reste des mains (2, Bouffées paire, maisons pleines, voyages, etc.). Il rend également facile à comprendre si une droite donnée est supérieure à une autre. Et il se développe proprement à 7 évaluateur de cartes

Dans le code pseudo, il ressemble à ceci pour un cas très général (vous pouvez avoir un certain nombre de cartes. Il retourne la première ligne droite)

 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

Ajoutez tous les rangs pour une liste, deux fois. Ensuite, pour vérifier si une main est un droit, trier la main par rang puis vérifier si la main est une sous-liste de cette liste.

vous pouvez écrire une classe qui convertit toutes les cartes à une valeur de carte spécifique

Joker = 11 Reine = 12 Roi = 13 Ace = 0 ou 14

il fera beaucoup plus facile la manipulation de la carte et la recherche de mains possibles.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top