summaryrefslogtreecommitdiff
path: root/Game.java
diff options
context:
space:
mode:
authorMichael Hunteman <michael@huntm.net>2022-11-22 14:07:43 -0600
committerMichael Hunteman <michael@huntm.net>2022-11-22 14:07:43 -0600
commit7ff5e12124aebe9255c7962ce6eb0ef49ceea9c1 (patch)
tree9ea31987bb6dd64c3d66e38ccbb5dc56a8fcdecf /Game.java
Initial commit
Diffstat (limited to 'Game.java')
-rw-r--r--Game.java364
1 files changed, 364 insertions, 0 deletions
diff --git a/Game.java b/Game.java
new file mode 100644
index 0000000..8959282
--- /dev/null
+++ b/Game.java
@@ -0,0 +1,364 @@
+import java.util.*;
+import card.*;
+
+class Game {
+ private List<Card> deck = new ArrayList<>();
+ private List<List<Card>> hands = new ArrayList<>();
+ private List<Integer> ranks = new ArrayList<>();
+
+ public Game() {
+ setDeck();
+ }
+
+ public Game(int handsNum) {
+ setDeck();
+ for (int i = 0; i < handsNum; i++) {
+ hands.add(setHand());
+ ranks.add(getRank(hands.get(i)));
+ }
+ }
+
+ public void setHands(List<List<Card>> hands) {
+ this.hands = hands;
+ }
+
+ public void setRanks(List<Integer> ranks) {
+ this.ranks = ranks;
+ }
+
+ public void setDeck() {
+ Suit s = Suit.CLUBS;
+ for (int i = 0; i < 4; i++) {
+ switch (i) {
+ case 0:
+ s = Suit.CLUBS;
+ break;
+ case 1:
+ s = Suit.DIAMONDS;
+ break;
+ case 2:
+ s = Suit.HEARTS;
+ break;
+ case 3:
+ s = Suit.SPADES;
+ break;
+ }
+ for (int j = 1; j <= 13; j++) {
+ Card card = new Card(j, s);
+ deck.add(card);
+ }
+ }
+ }
+
+ public List<Card> sort(List<Card> hand) {
+ if (hand.size() <= 1)
+ return hand;
+ int mid = hand.size() / 2;
+ List<Card> left = sort(hand.subList(0, mid));
+ List<Card> right = sort(hand.subList(mid, hand.size()));
+ return merge(left, right);
+ }
+
+ public List<Card> merge(List<Card> left, List<Card> right) {
+ List<Card> result = new ArrayList<>();
+ int l = 0, r = 0;
+ while (l < left.size() || r < right.size()) {
+ if (l < left.size() && (r == right.size()
+ || left.get(l).getValue() < right.get(r).getValue() )) {
+ result.add(left.get(l));
+ l++;
+ } else {
+ result.add(right.get(r));
+ r++;
+ }
+ }
+ return result;
+ }
+
+ public List<Card> setHand() {
+ List<Card> hand = new ArrayList<>();
+ Random rand = new Random();
+ for (int i = 0; i < 5; i++) {
+ int randInt = rand.nextInt(deck.size());
+ hand.add(deck.get(randInt));
+ deck.remove(randInt);
+ }
+ return sort(hand);
+ }
+
+ public void getHand(List<Card> hand) {
+ for (Card c : hand) {
+ System.out.println(c.displayCard());
+ }
+ }
+
+ public int getRank(List<Card> hand) {
+ if (isRoyalFlush(hand)) {
+ return 9;
+ } else if (isStraightFlush(hand)) {
+ return 8;
+ } else if (isFourOfKind(hand)) {
+ return 7;
+ } else if (isFullHouse(hand)) {
+ return 6;
+ } else if (isFlush(hand)) {
+ return 5;
+ } else if (isStraight(hand)) {
+ return 4;
+ } else if (isThreeOfKind(hand)) {
+ return 3;
+ } else if (isTwoPair(hand)) {
+ return 2;
+ } else if (isPair(hand)) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
+ public void displayRank(List<Card> hand, int rank) {
+ switch (rank) {
+ case 8:
+ System.out.println("Straight flush");
+ break;
+ case 7:
+ System.out.println("Four of a kind");
+ break;
+ case 6:
+ System.out.println("Full house");
+ break;
+ case 5:
+ System.out.println("Flush");
+ break;
+ case 4:
+ System.out.println("Straight");
+ break;
+ case 3:
+ System.out.println("Three of a kind");
+ break;
+ case 2:
+ System.out.println("Two pair");
+ break;
+ case 1:
+ System.out.println("Pair");
+ break;
+ default:
+ System.out.println("High card " + highCard(hand));
+ }
+ }
+
+ public String highCard(List<Card> hand) {
+ if (hand.get(0).getValue() == 1)
+ return hand.get(0).displayCard();
+ return hand.get(hand.size() - 1).displayCard();
+ }
+
+ public boolean isPair(List<Card> hand) {
+ boolean pair = false;
+ for (int i = 0; i < hand.size() - 1; i++)
+ pair = pair || (hand.get(i).getValue() == hand.get(i + 1).getValue());
+ return pair;
+ }
+
+ public boolean isTwoPair(List<Card> hand) {
+ int numberOfPairs = 0;
+ int i = 0;
+ while (i < hand.size() - 1) {
+ if (isPair(hand.subList(i, i + 2))) {
+ numberOfPairs++;
+ i += 2;
+ } else {
+ i++;
+ }
+ }
+ return numberOfPairs == 2;
+ }
+
+ public boolean isThreeOfKind(List<Card> hand) {
+ boolean threeOfKind = false;
+ for (int i = 0; i < hand.size() - 2; i++)
+ threeOfKind = threeOfKind
+ || (hand.get(i).getValue() == hand.get(i + 2).getValue());
+ return threeOfKind;
+ }
+
+ // TODO: ace high straight
+ public boolean isStraight(List<Card> hand) {
+ int prev = hand.get(0).getValue();
+ int count = 0;
+ for (int i = 1; i < hand.size() && count < 4; i++) {
+ if (hand.get(i).getValue() - prev == 1) {
+ count++;
+ } else {
+ count = 0;
+ }
+ prev = hand.get(i).getValue();
+ }
+ return count == 4;
+ }
+
+ public boolean isFlush(List<Card> hand) {
+ boolean flush = true;
+ Suit suit = hand.get(0).getSuit();
+ for (int i = 1; i < hand.size(); i++)
+ flush = flush && (hand.get(i).getSuit() == suit);
+ return flush;
+ }
+
+ public boolean isFullHouse(List<Card> hand) {
+ boolean pairThreeOfKind = false;
+ boolean threeOfKindPair = false;
+
+ for (int i = 0; i < hand.size() - 4; i++)
+ pairThreeOfKind = (hand.get(i).getValue() == hand.get(i + 1).getValue())
+ && (hand.get(i + 2).getValue() == hand.get(i + 4).getValue());
+
+ for (int i = 0; i < hand.size() - 4; i++)
+ threeOfKindPair = (hand.get(i).getValue() == hand.get(i + 2).getValue())
+ && (hand.get(i + 3).getValue() == hand.get(i + 4).getValue());
+
+ return pairThreeOfKind || threeOfKindPair;
+ }
+
+ public boolean isFourOfKind(List<Card> hand) {
+ boolean fourOfKind = false;
+ for (int i = 0; i < hand.size() - 3; i++)
+ fourOfKind = fourOfKind
+ || (hand.get(i).getValue() == hand.get(i + 3).getValue());
+ return fourOfKind;
+ }
+
+ public boolean isStraightFlush(List<Card> hand) {
+ return isStraight(hand) && isFlush(hand);
+ }
+
+ // TODO: check A-10
+ public boolean isRoyalFlush(List<Card> hand) {
+ return isFlush(hand) && hand.get(0).getValue() == 1
+ && hand.get(1).getValue() == 10 && hand.get(4).getValue() == 13;
+ }
+
+ public boolean compareHighCard(List<Card> firstHand, List<Card> secondHand) {
+ if (firstHand.get(0).getValue() == 1) {
+ return true;
+ } else if (secondHand.get(0).getValue() == 1) {
+ return false;
+ }
+ for (int j = firstHand.size() - 1; j > 0; j--) {
+ if (firstHand.get(j).getValue()
+ > secondHand.get(j).getValue()) {
+ return true;
+ } else if (secondHand.get(j).getValue()
+ > firstHand.get(j).getValue()) {
+ return false;
+ }
+ }
+ return false;
+ }
+
+ public boolean comparePair(List<Card> firstHand, List<Card> secondHand) {
+ Set<Integer> temp = new HashSet<>();
+ int high = firstHand.get(0).getValue();
+ for (int i = 1; i < firstHand.size(); i++) {
+ Card c = firstHand.get(i);
+ if (temp.contains(c.getValue())) {
+ high = c.getValue();
+ } else {
+ temp.add(c.getValue());
+ }
+ }
+ temp.clear();
+ for (Card c : secondHand) {
+ if (temp.contains(c.getValue())) {
+ if (high > c.getValue())
+ return true;
+ } else {
+ temp.add(c.getValue());
+ }
+ }
+ return false;
+ }
+
+ // TODO: combine with comparePair and compareThreeOfKind
+ public boolean compareTwoPair(List<Card> firstHand, List<Card> secondHand) {
+ Set<Integer> temp = new HashSet<>();
+ int high = firstHand.get(0).getValue();
+ for (int i = 1; i < firstHand.size(); i++) {
+ Card c = firstHand.get(i);
+ if (temp.contains(c.getValue()) && c.getValue() > high) {
+ high = c.getValue();
+ } else {
+ temp.add(c.getValue());
+ }
+ }
+ temp.clear();
+ int greater = 0;
+ for (Card c : secondHand) {
+ if (temp.contains(c.getValue()) && high > c.getValue()) {
+ greater++;
+ } else {
+ temp.add(c.getValue());
+ }
+ }
+ return greater >= 2;
+ }
+
+ public int getWinner() {
+ int bestHand = 0, bestRank = 0;
+ for (int i = 0; i < ranks.size(); i++) {
+ if (ranks.get(i) > bestRank) {
+ bestHand = i;
+ bestRank = ranks.get(i);
+ } else if (ranks.get(i) == bestRank) {
+ switch (bestRank) {
+ case 7:
+ if (compareTwoPair(hands.get(i), hands.get(bestHand))) {
+ bestHand = i;
+ bestRank = ranks.get(i);
+ }
+ break;
+ case 6:
+ if (compareTwoPair(hands.get(i), hands.get(bestHand))) {
+ bestHand = i;
+ bestRank = ranks.get(i);
+ }
+ break;
+ case 3:
+ if (compareTwoPair(hands.get(i), hands.get(bestHand))) {
+ bestHand = i;
+ bestRank = ranks.get(i);
+ }
+ break;
+ case 2:
+ if (compareTwoPair(hands.get(i), hands.get(bestHand))) {
+ bestHand = i;
+ bestRank = ranks.get(i);
+ }
+ break;
+ case 1:
+ if (comparePair(hands.get(i), hands.get(bestHand))) {
+ bestHand = i;
+ bestRank = ranks.get(i);
+ }
+ break;
+ case 0:
+ if (compareHighCard(hands.get(i), hands.get(bestHand))) {
+ bestHand = i;
+ bestRank = ranks.get(i);
+ }
+ }
+ }
+ }
+ return bestHand;
+ }
+
+ public static void main(String args[]) {
+ Game g = new Game(10);
+ for (int i = 0; i < g.hands.size(); i++) {
+ g.getHand(g.hands.get(i));
+ g.displayRank(g.hands.get(i), g.ranks.get(i));
+ System.out.println();
+ }
+ System.out.println(g.getWinner());
+ }
+}