104 lines
3.3 KiB
Python
104 lines
3.3 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import List, Set, Dict
|
|
from dataclasses import dataclass
|
|
|
|
|
|
@dataclass
|
|
class SidePot:
|
|
amount: int
|
|
eligible_players: Set[int]
|
|
is_main_pot: bool = False
|
|
|
|
def __post_init__(self):
|
|
if not self.eligible_players:
|
|
self.eligible_players = set()
|
|
|
|
|
|
class SidePotManager:
|
|
def __init__(self):
|
|
self.pots: List[SidePot] = []
|
|
self.player_total_investment: Dict[int, int] = {}
|
|
|
|
def add_investment(self, player_id: int, amount: int):
|
|
if player_id not in self.player_total_investment:
|
|
self.player_total_investment[player_id] = 0
|
|
self.player_total_investment[player_id] += amount
|
|
|
|
def create_side_pots(self, active_players: List[int]) -> List[SidePot]:
|
|
if not self.player_total_investment:
|
|
return []
|
|
|
|
# 按投入金额排序
|
|
sorted_investments = sorted(
|
|
[(pid, amount) for pid, amount in self.player_total_investment.items()
|
|
if pid in active_players and amount > 0],
|
|
key=lambda x: x[1]
|
|
)
|
|
|
|
if not sorted_investments:
|
|
return []
|
|
|
|
pots = []
|
|
prev_level = 0
|
|
|
|
for i, (player_id, investment) in enumerate(sorted_investments):
|
|
if investment > prev_level:
|
|
# 计算本层级的贡献
|
|
level_contribution = investment - prev_level
|
|
|
|
# 找到有资格竞争本层级的玩家
|
|
eligible_players = {
|
|
pid for pid, inv in sorted_investments[i:]
|
|
if inv >= investment
|
|
}
|
|
|
|
pot_amount = level_contribution * len(eligible_players)
|
|
|
|
side_pot = SidePot(
|
|
amount=pot_amount,
|
|
eligible_players=eligible_players,
|
|
is_main_pot=(len(pots) == 0)
|
|
)
|
|
|
|
pots.append(side_pot)
|
|
prev_level = investment
|
|
|
|
self.pots = pots
|
|
return pots
|
|
|
|
def get_total_pot(self) -> int:
|
|
return sum(pot.amount for pot in self.pots)
|
|
|
|
def distribute_winnings(self, hand_rankings: Dict[int, int]) -> Dict[int, int]:
|
|
winnings = {}
|
|
|
|
for pot in self.pots:
|
|
|
|
eligible = [pid for pid in pot.eligible_players if pid in hand_rankings]
|
|
if not eligible:
|
|
continue
|
|
|
|
# 找到最强手牌
|
|
best_strength = max(hand_rankings[pid] for pid in eligible)
|
|
winners = [pid for pid in eligible
|
|
if hand_rankings[pid] == best_strength]
|
|
|
|
# 平分底池
|
|
winnings_per_winner = pot.amount // len(winners)
|
|
remainder = pot.amount % len(winners)
|
|
|
|
for i, winner in enumerate(winners):
|
|
if winner not in winnings:
|
|
winnings[winner] = 0
|
|
winnings[winner] += winnings_per_winner
|
|
# 余数给前面的获胜者
|
|
if i < remainder:
|
|
winnings[winner] += 1
|
|
|
|
return winnings
|
|
|
|
def reset(self):
|
|
"""重置边池管理器"""
|
|
self.pots.clear()
|
|
self.player_total_investment.clear() |