This commit is contained in:
Ubuntu
2026-07-03 16:58:28 +08:00
commit 32b43f85bd
6240 changed files with 1987678 additions and 0 deletions
+236
View File
@@ -0,0 +1,236 @@
"""
GameBase 游戏基类
定义游戏的通用接口和状态管理
"""
from abc import ABC, abstractmethod
from typing import Dict, List, Any, Optional
from enum import Enum
import time
import json
class GamePhase(Enum):
"""游戏阶段枚举"""
WAITING = "waiting" # 等待玩家
READY = "ready" # 准备开始
STARTING = "starting" # 开始中
PLAYING = "playing" # 游戏中
PAUSED = "paused" # 暂停
ENDED = "ended" # 已结束
class GameState:
"""
游戏状态类
管理游戏的所有状态数据
"""
def __init__(self, game_type: str, room_id: str):
self.game_type = game_type
self.room_id = room_id
self.phase = GamePhase.WAITING
self.round = 0
self.turn_count = 0
self.current_turn_player_id: Optional[str] = None
self.winner_id: Optional[str] = None
self.started_at: Optional[float] = None
self.ended_at: Optional[float] = None
# 玩家状态
self.player_states: Dict[str, Dict] = {}
# 游戏特定数据
self.data: Dict[str, Any] = {}
# 历史记录
self.history: List[Dict] = []
def start(self):
"""开始游戏"""
self.phase = GamePhase.PLAYING
self.round = 1
self.started_at = time.time()
def end(self, winner_id: Optional[str] = None):
"""结束游戏"""
self.phase = GamePhase.ENDED
self.winner_id = winner_id
self.ended_at = time.time()
def next_turn(self, player_id: str):
"""切换回合"""
self.current_turn_player_id = player_id
self.turn_count += 1
def add_history(self, action: str, player_id: str, data: Dict):
"""添加历史记录"""
self.history.append({
'turn': self.turn_count,
'action': action,
'player_id': player_id,
'data': data,
'timestamp': time.time()
})
def set_player_state(self, player_id: str, state: Dict):
"""设置玩家状态"""
self.player_states[player_id] = state
def get_player_state(self, player_id: str) -> Optional[Dict]:
"""获取玩家状态"""
return self.player_states.get(player_id)
def to_dict(self, player_id: Optional[str] = None) -> Dict[str, Any]:
"""
序列化为字典
player_id: 如果提供,包含该玩家的私有信息
"""
return {
'game_type': self.game_type,
'room_id': self.room_id,
'phase': self.phase.value,
'round': self.round,
'turn_count': self.turn_count,
'current_turn': self.current_turn_player_id,
'winner': self.winner_id,
'started_at': self.started_at,
'ended_at': self.ended_at,
'player_states': self.player_states,
'data': self.data,
'history': self.history[-20:] if len(self.history) > 20 else self.history,
}
def to_json(self) -> str:
"""序列化为 JSON"""
return json.dumps(self.to_dict(), default=str)
class GameBase(ABC):
"""
游戏基类
所有具体游戏必须继承此类
"""
def __init__(self, room_id: str, game_type: str):
self.room_id = room_id
self.game_type = game_type
self.state = GameState(game_type, room_id)
self.players: Dict[str, Any] = {} # player_id -> Player
self.player_order: List[str] = [] # 玩家顺序
self.is_started = False
self.is_ended = False
@property
@abstractmethod
def min_players(self) -> int:
"""最少玩家数"""
pass
@property
@abstractmethod
def max_players(self) -> int:
"""最多玩家数"""
pass
@property
def player_count(self) -> int:
"""当前玩家数"""
return len(self.players)
def add_player(self, player):
"""添加玩家"""
if self.player_count >= self.max_players:
raise ValueError("房间已满")
self.players[player.id] = player
if player.id not in self.player_order:
self.player_order.append(player.id)
self.state.set_player_state(player.id, {
'name': player.name,
'is_ai': player.is_ai,
'seat': player.seat_number,
})
def remove_player(self, player_id: str):
"""移除玩家"""
if player_id in self.players:
del self.players[player_id]
if player_id in self.player_order:
self.player_order.remove(player_id)
@abstractmethod
def can_start(self) -> bool:
"""检查是否可以开始游戏"""
pass
@abstractmethod
def start(self):
"""开始游戏"""
pass
@abstractmethod
def handle_action(self, player_id: str, action: str, data: Dict) -> Dict:
"""
处理玩家操作
返回: {'success': bool, 'message': str, 'state_update': Dict}
"""
pass
@abstractmethod
def get_valid_actions(self, player_id: str) -> List[str]:
"""获取玩家当前可用的操作列表"""
pass
@abstractmethod
def check_winner(self) -> Optional[str]:
"""检查是否有获胜者"""
pass
def get_current_player(self) -> Optional[Any]:
"""获取当前回合玩家"""
if self.state.current_turn_player_id:
return self.players.get(self.state.current_turn_player_id)
return None
def next_player(self) -> Optional[Any]:
"""切换到下一个玩家"""
if not self.player_order:
return None
current_id = self.state.current_turn_player_id
if not current_id or current_id not in self.player_order:
next_id = self.player_order[0]
else:
current_idx = self.player_order.index(current_id)
next_idx = (current_idx + 1) % len(self.player_order)
next_id = self.player_order[next_idx]
self.state.next_turn(next_id)
return self.players.get(next_id)
def end_game(self, winner_id: Optional[str] = None):
"""结束游戏"""
self.is_ended = True
self.state.end(winner_id)
def to_dict(self) -> Dict[str, Any]:
"""序列化游戏状态"""
return {
'room_id': self.room_id,
'game_type': self.game_type,
'min_players': self.min_players,
'max_players': self.max_players,
'player_count': self.player_count,
'is_started': self.is_started,
'is_ended': self.is_ended,
'state': self.state.to_dict(),
'players': {
pid: p.to_dict() for pid, p in self.players.items()
}
}