地址:https://www.codewars.com/kata/5739174624fc28e188000465/java
总结:不好写,各种牌的可能的情况都要考虑到,同种牌型之间还需要比较牌的大小。
package codewar;
import java.util.*;
import java.util.stream.Collectors;
// https://www.codewars.com/kata/5739174624fc28e188000465/train/java
public class PokerHand {
static char[] CARDS = new char[]{'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'};
static Map<Character, Integer> VALUES = new HashMap<>();
static {
int i = 0;
for (char c : CARDS) {
VALUES.put(c, i++);
}
}
static char[] SUITS = new char[]{'S', 'H', 'D', 'C'};
public enum Result {TIE, WIN, LOSS}
Set<String> cards;
Map<Character, Integer> cardCount = new HashMap<>();
List<Integer> value = new ArrayList<>();
PokerHand(String hand) {
this.cards = new HashSet<>(Arrays.asList(hand.split(" ")));
cards.forEach(a -> {
cardCount.put(a.charAt(0), 1 + cardCount.getOrDefault(a.charAt(0), 0));
});
computeValue();
}
public Result compareWith(PokerHand hand) {
int len = Math.min(hand.value.size(), value.size());
for (int i = 0; i < len; i++) {
if (value.get(i) > hand.value.get(i)) {
return Result.WIN;
}
if (value.get(i) < hand.value.get(i)) {
return Result.LOSS;
}
}
return Result.TIE;
}
public void computeValue() {
if (royalFlush()) {
value.add(10);
} else if (straightFlush()) {
value.add(9);
value.addAll(cardValueWithNumber(1));
} else if (fourOfKind()) {
value.add(8);
value.addAll(cardValueWithNumber(4));
value.addAll(cardValueWithNumber(1));
} else if (fullHouse()) {
value.add(7);
value.addAll(cardValueWithNumber(3));
value.addAll(cardValueWithNumber(2));
} else if (flush()) {
value.add(6);
value.addAll(cardValueWithNumber(1));
} else if (straight()) {
value.add(5);
value.addAll(cardValueWithNumber(1));
} else if (threeOfKind()) {
value.add(4);
value.addAll(cardValueWithNumber(3));
value.addAll(cardValueWithNumber(1));
} else if (twoPair()) {
value.add(3);
value.addAll(cardValueWithNumber(2));
value.addAll(cardValueWithNumber(1));
} else if (onePair()) {
value.add(2);
value.addAll(cardValueWithNumber(2));
value.addAll(cardValueWithNumber(1));
} else {
value.add(1);
value.addAll(cardValueWithNumber(1));
}
}
List<Character> exactNumberOfCard(int n) {
List<Character> result = new ArrayList<>();
for (char card : cardCount.keySet()) {
if (cardCount.get(card) == n) {
result.add(card);
}
}
return result;
}
List<Integer> cardValueWithNumber(int number) {
List<Character> cs = exactNumberOfCard(number);
return cs.stream()
.map(c -> VALUES.get(c))
.sorted(Collections.reverseOrder())
.collect(Collectors.toList());
}
boolean containsCard(char card, char suit) {
return cards.contains(card + "" + suit);
}
boolean containsCard(char card) {
for (char suit : SUITS) {
if (cards.contains(card + "" + suit)) {
return true;
}
}
return false;
}
boolean royalFlush() {
for (char suit : SUITS) {
char[] C = {'A', 'K', 'Q', 'J', 'T'};
int cnt = 0;
for (char c : C) {
if (containsCard(c, suit)) {
cnt += 1;
} else {
break;
}
}
if (cnt == 5) {
return true;
}
}
return false;
}
boolean straightFlush() {
for (char suit : SUITS) {
int i = 0;
while (i < CARDS.length) {
while (i < CARDS.length && !containsCard(CARDS[i], suit)) {
i++;
}
int cnt = 0;
int tmp = i;
i += 1;
while (tmp < CARDS.length && containsCard(CARDS[tmp], suit)) {
cnt += 1;
tmp += 1;
}
if (cnt == 5) {
return true;
}
}
}
return false;
}
// contains the number of card with same suit
boolean numberOfKind(int n) {
return cardCount.containsValue(n);
}
boolean fourOfKind() {
return numberOfKind(4);
}
boolean fullHouse() {
return numberOfKind(3) && numberOfKind(2);
}
boolean flush() {
for (char suit : SUITS) {
int cnt = 0;
for (char card : cardCount.keySet()) {
if (containsCard(card, suit)) {
cnt += 1;
}
}
if (cnt == 5) {
return true;
}
}
return false;
}
boolean straight() {
int i = 0;
while (i < CARDS.length) {
while (i < CARDS.length && !containsCard(CARDS[i])) {
i += 1;
}
int tmp = i;
i += 1;
int cnt = 0;
while (tmp < CARDS.length && containsCard(CARDS[tmp])) {
cnt += 1;
tmp += 1;
}
if (cnt == 5) {
return true;
}
}
return false;
}
boolean threeOfKind() {
return numberOfKind(3) && exactNumberOfCard(1).size() == 2;
}
boolean twoPair() {
return exactNumberOfCard(2).size() == 2 && exactNumberOfCard(1).size() == 1;
}
boolean onePair() {
return exactNumberOfCard(2).size() == 1 && exactNumberOfCard(1).size() == 3;
}
}
来源:oschina
链接:https://my.oschina.net/reter/blog/3290920