shortdeck1.2
This commit is contained in:
104
shortdeck_arena/side_pot.py
Normal file
104
shortdeck_arena/side_pot.py
Normal file
@@ -0,0 +1,104 @@
|
||||
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()
|
||||
Reference in New Issue
Block a user