首页 > 解决方案 > 扑克游戏:找到玩家获胜的可能性

问题描述

我有德州扑克的基于 Java 的应用程序。我必须介绍一个功能,当除一个以外的所有玩家全押时,我们必须计算每个玩家获胜的概率。

这可能发生在翻牌前、翻牌圈和转牌圈。正如您可能知道在翻牌前阶段必须选择所有 5 张牌,在翻牌桌中已经有 3 张公共牌,必须再选择 2 张牌,而在轮次必须再选择 1 张牌。让我们假设有 2 个玩家。

所以每个玩家都有 2 张底牌。所以我们必须从 52 张 -2*2 = 48 张牌中选择 2 张牌。通过使用组合我能够做到这一点。但是在翻牌前阶段组合太多了,从48张牌中我们必须选择5张,即48Cr5 = 1712304种组合。如果我做那么多计算,游戏就会卡住。所以尝试使用 ForkJoinPool。我发现部署应用程序的机器中只有 2 个内核。它根本不起作用。ForkJoinPool 适合这个任务还是我应该去其他一些 ExecutorService。这是我的一些 RecursiveTask 代码

public class WinnerPercentageTask extends RecursiveTask<List<String>> {
    
    private static int threshold = 50_000;
    
    private List<List<Byte>> combinations;
    
    private int start;
    private int end;
    
    private ITexasHoldemGame game;
    
    
    public WinnerPercentageTask(ITexasHoldemGame game, List<List<Byte>> allCombinations, int start, int end) {
        super();
        this.game = game;
        this.combinations = allCombinations;
        this.start = start;
        this.end = end;
    }

    @Override
    protected List<String> compute() {
        if (end - start < threshold) {
            return computeDirectly();
        }
        else {
            int middle = (end + start) / 2;
            WinnerPercentageTask subTask1 = new WinnerPercentageTask(game,combinations, start, middle);
            WinnerPercentageTask subTask2 = new WinnerPercentageTask(game,combinations, middle, end);
 
            invokeAll(subTask1, subTask2);
 
            List<String> ret = new ArrayList<>();
            ret.addAll(subTask1.join());
            ret.addAll(subTask1.join());
            return ret;
        }
    }

    private List<String> computeDirectly() {
        List<Card> communityCards = game.getCommunityCardsDealt();
        List<Winner> winners = new ArrayList<>();
        List<String> winnersForAllCombinations = new ArrayList<>();
        for(List<Byte> combination: combinations.subList(start, end)) {
            List<Card> allCommunityCard = new ArrayList<>();
            for (Card c : communityCards) {
                allCommunityCard.add(new Card(c.getId(), c.getFaceValue(), c.getSuit()));
            }
            for (Byte b : combination) {
                Card fakeCommunityCard = new Card(b);
                allCommunityCard.add(fakeCommunityCard);
            }
            List<PokerHand> playerRankList = calculateHandRank(allCommunityCard);
            winners = prepareWinnerList(playerRankList);
            winnersForAllCombinations.addAll(
                    winners.stream()
                    .map(Winner:: getPlayerId)
                    .collect(Collectors.toList()));
             
        }
        return winnersForAllCombinations;
        
    }
    
    private List<PokerHand> calculateHandRank(List<Card> communityCardsDealt) {

        List<PokerHand> playerRankList = new ArrayList<>();
        
        Map<String, List<Card>> playersCards = this.game.getCardsDealtForAllPlayers();
        
        playersCards.forEach((player, holeCards) -> {
            PokerHand pokerHand = new PokerHand(player, holeCards);
            HandRanker.checkRanking(pokerHand, communityCardsDealt);
            playerRankList.add(pokerHand);
        });
        Collections.sort(playerRankList);
//        if (logger.isInfoEnabled()) {
//            logger.info("Player Rank List : {}", playerRankList);
//        }
        
        return playerRankList;
    }
    
     private List<Winner> prepareWinnerList(List<PokerHand> playerRankList) {

            List<Winner> winnerList = new ArrayList<>();
            if (!CollectionUtils.isEmpty(playerRankList)) {

                // Grouping Players based on similar Ranks
                Map<HandRankingEnum, List<PokerHand>> groupByRankMap = playerRankList.stream()
                        .collect(Collectors.groupingBy(PokerHand::getRankingEnum));

                // Sort the Map based on Rank, highest rank first
                List<Map.Entry<HandRankingEnum, List<PokerHand>>> sortedWinnerList = groupByRankMap
                        .entrySet().stream().sorted(reverseOrder(Map.Entry.comparingByKey()))
                        .collect(Collectors.toList());

                // Reading the Winners of highest rank
                Map.Entry<HandRankingEnum, List<PokerHand>> winnerListMap = sortedWinnerList
                        .get(0);

                List<PokerHand> highestRankList = winnerListMap.getValue();
                List<PokerHand> winnerHandList = new WinnerIdentifier().getWinners(highestRankList);

                for (PokerHand hand : winnerHandList) {
                    Winner winnerPlayer = Winner.builder()
                            .rank((byte) hand.getRankingEnum().getValue())
                            .rankName(hand.getRankingEnum().name())
                            .playerId(hand.getGamePlayerId()).cards(hand.getRankingList())
                            .pots(new ArrayList<>()).build();

                    winnerList.add(winnerPlayer);
                }

            } 
            
            return winnerList;
        }

}
`

标签: javaconcurrencycombinatoricsfork-join

解决方案


推荐阅读