java - 扑克游戏:找到玩家获胜的可能性
问题描述
我有德州扑克的基于 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;
}
}
`
解决方案
推荐阅读
- bitwise-operators - 面具之外的一切都等于
- c - 使用 arduino nano 上的簧片开关计算磁铁外观
- reactjs - events.js:182 抛出错误;// 未处理的 'error' 事件和无法读取未定义的属性 'has'
- tmux - 如何在 tmux 中发送功能键?
- sql - PostgreSQL - 选择字符串中带有 ID 的所有评论
- json - Pyspark 爆炸嵌套 json - 删除空行
- php - Laravel 8 分页无法正确加载
- wpf - 使用 .XAML 中的 Viewbox 作为其他控件中的图像
- bash - 如何从 slurm 加载 anaconda 虚拟环境?
- c# - 将 XML 转换为 JSON 时如何阻止 JsonConvert.SerializeObject 将整数更改为字符串