HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Poker Odds Calculation with Monte Carlo

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
pokermontecalculationoddswithcarlo

Problem

I have created an Odds Calculator in Java. The program gives me the odds, but I want to make sure that they are correct. Maybe someone can tell me a calculator I can compare my results with or knows another way to check if the odds are correct? With the calculator you can set your own hand plus the cards on the table. Also I want to optimize the MonteCarlo class so that it's as fast and efficient as possible. I have removed the init method otherwise the post contains to many characters,
How to optimize the MonteCarlo class?

MonteCarlo.java

```
public class MonteCarlo {

Game game=new Game();
private long numberOfLoops=0L;
private long currentLoop = 0L;
private boolean running = false;
private Random prng = new Random();
private String knownCards;

public MonteCarlo(String knownCards, long numberOfLoops, int numberOfPlayers) {
/*
* Parse initial game options from command line.
*/
if (numberOfPlayers Constants.MAX_NUMBER_OF_PLAYERS) {
numberOfPlayers = Constants.MAX_NUMBER_OF_PLAYERS;
}

if (numberOfLoops Constants.MAX_NUMBER_OF_LOOPS) {
numberOfLoops = Constants.MAX_NUMBER_OF_LOOPS;
}

/*
* Initialize the table with players and cards.
*/
init(numberOfPlayers);

this.knownCards = knownCards;
this.numberOfLoops = numberOfLoops;
}

/ Evaluate one pair /
public HandStrength evaluateOnePair(Card[] hand) {
HandStrength result = new HandStrength();
result.fifthKicker = 0;
result.fourthKicker = 0;
result.thirdKicker = 0;
result.secondKicker = 0;
result.firstKicker = 0;
result.onePair = 0;
result.twoPair = 0;
result.threeOfKind = 0;
result.straight = 0;
result.flush = 0;
result.fullHouse = 0;
result.fourOfKind = 0;
result.straightFlush = 0;

if (hand[0].kind == hand[1].kind && hand[0].kind != hand[2].kind &&

Solution

The shuffle

Right now you shuffle the full deck (with an incorrect version of Fisher Yates shuffle btw), and then you call fillKnownCards() which looks through the entire deck searching for particular cards to swap to the front. Instead of doing that, why not just call fillKnownCards() once to begin with, and then every time you shuffle, you only shuffle the rest of the cards? For example if there are 2 known cards, then shuffle only the last 50 cards each time.

One thing that needs to be changed if you did that is you would need to change your dealing order to deal to the player first, then to the table, then to the other players. This is because your known cards are only the player's cards and the table cards. But since the dealing order doesn't affect the simulation, it's fine to make this change.
Lots of useless lines

HandStrength result = new HandStrength();
        result.fifthKicker = 0;
        result.fourthKicker = 0;
        result.thirdKicker = 0;
        result.secondKicker = 0;
        ...


All of the result.field = 0 lines are useless because all the fields should already be set to 0 by the default constructor (although you haven't showed that code, but I'm assuming).
fillKnownCards() card parsing

I don't know why there is all this card parsing code here. Don't you already have a Card constructor that takes a string argument? If not, you should move all this code to the Card class and create a new constructor for it. Make the constructor take either two characters or a single string.
Ranking hands

Your hand ranking algorithm is slow. You sort the cards twice and rank the hands completely each time even though the Ace low sorting should only ever be needed to find a wheel straight.

I recently answered a poker ranking question so I'll just refer you to what I recommended in the other review. Essentially, you could encode each hand's score into a single long. The code to do that would be both faster and smaller than your current ranking code.

Code Snippets

HandStrength result = new HandStrength();
        result.fifthKicker = 0;
        result.fourthKicker = 0;
        result.thirdKicker = 0;
        result.secondKicker = 0;
        ...

Context

StackExchange Code Review Q#90489, answer score: 2

Revisions (0)

No revisions yet.