2
\$\begingroup\$

I'm trying to make a poker game, but right now my code - to me - looks way too crowded, and I can't seem to find anything to shorten it and make it look cleaner. Because of that, I came here to see if anyone else has better luck finding places where my code can condense.
Here's the code:

import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public class PlayGame {

    private Display display;

    public PlayGame() {
        makeCards();
        display = new Display("Best poker game ever!", 1000, 750);
    }

    private int p1money = 100, p2money = 100, p3money = 100, p4money = 100, p5money = 100, potSize = 0;

    private BufferStrategy bs;
    private Graphics g;

    private ArrayList<String> cards = new ArrayList<String>();

    private void makeCards() {
        // spades
        cards.add("Ace of spades");
        cards.add("Jack of spades");
        cards.add("Queen of spades");
        cards.add("King of spades");
        int spade = 2;
        while(spade <= 10) {
            cards.add(spade + " of spades");
            spade++;
        }
        // hearts
        cards.add("Ace of hearts");
        cards.add("Jack of hearts");
        cards.add("Queen of hearts");
        cards.add("King of hearts");
        int heart = 2;
        while(heart <= 10) {
            cards.add(heart + " of hearts");
            heart++;
        }
        // dims
        cards.add("Ace of diamonds");
        cards.add("Jack of diamonds");
        cards.add("Queen of diamonds");
        cards.add("King of diamonds");
        int dim = 2;
        while(dim <= 10) {
            cards.add(dim + " of diamonds");
            dim++;
        }
        // clubs
        cards.add("Ace of clubs");
        cards.add("Jack of clubs");
        cards.add("Queen of clubs");
        cards.add("King of clubs");
        int club = 2;
        while(club <= 10) {
            cards.add(club + " of clubs");
            club++;
        }
        System.out.println(cards);
    }

    private void dealHands() {
        Collections.shuffle(cards);
        List<String> p1hand = cards.subList(0, 2);
        List<String> p2hand = cards.subList(2, 4);
        List<String> p3hand = cards.subList(4, 6);
        List<String> p4hand = cards.subList(6, 8);
        List<String> p5hand = cards.subList(8, 10);
        System.out.println("Player 1's hand is " + p1hand);
        System.out.println("Player 2's hand is " + p2hand);
        System.out.println("Player 3's hand is " + p3hand);
        System.out.println("Player 4's hand is " + p4hand);
        System.out.println("Player 5's hand is " + p5hand);
    }

    private void testBid() {
        Scanner scanner = new Scanner(System.in);
        int pot = potSize;
        // p1
        System.out.println("Player 1: bid? (true/false)");
        int p1bidAmount = 0;
        boolean p1bid = scanner.nextBoolean();
        if(p1bid) {
            System.out.println("How much?");
            p1bidAmount = scanner.nextInt();
            if(p1bidAmount > p1money) {
                System.out.println("You do not have that much money. You now have $0 and the pot is worth $" + (pot + p1money));
                p1money = 0;
                potSize += p1money;
                return;
            }
            potSize += p1bidAmount;
            p1money -= p1bidAmount;
            System.out.println("The pot is now worth $" + potSize + ". Player 1 now has $" + p1money + " in their hand.");
        }
        // p2
        System.out.println("Player 2: bid? (true/false)");
        boolean p2bid = scanner.nextBoolean();
        int p2bidAmount = 0;
        if(p2bid) {
            System.out.println("How much?");
            p2bidAmount = scanner.nextInt();
            if(p2bidAmount > p2money) {
                System.out.println("You do not have that much money. You now have $0 and the pot is worth $" + (pot + p2money));
                p2money = 0;
                potSize += p2money;
                return;
            }
            potSize += p2bidAmount;
            p2money -= p2bidAmount;
            System.out.println("The pot is now worth $" + potSize + ". Player 2 now has $" + p2money + " in their hand.");
        }
        if(p1bid && p2bidAmount < p1bidAmount) {
            System.out.println("Your bid amount was less than what p1 bidded, now your bid amount is $" + p1bidAmount + " because of that.");
            p2bidAmount = p1bidAmount;
            if(p2money >= p2bidAmount)
                p2money -= p2bidAmount;
            else {
                p2money = 0;
            }
        }
        // p3
        System.out.println("Player 3: bid? (true/false)");
        boolean p3bid = scanner.nextBoolean();
        int p3bidAmount = 0;
        if(p3bid) {
            System.out.println("How much?");
            p3bidAmount = scanner.nextInt();
            if(p3bidAmount > p3money) {
                System.out.println("You do not have that much money. You now have $0 and the pot is worth $" + (pot + p3money));
                p3money = 0;
                potSize += p3money;
                return;
            }
            potSize += p3bidAmount;
            p3money -= p3bidAmount;
            System.out.println("The pot is now worth $" + potSize + ". Player 3 now has $" + p3money + " in their hand.");
        }
        if(p1bid && p3bidAmount < p1bidAmount) {
            System.out.println("Your bid amount was less than what p1 bidded, now your bid amount is $" + p1bidAmount + " because of that.");
            p3bidAmount = p1bidAmount;
            if(p3money >= p3bidAmount)
                p3money -= p3bidAmount;
            else {
                p3money = 0;
            }
        }
        if(p2bid && p3bidAmount < p2bidAmount) {
            System.out.println("Your bid amount was less than what p2 bidded, now your bid amount is $" + p2bidAmount + " because of that.");
            p3bidAmount = p2bidAmount;
            if(p3money >= p3bidAmount)
                p3money -= p3bidAmount;
            else {
                p3money = 0;
            }
        }
        // p4
        System.out.println("Player 4: bid? (true/false)");
        boolean p4bid = scanner.nextBoolean();
        int p4bidAmount = 0;
        if(p4bid) {
            System.out.println("How much?");
            p4bidAmount = scanner.nextInt();
            if(p4bidAmount > p4money) {
                System.out.println("You do not have that much money. You now have $0 and the pot is worth $" + (pot + p4money));
                p4money = 0;
                potSize += p4money;
                return;
            }
            potSize += p4bidAmount;
            p4money -= p4bidAmount;
            System.out.println("The pot is now worth $" + potSize + ". Player 4 now has $" + p4money + " in their hand.");
        }
        if(p1bid && p4bidAmount < p1bidAmount) {
            System.out.println("Your bid amount was less than what p1 bidded, now your bid amount is $" + p1bidAmount + " because of that.");
            p4bidAmount = p1bidAmount;
            if(p4money >= p4bidAmount)
                p4money -= p4bidAmount;
            else {
                p4money = 0;
            }
        }
        if(p2bid && p4bidAmount < p2bidAmount) {
            System.out.println("Your bid amount was less than what p2 bidded, now your bid amount is $" + p2bidAmount + " because of that.");
            p4bidAmount = p2bidAmount;
            if(p4money >= p4bidAmount)
                p4money -= p4bidAmount;
            else {
                p4money = 0;
            }
        }
        if(p3bid && p4bidAmount < p3bidAmount) {
            System.out.println("Your bid amount was less than what p3 bidded, now your bid amount is $" + p3bidAmount + " because of that.");
            p4bidAmount = p3bidAmount;
            if(p4money >= p4bidAmount)
                p4money -= p4bidAmount;
            else {
                p4money = 0;
            }
        }
        // p5
        System.out.println("Player 5: bid? (true/false)");
        boolean p5bid = scanner.nextBoolean();
        int p5bidAmount = 0;
        if(p5bid) {
            System.out.println("How much?");
            p5bidAmount = scanner.nextInt();
            if(p5bidAmount > p5money) {
                System.out.println("You do not have that much money. You now have $0 and the pot is worth $" + (pot + p5money));
                p5money = 0;
                potSize += p5money;
                return;
            }
            potSize += p5bidAmount;
            p5money -= p5bidAmount;
            System.out.println("The pot is now worth $" + potSize + ". Player 5 now has $" + p5money + " in their hand.");
        }
        if(p1bid && p5bidAmount < p1bidAmount) {
            System.out.println("Your bid amount was less than what p1 bidded, now your bid amount is $" + p1bidAmount + " because of that.");
            p5bidAmount = p1bidAmount;
            if(p5money >= p5bidAmount)
                p5money -= p5bidAmount;
            else {
                p5money = 0;
            }
        }
        if(p2bid && p5bidAmount < p2bidAmount) {
            System.out.println("Your bid amount was less than what p2 bidded, now your bid amount is $" + p2bidAmount + " because of that.");
            p5bidAmount = p2bidAmount;
            if(p5money >= p5bidAmount)
                p5money -= p5bidAmount;
            else {
                p5money = 0;
            }
        }
        if(p3bid && p5bidAmount < p3bidAmount) {
            System.out.println("Your bid amount was less than what p3 bidded, now your bid amount is $" + p3bidAmount + " because of that.");
            p5bidAmount = p3bidAmount;
            if(p5money >= p5bidAmount)
                p5money -= p5bidAmount;
            else {
                p5money = 0;
            }
        }
        if(p4bid && p5bidAmount < p4bidAmount) {
            System.out.println("Your bid amount was less than what p4 bidded, now your bid amount is $" + p4bidAmount + " because of that.");
            p5bidAmount = p4bidAmount;
            if(p5money >= p5bidAmount)
                p5money -= p5bidAmount;
            else {
                p5money = 0;
            }
        }
    }

    private void throwCards() {
        testBid();
        List<String> first3Cards = cards.subList(10, 13);
        System.out.println("The first three cards thrown are " + first3Cards);
        try {
            Thread.sleep(2000);
        } catch(InterruptedException e) {
            e.printStackTrace();
        }
        testBid();
        System.out.println("The next card thrown is " + cards.get(13));
        try {
            Thread.sleep(2000);
        } catch(InterruptedException e) {
            e.printStackTrace();
        }
        testBid();
        System.out.println("The final card thrown is " + cards.get(14));
        testBid();
    }

    private void testRoyalFlush(List<String> playerHand, int playerNum, int pMoney) {
        // royal flush
        String[] spadeRoyalFlush = {"Ace of spades", "King of spades", "Queen of spades", "Jack of spades", "10 of spades"};
        String[] heartRoyalFlush = {"Ace of hearts", "King of hearts", "Queen of hearts", "Jack of hearts", "10 of hearts"};
        String[] dimRoyalFlush = {"Ace of diamonds", "King of diamonds", "Queen of diamonds", "Jack of diamonds", "10 of diamonds"};
        String[] clubRoyalFlush = {"Ace of clubs", "King of clubs", "Queen of clubs", "Jack of clubs", "10 of clubs"};
        boolean p1royalFlush = false;
        p1royalFlush = playerHand.containsAll(Arrays.asList(spadeRoyalFlush));
        if(p1royalFlush) {
            System.out.println("Player " + playerNum + " got a royal flush with " + playerHand);
            System.out.println("Player " + playerNum + " now has $" + pMoney);
        }
        p1royalFlush = playerHand.containsAll(Arrays.asList(heartRoyalFlush));
        if(p1royalFlush) {
            System.out.println("Player " + playerNum + " got a royal flush with " + playerHand);
            System.out.println("Player " + playerNum + " now has $" + pMoney);
        }
        p1royalFlush = playerHand.containsAll(Arrays.asList(dimRoyalFlush));
        if(p1royalFlush) {
            System.out.println("Player " + playerNum + " got a royal flush with " + playerHand);
            System.out.println("Player " + playerNum + " now has $" + pMoney);
        }
        p1royalFlush = playerHand.containsAll(Arrays.asList(clubRoyalFlush));
        if(p1royalFlush) {
            System.out.println("Player " + playerNum + " got a royal flush with " + playerHand);
            System.out.println("Player " + playerNum + " now has $" + pMoney);
        }
    }

    private void findWinner() {
        // p1 hand
        List<String> p1hand = new ArrayList<>(cards.subList(10, 15)); // create a new list
        p1hand.addAll(cards.subList(0, 2));
        System.out.println("Player 1's total hand is " + p1hand);
        System.out.println("Player 1 has $" + p1money);
        // p2 hand
        List<String> p2hand = new ArrayList<>(cards.subList(10, 15)); // create a new list
        p2hand.addAll(cards.subList(2, 4));
        System.out.println("Player 2's total hand is " + p2hand);
        System.out.println("Player 2 has $" + p2money);
        // p3 hand
        List<String> p3hand = new ArrayList<>(cards.subList(10, 15)); // create a new list
        p3hand.addAll(cards.subList(4, 6));
        System.out.println("Player 3's total hand is " + p3hand);
        System.out.println("Player 3 has $" + p3money);
        // p4 hand
        List<String> p4hand = new ArrayList<>(cards.subList(10, 15)); // create a new list
        p4hand.addAll(cards.subList(6, 8));
        System.out.println("Player 4's total hand is " + p4hand);
        System.out.println("Player 4 has $" + p4money);
        List<String> p5hand = new ArrayList<>(cards.subList(10, 15)); // create a new list
        p5hand.addAll(cards.subList(8, 10));
        System.out.println("Player 5's total hand is " + p5hand);
        System.out.println("Player 5 has $" + p5money);

        // p1
        testRoyalFlush(p1hand, 1, p1money);

        // p2
        testRoyalFlush(p2hand, 2, p2money);

        // p3
        testRoyalFlush(p3hand, 3, p3money);

        // p4
        testRoyalFlush(p4hand, 4, p4money);

        // p5
        testRoyalFlush(p5hand, 5, p5money);

        // straight flush
        // spades
        String[] spadeA5 = {"Ace of spades", "2 of spades", "3 of spades", "4 of spades", "5 of spades"};
        String[] spade26 = {"2 of spades", "3 of spades", "4 of spades", "5 of spades", "6 of spades"};
        String[] spade37 = {"3 of spades", "4 of spades", "5 of spades", "6 of spades", "7 of spades"};
        String[] spade48 = {"4 of spades", "5 of spades", "6 of spades", "7 of spades", "8 of spades"};
        String[] spade59 = {"5 of spades", "6 of spades", "7 of spades", "8 of spades", "9 of spades"};
        String[] spade610 = {"6 of spades", "7 of spades", "8 of spades", "9 of spades", "10 of spades"};
        String[] spade7J = {"7 of spades", "8 of spades", "9 of spades", "10 of spades", "Jack of spades"};
        String[] spade8Q = {"8 of spades", "9 of spades", "10 of spades", "Jack of spades", "Queen of spades"};
        String[] spade9K = {"9 of spades", "10 of spades", "Jack of spades", "Queen of spades", "King of spades"};
        // hearts
        String[] heartA5 = {"Ace of hearts", "2 of hearts", "3 of hearts", "4 of hearts", "5 of hearts"};
        String[] heart26 = {"2 of hearts", "3 of hearts", "4 of hearts", "5 of hearts", "6 of hearts"};
        String[] heart37 = {"3 of hearts", "4 of hearts", "5 of hearts", "6 of hearts", "7 of hearts"};
        String[] heart48 = {"4 of hearts", "5 of hearts", "6 of hearts", "7 of hearts", "8 of hearts"};
        String[] heart59 = {"5 of hearts", "6 of hearts", "7 of hearts", "8 of hearts", "9 of hearts"};
        String[] heart610 = {"6 of hearts", "7 of hearts", "8 of hearts", "9 of hearts", "10 of hearts"};
        String[] heart7J = {"7 of hearts", "8 of hearts", "9 of hearts", "10 of hearts", "Jack of hearts"};
        String[] heart8Q = {"8 of hearts", "9 of hearts", "10 of hearts", "Jack of hearts", "Queen of hearts"};
        String[] heart9K = {"9 of hearts", "10 of hearts", "Jack of hearts", "Queen of hearts", "King of hearts"};
        // dims
        // clubs

        // p1
        boolean p1straightFlush = false;
        p1straightFlush = p1hand.containsAll(Arrays.asList(spadeA5));
    }

    public void doEverything() {
        dealHands();
        throwCards();
        findWinner();
    }

}

The place that I would really like condensed is the testBid method.

\$\endgroup\$
  • \$\begingroup\$ Half finished, what's missing? \$\endgroup\$ – Mast Jan 18 '18 at 14:53
  • \$\begingroup\$ @Mast the rest of the findWinner() game. A few other things here and there. \$\endgroup\$ – The Magician Jan 18 '18 at 15:56
2
\$\begingroup\$

Nitpicks

    private ArrayList<String> cards = new ArrayList<String>();

Could be

    private List<String> cards = new ArrayList<>();

In general, we code to the interface. That way we could change the implementation at any time.

We don't need to say String twice. The <> will figure out what is needed to match the declaration.

    private int p1money = 100, p2money = 100, p3money = 100, p4money = 100, p5money = 100, potSize = 0;

In general, one initialization per line.

    private int p1money = 100;
    private int p2money = 100;
    private int p3money = 100;
    private int p4money = 100;
    private int p5money = 100;
    private int potSize = 0;

That way we don't have to look all over hither and yon for potSize, which is hidden at the end of a list of variables that do something else.

    private void testBid() {

Consider changing this to something like

    private void checkBid() {

As is, I would expect this to be part of the unit test code. But in reality, this is the actual code that you expect to run in production. It would be more consistent with industry naming schemes if you regard test as being reserved for testing frameworks.

I'm not even sure that check is necessary. Why not just call it bid?

        Scanner scanner = new Scanner(System.in);

By putting this in the method, you make it get called multiple times. Consider moving it to the constructor, main, or even just set it statically:

        public static Scanner scanner = new Scanner(System.in);

Then it would be available for the life of the program.

enum

        // spades
        cards.add("Ace of spades");
        cards.add("Jack of spades");
        cards.add("Queen of spades");
        cards.add("King of spades");
        int spade = 2;
        while(spade <= 10) {
            cards.add(spade + " of spades");
            spade++;
        }

The first obvious thing to do is to replace the last five lines with

        for (int spade = 2; spade <= 10; spade++) {
            cards.add(spade + " of spades");
        }

Functionally the same, that condenses the loop logic into a single line declaration. This makes it take fewer lines of code and is more readable. The same line tells us the initial value, the final value, and how it moves between them.

But in the longer run, consider replacing the whole thing with something like

        for (Suit suit : Suit.values()) {
            for (Rank rank : Rank.values()) {
                cards.add(new Card(suit, rank));
            }
        }

Note that this will handle all four suits, not just spades. You also need something like

class Card {

    private final Suit SUIT;
    private final Rank RANK;

    public Card(Suit suit, Rank rank) {
        SUIT = suit;
        RANK = rank;
    }

    public Suit getSuit() {
        return SUIT;
    }

    public Rank getRank() {
        return RANK;
    }

}

and

Enum Suit {

    SPADES, HEARTS, DIAMONDS, CLUBS

}

I won't write out the definition of Rank here, but here is an example of how it worked for a Blackjack game.

Removing duplication

        // p1
        System.out.println("Player 1: bid? (true/false)");
        int p1bidAmount = 0;
        boolean p1bid = scanner.nextBoolean();
        if(p1bid) {
            System.out.println("How much?");
            p1bidAmount = scanner.nextInt();
            if(p1bidAmount > p1money) {
                System.out.println("You do not have that much money. You now have $0 and the pot is worth $" + (pot + p1money));
                p1money = 0;
                potSize += p1money;
                return;
            }
            potSize += p1bidAmount;
            p1money -= p1bidAmount;
            System.out.println("The pot is now worth $" + potSize + ". Player 1 now has $" + p1money + " in their hand.");
        }

Anytime you have the same code listed multiple times with variables that differ only in predictable ways, chances are that you should be abstracting. Consider

        for (int i = 0; i < players.size(); i++) {
            if (players[i].bid(currentBid)) {
                currentBid = players[i].getBid();
                potSize += currentBid;
                System.out.println("The pot is now worth $" + potSize + ". Player 1 now has $" + players[i].getMoney() + " in their hand.");
                for (int j = 0; j < i; j++) {
                    if (players[j].call(currentBid)) {
                        potSize += players[j].getBid();
                    }
                }
            }
        }

Then

    public boolean bid(int minimum) {
        Scanner scanner = PlayGame.scanner;

        System.out.println(getPlayerDisplay() + ": bid? (true/false)");
        if (!scanner.getBoolean()) {
            return false;
        }

        System.out.println("How much?");
        bidAmount = scanner.nextInt();
        if (bidAmount > money) {
            bidAmount = money;
            System.out.println("You do not have that much money. You now have $0");
            money = 0;
        }

        return true;
    }

Now each player is responsible for each player's own bid.

If you find logic errors in this, consider the possibility that they already existed in your original code. I tried to match your code as best as possible, even where it was wrong. It is in large part due to that that I didn't try to implement call. Hint: what happens if a player bets everything and then someone else bets more? If you making betting match offline play more, you may find that that gets easier.

Also, be careful of syntax errors. I don't have my Java IDE at the moment, so I haven't tested this in any way.

\$\endgroup\$
  • \$\begingroup\$ For your hint: if a player bets everything, they're all-in and nothing will happen when someone else bids. The only thing they have to worry about is if they win or lose the hand. \$\endgroup\$ – The Magician Jan 18 '18 at 19:14
  • \$\begingroup\$ @TheMagician Try it. That's not what your code does. \$\endgroup\$ – mdfst13 Jan 18 '18 at 19:17
  • \$\begingroup\$ I know that - it's what it will do. \$\endgroup\$ – The Magician Jan 18 '18 at 21:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.