Determining winning amount in Poker without creati

2019-03-26 04:30发布

问题:

I'm trying to run a poker simulation and have the following data about a poker table

  • how much each player contributed to the pot
  • a "hand score" (after flop) for each player (ie, if player[0].score == player[1].score, they tied)

I'm stuck calculating how much each player should win without needing to create sidepots and assigning players to each of them.

For example,

player[0].contributed = 100
player[1].contributed = 80
player[2].contributed = 20

player[0].score = 10
player[1].score = 2
player[2].score = 10

total_pot = 200;

In this example, do I first need to return player[0] 20 back and remove it from the pot?

Then, since player[0] and player[2] have tied for first spot, and player[1] has lost, should the pot be divided as:

player[0].received = 170
player[1].received = 0
player[2].received = 30

And subsequently, if player[1] had won, should the pot be divided as:

player[0].received = 20
player[1].received = 180
player[2].received = 0

回答1:

First sort by score descending, so you'll end up with two groups: { 0, 2 }, { 1 }.

Then, sort each group by the order they have contributed ascending: { 2 (20), 0 (100) }, { 1 (80) }.

Now, divide the pot in that order:

  1. First you'll take (max) 20 away from each players contributions to create the first pot. And divide it evenly to 2 and 0. The first pot will be (20 + 20 + 20 = 60. So both 0 and 2 will be given 30). After that, the first players winnings are done, and you are left with: { 0 (80) }, { 1 (60) }.

  2. Now, you'll take (max) 80 away from each players contributions to create the next pot (80 + 60 = 140). And give it to 0 (no division needed as there are no longer more than one in the top group, so 0 will receive the whole 140). You'll be left with: { 1 (0) }.

  3. No more contributions left, so you are done.

So, in total in your example, 0 would receive 170 and 2 would receive 30.



回答2:

The following code has a very large number of assertions, but BE CAREFUL because I have not tested it carefully. It's not clear what to do with the odd chips; I give them to the players that appear later in the collection.

import java.util.*;

public class Player {
    int contributed, score, received;

    static void winnings(Collection<Player> players) {
        for (Player player : players) {
            assert player.contributed >= 0;
            player.received = 0;
        }
        int potCutoff = 0;
        while (true) {
            int playerCount = 0;
            int nextPotCutoff = Integer.MAX_VALUE;
            int scoreMax = Integer.MIN_VALUE;
            int winnerCount = 0;
            for (Player player : players) {
                if (player.contributed <= potCutoff) {
                    continue;
                }
                playerCount++;
                assert playerCount > 0;
                nextPotCutoff = Math.min(nextPotCutoff, player.contributed);
                if (player.score > scoreMax) {
                    scoreMax = player.score;
                    winnerCount = 1;
                } else if (player.score == scoreMax) {
                    winnerCount++;
                    assert winnerCount > 0;
                } else {
                    assert player.score < scoreMax;
                }
            }
            if (playerCount == 0) {
                break;
            }
            assert playerCount > 0;
            assert nextPotCutoff > potCutoff;
            assert potCutoff >= 0;
            assert Integer.MAX_VALUE / (nextPotCutoff - potCutoff) >= playerCount;
            int potTotal = playerCount * (nextPotCutoff - potCutoff);
            assert potTotal > 0;
            assert winnerCount > 0;
            assert winnerCount <= playerCount;
            for (Player player : players) {
                if (player.contributed <= potCutoff) {
                    continue;
                }
                assert player.contributed >= nextPotCutoff;
                if (player.score == scoreMax) {
                    assert winnerCount > 0;
                    int winnerShare = potTotal / winnerCount;
                    winnerCount--;
                    assert winnerShare > 0;
                    assert potTotal >= winnerShare;
                    potTotal -= winnerShare;
                    player.received += winnerShare;
                    assert player.received > 0;
                } else {
                    assert player.score < scoreMax;
                }
            }
            assert winnerCount == 0;
            assert potTotal == 0;
            potCutoff = nextPotCutoff;
        }
    }

    public static void main(String[] args) {
        Player p0 = new Player(), p1 = new Player(), p2 = new Player();
        p0.contributed = 100;
        p1.contributed = 80;
        p2.contributed = 20;
        p0.score = 10;
        p1.score = 2;
        p2.score = 10;
        Collection<Player> players = new ArrayList<Player>();
        players.add(p0);
        players.add(p1);
        players.add(p2);
        winnings(players);
        for (Player player : players) {
            System.out.println(player.received);
        }
    }
}