shortdeck1.3:ui and fix
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import uuid
|
||||
import random
|
||||
from typing import List, Optional, Dict
|
||||
from shortdeck_arena.simulation import Simulation
|
||||
from shortdeck_arena.agent import Agent, HumanAgent
|
||||
from shortdeck_arena.game_stage import BlindConfig
|
||||
|
||||
from shortdeck_arena import Simulation, Agent, HumanAgent, BlindConfig
|
||||
|
||||
|
||||
class ArenaGame:
|
||||
@@ -42,6 +42,51 @@ class ArenaGame:
|
||||
self.sim.new_round()
|
||||
|
||||
return player_id
|
||||
|
||||
def get_valid_actions(self, player_id) -> List[str]:
|
||||
if not self.sim:
|
||||
return []
|
||||
|
||||
try:
|
||||
actions_info = self.sim.get_available_actions(player_id)
|
||||
if isinstance(actions_info, dict) and actions_info.get("can_act", False):
|
||||
valid_actions = []
|
||||
|
||||
if actions_info.get("can_fold", False):
|
||||
valid_actions.append("fold")
|
||||
if actions_info.get("can_check", False):
|
||||
valid_actions.append("check")
|
||||
if actions_info.get("can_call", False):
|
||||
valid_actions.append("call")
|
||||
if actions_info.get("can_bet", False):
|
||||
valid_actions.append("bet")
|
||||
if actions_info.get("can_raise", False):
|
||||
valid_actions.append("raise")
|
||||
|
||||
return valid_actions
|
||||
else:
|
||||
return []
|
||||
# 是否需要添加日志
|
||||
except Exception as e:
|
||||
print(f"Error getting valid actions: {e}")
|
||||
valid_actions = ["fold"]
|
||||
|
||||
try:
|
||||
if hasattr(self.sim, 'current_bet') and self.sim.current_bet > 0:
|
||||
valid_actions.append("call")
|
||||
else:
|
||||
valid_actions.append("check")
|
||||
|
||||
if hasattr(self.sim, 'stacks') and player_id < len(self.sim.stacks):
|
||||
if self.sim.stacks[player_id] > getattr(self.sim, 'current_bet', 0):
|
||||
if getattr(self.sim, 'current_bet', 0) > 0:
|
||||
valid_actions.append("raise")
|
||||
else:
|
||||
valid_actions.append("bet")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return valid_actions
|
||||
|
||||
def apply_action(self, player_id, action, amount: Optional[int] = None) -> dict:
|
||||
if not self.sim:
|
||||
@@ -50,6 +95,16 @@ class ArenaGame:
|
||||
try:
|
||||
self.sim.apply_action(player_id, action, amount)
|
||||
|
||||
if (hasattr(self.sim, 'current_stage') and
|
||||
getattr(self.sim.current_stage, 'value', '') == 'finished' and
|
||||
hasattr(self.sim, 'hand_completed') and
|
||||
self.sim.hand_completed):
|
||||
|
||||
import time
|
||||
time.sleep(10)
|
||||
print("游戏结束,自动开始新一轮...")
|
||||
self.reset_hand_keep_chips()
|
||||
|
||||
self.sim.dump_data()
|
||||
|
||||
return {"success": True, "message": f"Applied {action}"}
|
||||
@@ -59,41 +114,100 @@ class ArenaGame:
|
||||
def info(self, player_id: Optional[int] = None) -> Dict:
|
||||
|
||||
if not self.sim:
|
||||
return {"error": "游戏未初始化"}
|
||||
return {
|
||||
"game_id": self.game_id,
|
||||
"players": self.player_names,
|
||||
"dealer_index": 0,
|
||||
"current_turn": 0,
|
||||
"stage": "waiting",
|
||||
"total_pot": 0,
|
||||
"side_pots": [],
|
||||
"player_cards": [],
|
||||
"board_cards": [],
|
||||
"stacks": [self.starting_stack] * len(self.agents),
|
||||
"player_states": ["WAITING"] * len(self.agents),
|
||||
"current_pot": [0] * len(self.agents),
|
||||
"actions": {"can_act": False, "reason": "游戏未开始"}
|
||||
}
|
||||
|
||||
info_data = {
|
||||
"game_id": self.game_id,
|
||||
"players": self.player_names,
|
||||
"dealer_index": self.sim.dealer_position,
|
||||
"current_turn": self.sim.current_turn,
|
||||
"stage": self.sim.current_stage.value,
|
||||
"total_pot": self.sim.total_pot,
|
||||
"side_pots": [{"amount": pot.amount, "eligible_players": list(pot.eligible_players)}
|
||||
for pot in self.sim.get_side_pots()],
|
||||
"dealer_index": getattr(self.sim, 'dealer_position', 0),
|
||||
"current_turn": getattr(self.sim, 'current_turn', 0),
|
||||
"stage": getattr(self.sim.current_stage, 'value', 'pre_flop') if hasattr(self.sim, 'current_stage') else 'pre_flop',
|
||||
"total_pot": getattr(self.sim, 'total_pot', 0),
|
||||
"side_pots": [],
|
||||
}
|
||||
|
||||
try:
|
||||
side_pots = self.sim.get_side_pots()
|
||||
info_data["side_pots"] = [{"amount": pot.amount, "eligible_players": list(pot.eligible_players)}
|
||||
for pot in side_pots]
|
||||
except Exception:
|
||||
info_data["side_pots"] = []
|
||||
|
||||
|
||||
if player_id is not None and 0 <= player_id < len(self.sim.stacks):
|
||||
try:
|
||||
player_cards = self.sim.player_cards(player_id)
|
||||
info_data["player_cards"] = [str(card) for card in player_cards]
|
||||
except Exception:
|
||||
print(f"DEBUG - Player {player_id} cards: {info_data['player_cards']} (raw: {player_cards})")
|
||||
except Exception as e:
|
||||
print(f"DEBUG - Error getting player {player_id} cards: {e}")
|
||||
info_data["player_cards"] = []
|
||||
|
||||
info_data["actions"] = self.sim.get_available_actions(player_id)
|
||||
try:
|
||||
actions_result = self.sim.get_available_actions(player_id)
|
||||
info_data["actions"] = actions_result
|
||||
except Exception as e:
|
||||
info_data["actions"] = {"can_act": False, "reason": f"Error getting actions: {str(e)}"}
|
||||
else:
|
||||
info_data["player_cards"] = []
|
||||
info_data["actions"] = {"can_act": False, "reason": "Invalid player"}
|
||||
|
||||
try:
|
||||
board_cards = self.sim.board_cards(self.sim.current_stage.value)
|
||||
stage_value = getattr(self.sim.current_stage, 'value', 'pre_flop') if hasattr(self.sim, 'current_stage') else 'pre_flop'
|
||||
board_cards = self.sim.board_cards(stage_value)
|
||||
info_data["board_cards"] = [str(card) for card in board_cards]
|
||||
except Exception:
|
||||
info_data["board_cards"] = []
|
||||
|
||||
info_data["stacks"] = self.sim.stacks.copy()
|
||||
info_data["player_states"] = [state.value for state in self.sim.player_states]
|
||||
info_data["current_pot"] = self.sim.pot.copy()
|
||||
try:
|
||||
info_data["stacks"] = self.sim.stacks.copy() if hasattr(self.sim, 'stacks') else []
|
||||
except Exception:
|
||||
info_data["stacks"] = []
|
||||
|
||||
try:
|
||||
info_data["player_states"] = [state.value for state in self.sim.player_states] if hasattr(self.sim, 'player_states') else []
|
||||
except Exception:
|
||||
info_data["player_states"] = []
|
||||
|
||||
try:
|
||||
info_data["current_pot"] = self.sim.pot.copy() if hasattr(self.sim, 'pot') else []
|
||||
except Exception:
|
||||
info_data["current_pot"] = []
|
||||
|
||||
if (hasattr(self.sim, 'current_stage') and
|
||||
getattr(self.sim.current_stage, 'value', '') == 'finished' and
|
||||
self.sim.is_hand_complete()):
|
||||
|
||||
result = self.sim.complete_hand()
|
||||
if result.get("complete", False):
|
||||
info_data["showdown_hands"] = result.get("showdown_hands", {})
|
||||
info_data["winnings"] = result.get("winnings", {})
|
||||
info_data["winners"] = result.get("winners", [])
|
||||
|
||||
if not hasattr(self, '_result_shown_count'):
|
||||
self._result_shown_count = 0
|
||||
self._result_shown_count += 1
|
||||
|
||||
if self._result_shown_count >= 3:
|
||||
print(" 自动开始新一轮游戏...")
|
||||
self.sim.new_round()
|
||||
self._result_shown_count = 0
|
||||
info_data["stage"] = "preflop"
|
||||
## todo
|
||||
return info_data
|
||||
|
||||
|
||||
@@ -163,4 +277,26 @@ class ArenaGame:
|
||||
|
||||
@property
|
||||
def history(self) -> List[Dict]:
|
||||
return self.sim.history if self.sim else []
|
||||
return self.sim.history if self.sim else []
|
||||
|
||||
def reset_hand_keep_chips(self):
|
||||
if not self.sim or len(self.agents) < 2:
|
||||
return
|
||||
|
||||
if hasattr(self.sim, 'hand_completed') and not self.sim.hand_completed:
|
||||
if self.sim.is_hand_complete():
|
||||
self.sim.complete_hand()
|
||||
|
||||
current_stacks = self.sim.stacks.copy()
|
||||
|
||||
self.sim = Simulation(self.agents, blind_config=self.blind_config)
|
||||
|
||||
self.sim.stacks = current_stacks
|
||||
|
||||
self.sim.new_round()
|
||||
|
||||
def full_reset(self):
|
||||
self.agents = []
|
||||
self.player_names = []
|
||||
self.sim = None
|
||||
self.game_id = str(uuid.uuid4())
|
||||
Reference in New Issue
Block a user