I have tried to write a small part of a Poker game to check the Poker hand rankings. Please review and provide your feedback.
package com.sa.test.conditions.poker;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
class Hand {
Card[] cards;
public Card[] getCards() {
return cards;
}
public void setCards(Card[] cards) {
this.cards = cards;
Arrays.sort(cards);
}
public void printHand() {
for (Card card : cards) {
System.out.print(card.suite + " => ");
System.out.println(card.rank);
}
}
public HandType getType() {
if (isAllFromSameSuite()) {
if (isARoyalFlush()) {
return HandType.ROYAL_FLUSH;
}
if (cardsInSequence()) {
return HandType.STRAIGHT_FLUSH;
}
if (!cardsInSequence()) {
return HandType.FLUSH;
}
}
if (hasNumberOfCardsEqualToN(4)) {
return HandType.FOUR_OF_A_KIND;
}
if (hasNumberOfCardsEqualToN(3) && hasNumberOfCardsEqualToN(2)) {
return HandType.FULL_HOUSE;
}
if (!isAllFromSameSuite() && cardsInSequence()) {
return HandType.STRAIGHT;
}
if (hasNumberOfCardsEqualToN(3)) {
return HandType.THREE_OF_A_KIND;
}
if (hasTotalPairsEqualToN(2)) {
return HandType.TWO_PAIR;
}
if (hasTotalPairsEqualToN(1)) {
return HandType.PAIR;
}
return HandType.HIGH_CARD;
}
private boolean isARoyalFlush() {
int royal = 10;
for (Card card : cards) {
if (card.getRank() < royal && card.getRank() != 1) {
return false;
}
}
// System.out.println("ALl isRoyalFlush");
return true;
}
// This method will check the distance between the cards.. whole purpose is
// to check of cards are in sequence either forward or backward.
private boolean cardsInSequence() {
int maxDiff = 1;
Card tmpCard = null;
for (Card card : cards) {
if (tmpCard != null) {
// check the difference based on the value of rank
int diff = Math.abs(tmpCard.getRank() - card.getRank());
if (diff > maxDiff) {
return false;
}
}
tmpCard = card;
}
return true;
}
private boolean isAllFromSameSuite() {
Card tmpCard = null;
for (Card card : cards) {
if (tmpCard != null && !tmpCard.getSuite().equals(card.getSuite())) {
return false;
}
tmpCard = card;
}
return true;
}
private boolean hasNumberOfCardsEqualToN(int number) {
Map<Integer, Integer> ranksMap = getCardRankCountMap();
for (Map.Entry<Integer, Integer> entry : ranksMap.entrySet()) {
if (entry.getValue() == number) {
return true;
}
}
return false;
}
private boolean hasTotalPairsEqualToN(int numberOfPair) {
Card tmpCard = null;
int pairCount = 0;
for (Card card : cards) {
// increment the count if any sibling card matches based on rank
// which are making a pair.
if (tmpCard != null && (tmpCard.getRank() == card.getRank())) {
pairCount = pairCount + 1;
}
tmpCard = card;
}
// check if count matches the n
if (pairCount == numberOfPair)
return true;
return false;
}
private Map<Integer, Integer> getCardRankCountMap() {
Map<Integer, Integer> ranksMap = new HashMap<Integer, Integer>();
for (Card card : cards) {
if (ranksMap.containsKey(card.getRank())) {
int rank = card.getRank();
int count = ranksMap.get(rank);
ranksMap.put(rank, count + 1);
} else {
ranksMap.put(card.getRank(), 1);
}
}
return ranksMap;
}
}
Suite
(pronounced "sweet") is the wrong spelling. It should beSuit
(pronounced "soot"). \$\endgroup\$if (hasNumberOfCardsEqualToN(3) && hasNumberOfCardsEqualToN(2)) {
. You should probably have something likehasNumberOfCardsEqualToN(3, 2)
. \$\endgroup\$Comparable
. This way, someone using your code can simply usecompareTo
to compare hands. Example on Stack Overflow (see the response from gdejohn). \$\endgroup\$