779 lines
27 KiB
Python
779 lines
27 KiB
Python
"""狼人杀游戏"""
|
||
import json
|
||
import random
|
||
import logging
|
||
import time
|
||
from typing import Optional, Dict, Any, List
|
||
from games.base import BaseGame
|
||
from utils.parser import CommandParser
|
||
from utils.message import MessageSender
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
class WerewolfGame(BaseGame):
|
||
"""狼人杀游戏"""
|
||
|
||
def __init__(self):
|
||
"""初始化游戏"""
|
||
super().__init__()
|
||
# 角色配置:{总人数: {'wolves': 狼人数, 'seer': 预言家数, 'witch': 女巫数, 'civilians': 平民数}}
|
||
self.role_configs = {
|
||
6: {'wolves': 2, 'seer': 1, 'witch': 1, 'civilians': 2},
|
||
8: {'wolves': 2, 'seer': 1, 'witch': 1, 'civilians': 4},
|
||
10: {'wolves': 3, 'seer': 1, 'witch': 1, 'civilians': 5},
|
||
12: {'wolves': 4, 'seer': 1, 'witch': 1, 'civilians': 6}
|
||
}
|
||
self.min_players = 6
|
||
self.max_players = 12
|
||
|
||
async def handle(self, command: str, chat_id: int, user_id: int) -> str:
|
||
"""处理狼人杀指令
|
||
|
||
Args:
|
||
command: 指令,如 ".werewolf open" 或 ".werewolf 杀 1"
|
||
chat_id: 会话ID
|
||
user_id: 用户ID
|
||
|
||
Returns:
|
||
回复消息
|
||
"""
|
||
try:
|
||
# 提取参数
|
||
_, args = CommandParser.extract_command_args(command)
|
||
args = args.strip()
|
||
|
||
# 没有参数,显示帮助
|
||
if not args:
|
||
return self.get_help()
|
||
|
||
# 解析参数
|
||
parts = args.split(maxsplit=1)
|
||
action = parts[0].lower()
|
||
|
||
# 创建/加入/开始游戏
|
||
if action == 'open':
|
||
return self._open_game(chat_id, user_id)
|
||
|
||
if action == 'join':
|
||
return await self._join_game(chat_id, user_id)
|
||
|
||
if action == 'start':
|
||
return await self._start_game(chat_id, user_id)
|
||
|
||
if action == 'status':
|
||
return self._show_status(chat_id)
|
||
|
||
if action == 'end':
|
||
return self._end_game(chat_id, user_id)
|
||
|
||
# 私聊功能
|
||
if action == '狼人':
|
||
# 狼人群聊
|
||
if len(parts) < 2:
|
||
return "❌ 请输入要发送的内容"
|
||
content = parts[1].strip()
|
||
return await self._wolf_group_chat(chat_id, user_id, content)
|
||
|
||
# 普通私聊:<id> <content>
|
||
# 检查是否是数字(玩家代号)
|
||
try:
|
||
target_id = int(action)
|
||
if len(parts) < 2:
|
||
return "❌ 请输入要发送的内容"
|
||
content = parts[1].strip()
|
||
return await self._private_chat(chat_id, user_id, target_id, content)
|
||
except ValueError:
|
||
pass
|
||
|
||
# 技能指令
|
||
if action in ['杀', '验', '救', '毒', '守']:
|
||
if len(parts) < 2:
|
||
return f"❌ 请指定目标ID,如:`.werewolf {action} 3`"
|
||
try:
|
||
target_id = int(parts[1].strip())
|
||
return await self._handle_skill(chat_id, user_id, action, target_id)
|
||
except ValueError:
|
||
return "❌ 目标ID必须是数字"
|
||
|
||
# 查看帮助
|
||
if action in ['help', '帮助']:
|
||
return self.get_help()
|
||
|
||
# 未识别的指令
|
||
logger.warning(f"狼人杀未识别的指令 - args: {args}")
|
||
return f"❌ 未识别的指令:{args}\n\n💡 提示:输入 `.werewolf help` 查看帮助"
|
||
|
||
except Exception as e:
|
||
logger.error(f"处理狼人杀指令错误: {e}", exc_info=True)
|
||
return f"❌ 处理指令出错: {str(e)}"
|
||
|
||
def _get_game_state(self, chat_id: int) -> Optional[Dict]:
|
||
"""获取游戏状态
|
||
|
||
Args:
|
||
chat_id: 会话ID
|
||
|
||
Returns:
|
||
游戏状态或None
|
||
"""
|
||
state = self.db.get_game_state(chat_id, 0, 'werewolf')
|
||
if state:
|
||
return state['state_data']
|
||
return None
|
||
|
||
def _save_game_state(self, chat_id: int, state_data: Dict):
|
||
"""保存游戏状态
|
||
|
||
Args:
|
||
chat_id: 会话ID
|
||
state_data: 状态数据
|
||
"""
|
||
self.db.save_game_state(chat_id, 0, 'werewolf', state_data)
|
||
|
||
def _open_game(self, chat_id: int, user_id: int) -> str:
|
||
"""主持人开房
|
||
|
||
Args:
|
||
chat_id: 会话ID
|
||
user_id: 主持人用户ID
|
||
|
||
Returns:
|
||
提示消息
|
||
"""
|
||
# 检查是否已有游戏
|
||
state_data = self._get_game_state(chat_id)
|
||
if state_data:
|
||
if state_data['status'] == 'playing':
|
||
return "⚠️ 已经有游戏正在进行中!"
|
||
elif state_data['status'] == 'open':
|
||
return "⚠️ 房间已存在!\n\n房间状态:等待玩家加入\n\n玩家可以输入 `.werewolf join` 加入游戏"
|
||
|
||
# 创建新房间
|
||
state_data = {
|
||
'creator_id': user_id,
|
||
'status': 'open',
|
||
'players': [],
|
||
'phase': None,
|
||
'round': 0,
|
||
'wolves': [],
|
||
'kill_target': None,
|
||
'seer_result': {},
|
||
'witch_save': False,
|
||
'witch_poison': None,
|
||
'guard_target': None,
|
||
'day_dead': [],
|
||
'vote_targets': {},
|
||
'discussed': False,
|
||
'wolf_know_each_other': False
|
||
}
|
||
|
||
self._save_game_state(chat_id, state_data)
|
||
|
||
return f"## 🐺 狼人杀房间已创建!\n\n主持人:{user_id}\n\n其他玩家可以输入 `.werewolf join` 加入游戏\n\n**要求**:6-12人,必须注册用户名和个人URL"
|
||
|
||
async def _join_game(self, chat_id: int, user_id: int) -> str:
|
||
"""玩家加入游戏
|
||
|
||
Args:
|
||
chat_id: 会话ID
|
||
user_id: 用户ID
|
||
|
||
Returns:
|
||
提示消息
|
||
"""
|
||
# 获取游戏状态
|
||
state_data = self._get_game_state(chat_id)
|
||
if not state_data:
|
||
return "❌ 没有可加入的游戏!主持人需要先输入 `.werewolf open` 创建房间"
|
||
|
||
if state_data['status'] != 'open':
|
||
return "❌ 游戏已开始或已结束,无法加入!"
|
||
|
||
# 检查是否已加入
|
||
for player in state_data['players']:
|
||
if player['user_id'] == user_id:
|
||
return "⚠️ 你已经在这个房间里了!"
|
||
|
||
# 检查人数限制
|
||
if len(state_data['players']) >= self.max_players:
|
||
return f"❌ 房间已满!最多支持{self.max_players}人"
|
||
|
||
# 验证用户是否注册了用户名
|
||
user = self.db.get_or_create_user(user_id)
|
||
username = user.get('username')
|
||
if not username:
|
||
return "❌ 请先注册用户名!使用 `.register <名称>` 注册"
|
||
|
||
# 验证用户是否注册了个人URL
|
||
if not self.db.has_webhook_url(user_id):
|
||
return "❌ 请先注册个人URL!使用 `.register url <URL>` 注册\n\n个人URL用于接收游戏内的私聊消息"
|
||
|
||
# 加入玩家
|
||
player_id = len(state_data['players']) + 1
|
||
player_info = {
|
||
'user_id': user_id,
|
||
'name': username,
|
||
'id': player_id,
|
||
'role': None, # 稍后分配
|
||
'alive': True,
|
||
'id_label': f"{player_id}号玩家"
|
||
}
|
||
|
||
state_data['players'].append(player_info)
|
||
self._save_game_state(chat_id, state_data)
|
||
|
||
return f"✅ 加入成功!你是 **{player_id}号玩家**\n\n当前房间人数:{len(state_data['players'])}/{self.max_players}\n\n其他玩家继续输入 `.werewolf join` 加入"
|
||
|
||
async def _start_game(self, chat_id: int, user_id: int) -> str:
|
||
"""开始游戏
|
||
|
||
Args:
|
||
chat_id: 会话ID
|
||
user_id: 用户ID
|
||
|
||
Returns:
|
||
提示消息
|
||
"""
|
||
# 获取游戏状态
|
||
state_data = self._get_game_state(chat_id)
|
||
if not state_data:
|
||
return "❌ 没有可开始的游戏!主持人需要先输入 `.werewolf open` 创建房间"
|
||
|
||
if state_data['status'] != 'open':
|
||
return "❌ 游戏已经开始了!"
|
||
|
||
if user_id != state_data['creator_id']:
|
||
return "❌ 只有主持人可以开始游戏!"
|
||
|
||
player_count = len(state_data['players'])
|
||
if player_count < self.min_players or player_count > self.max_players:
|
||
return f"❌ 游戏人数必须在{self.min_players}-{self.max_players}人之间!当前人数:{player_count}"
|
||
|
||
# 检查人数是否在配置中
|
||
if player_count not in self.role_configs:
|
||
return f"❌ 不支持{player_count}人游戏!仅支持{list(self.role_configs.keys())}人"
|
||
|
||
# 分配角色
|
||
config = self.role_configs[player_count]
|
||
roles = []
|
||
|
||
# 添加狼人
|
||
for _ in range(config['wolves']):
|
||
roles.append('wolf')
|
||
|
||
# 添加预言家
|
||
for _ in range(config['seer']):
|
||
roles.append('seer')
|
||
|
||
# 添加女巫
|
||
for _ in range(config['witch']):
|
||
roles.append('witch')
|
||
|
||
# 添加平民
|
||
for _ in range(config['civilians']):
|
||
roles.append('civilian')
|
||
|
||
# 随机分配
|
||
random.shuffle(roles)
|
||
|
||
# 记录狼人列表
|
||
wolves = []
|
||
for i, player in enumerate(state_data['players']):
|
||
player['role'] = roles[i]
|
||
player['alive'] = True
|
||
if roles[i] == 'wolf':
|
||
wolves.append(player['id'])
|
||
|
||
state_data['wolves'] = wolves
|
||
state_data['status'] = 'playing'
|
||
state_data['round'] = 1
|
||
state_data['phase'] = 'night_kill'
|
||
state_data['wolf_know_each_other'] = True
|
||
|
||
self._save_game_state(chat_id, state_data)
|
||
|
||
# 私聊发送身份
|
||
await self._send_identities(chat_id, state_data)
|
||
|
||
# 公共消息
|
||
return f"## 🎮 游戏开始!\n\n玩家已分配身份,请查看私聊消息\n\n第一夜,天黑请闭眼..."
|
||
|
||
async def _send_identities(self, chat_id: int, state_data: Dict):
|
||
"""发送身份信息到私聊
|
||
|
||
Args:
|
||
chat_id: 会话ID
|
||
state_data: 游戏状态
|
||
"""
|
||
role_descriptions = {
|
||
'wolf': '🐺 **狼人**',
|
||
'seer': '🔮 **预言家**',
|
||
'witch': '🧪 **女巫**',
|
||
'civilian': '👤 **平民**'
|
||
}
|
||
|
||
role_details = {
|
||
'wolf': '你的技能:\n- 每晚可以投票决定杀死一个目标\n- 你认识所有狼人同伴\n- 胜利条件:杀死所有神职和平民\n\n使用 `.werewolf 杀 <id>` 投票杀人',
|
||
'seer': '你的技能:\n- 每晚可以查验一个玩家的身份\n- 胜利条件:消灭所有狼人\n\n使用 `.werewolf 验 <id>` 查验身份',
|
||
'witch': '你的技能:\n- 拥有一瓶解药和一瓶毒药\n- 每晚可以救人(只能使用一次)或毒人(只能使用一次)\n- 胜利条件:消灭所有狼人\n\n使用 `.werewolf 救 <id>` 救人\n使用 `.werewolf 毒 <id>` 毒人',
|
||
'civilian': '你没有特殊技能\n\n你的胜利条件:消灭所有狼人\n\n仔细观察,通过投票帮助好人阵营获胜'
|
||
}
|
||
|
||
for player in state_data['players']:
|
||
role = player['role']
|
||
identity_msg = f"## 🎭 你的身份信息\n\n"
|
||
identity_msg += f"你是:**{player['id_label']}**\n"
|
||
identity_msg += f"身份:{role_descriptions[role]}\n\n"
|
||
|
||
# 狼人显示同伴
|
||
if role == 'wolf':
|
||
teammates = [f"{tid}号" for tid in state_data['wolves'] if tid != player['id']]
|
||
if teammates:
|
||
identity_msg += f"你的狼人同伴:{', '.join(teammates)}\n\n"
|
||
|
||
identity_msg += role_details[role]
|
||
|
||
# 发送私聊
|
||
await self._send_to_player(player['user_id'], identity_msg, sender="系统")
|
||
|
||
async def _send_to_player(self, target_user_id: int, content: str, sender: str = "系统") -> bool:
|
||
"""发送私聊消息给指定玩家
|
||
|
||
Args:
|
||
target_user_id: 目标用户ID
|
||
content: 消息内容
|
||
sender: 发送者标识
|
||
|
||
Returns:
|
||
是否发送成功
|
||
"""
|
||
from utils.message import send_private_message
|
||
|
||
# 添加发送者信息
|
||
if sender != "系统":
|
||
content = f"**来自:{sender}**\n\n{content}"
|
||
|
||
return await send_private_message(target_user_id, content, 'text')
|
||
|
||
async def _private_chat(self, chat_id: int, user_id: int, target_id: int, content: str) -> str:
|
||
"""玩家私聊
|
||
|
||
Args:
|
||
chat_id: 会话ID
|
||
user_id: 发送者用户ID
|
||
target_id: 目标玩家代号
|
||
content: 消息内容
|
||
|
||
Returns:
|
||
提示消息
|
||
"""
|
||
state_data = self._get_game_state(chat_id)
|
||
if not state_data:
|
||
return "❌ 没有正在进行的游戏!"
|
||
|
||
if state_data['status'] != 'playing':
|
||
return "❌ 游戏未开始或已结束!"
|
||
|
||
# 查找发送者
|
||
sender = None
|
||
for player in state_data['players']:
|
||
if player['user_id'] == user_id:
|
||
sender = player
|
||
break
|
||
|
||
if not sender:
|
||
return "❌ 你不是游戏参与者!"
|
||
|
||
if not sender['alive']:
|
||
return "❌ 死亡玩家无法发送消息!"
|
||
|
||
# 查找目标
|
||
target = None
|
||
for player in state_data['players']:
|
||
if player['id'] == target_id:
|
||
target = player
|
||
break
|
||
|
||
if not target:
|
||
return f"❌ 找不到{target_id}号玩家!"
|
||
|
||
if not target['alive']:
|
||
return f"❌ {target_id}号玩家已死亡!"
|
||
|
||
# 发送私聊
|
||
msg = f"{sender['id_label']}对你发送消息:\n\n{content}"
|
||
success = await self._send_to_player(target['user_id'], msg, sender=sender['id_label'])
|
||
|
||
if success:
|
||
return f"✅ 消息已发送给{target_id}号玩家"
|
||
else:
|
||
return "❌ 消息发送失败,请稍后重试"
|
||
|
||
async def _wolf_group_chat(self, chat_id: int, user_id: int, content: str) -> str:
|
||
"""狼人群聊
|
||
|
||
Args:
|
||
chat_id: 会话ID
|
||
user_id: 发送者用户ID
|
||
content: 消息内容
|
||
|
||
Returns:
|
||
提示消息
|
||
"""
|
||
state_data = self._get_game_state(chat_id)
|
||
if not state_data:
|
||
return "❌ 没有正在进行的游戏!"
|
||
|
||
if state_data['status'] != 'playing':
|
||
return "❌ 游戏未开始或已结束!"
|
||
|
||
# 查找发送者
|
||
sender = None
|
||
for player in state_data['players']:
|
||
if player['user_id'] == user_id:
|
||
sender = player
|
||
break
|
||
|
||
if not sender:
|
||
return "❌ 你不是游戏参与者!"
|
||
|
||
if sender['role'] != 'wolf':
|
||
return "❌ 只有狼人可以使用这个功能!"
|
||
|
||
if not sender['alive']:
|
||
return "❌ 死亡玩家无法发送消息!"
|
||
|
||
# 发送给所有狼人
|
||
sent_count = 0
|
||
for player in state_data['players']:
|
||
if player['role'] == 'wolf' and player['user_id'] != user_id:
|
||
msg = f"🐺 狼人{sender['id']}号:{content}"
|
||
success = await self._send_to_player(player['user_id'], msg, sender="狼人群聊")
|
||
if success:
|
||
sent_count += 1
|
||
|
||
if sent_count > 0:
|
||
return f"✅ 消息已发送给{len(state_data['wolves'])-1}个狼人同伴"
|
||
else:
|
||
return "❌ 没有其他狼人在线或发送失败"
|
||
|
||
async def _handle_skill(self, chat_id: int, user_id: int, skill: str, target_id: int) -> str:
|
||
"""处理技能指令
|
||
|
||
Args:
|
||
chat_id: 会话ID
|
||
user_id: 用户ID
|
||
skill: 技能类型(杀/验/救/毒)
|
||
target_id: 目标玩家代号
|
||
|
||
Returns:
|
||
提示消息
|
||
"""
|
||
state_data = self._get_game_state(chat_id)
|
||
if not state_data:
|
||
return "❌ 没有正在进行的游戏!"
|
||
|
||
if state_data['status'] != 'playing':
|
||
return "❌ 游戏未开始或已结束!"
|
||
|
||
# 查找玩家
|
||
player = None
|
||
for p in state_data['players']:
|
||
if p['user_id'] == user_id:
|
||
player = p
|
||
break
|
||
|
||
if not player:
|
||
return "❌ 你不是游戏参与者!"
|
||
|
||
if not player['alive']:
|
||
return "❌ 死亡玩家无法使用技能!"
|
||
|
||
# 根据技能类型处理
|
||
if skill == '杀':
|
||
return await self._wolf_kill(chat_id, state_data, player, target_id)
|
||
elif skill == '验':
|
||
return await self._seer_check(chat_id, state_data, player, target_id)
|
||
elif skill == '救':
|
||
return await self._witch_save(chat_id, state_data, player, target_id)
|
||
elif skill == '毒':
|
||
return await self._witch_poison(chat_id, state_data, player, target_id)
|
||
|
||
return "❌ 未知技能"
|
||
|
||
async def _wolf_kill(self, chat_id: int, state_data: Dict, player: Dict, target_id: int) -> str:
|
||
"""狼人刀人
|
||
|
||
Args:
|
||
chat_id: 会话ID
|
||
state_data: 游戏状态
|
||
player: 玩家信息
|
||
target_id: 目标代号
|
||
|
||
Returns:
|
||
提示消息
|
||
"""
|
||
if player['role'] != 'wolf':
|
||
return "❌ 只有狼人可以刀人!"
|
||
|
||
current_phase = state_data['phase']
|
||
if not current_phase or not current_phase.startswith('night'):
|
||
return "❌ 只能在夜晚使用技能!"
|
||
|
||
# 查找目标
|
||
target = None
|
||
for p in state_data['players']:
|
||
if p['id'] == target_id:
|
||
target = p
|
||
break
|
||
|
||
if not target:
|
||
return f"❌ 找不到{target_id}号玩家!"
|
||
|
||
if not target['alive']:
|
||
return f"❌ {target_id}号玩家已死亡!"
|
||
|
||
# 记录投票
|
||
# 简化:只要有一个狼人投票就算成功
|
||
if state_data.get('kill_target') is None:
|
||
state_data['kill_target'] = target_id
|
||
self._save_game_state(chat_id, state_data)
|
||
return f"✅ 投票成功:刀{target_id}号玩家"
|
||
else:
|
||
return f"⚠️ 今晚已经有了投票目标:{state_data['kill_target']}号"
|
||
|
||
async def _seer_check(self, chat_id: int, state_data: Dict, player: Dict, target_id: int) -> str:
|
||
"""预言家验人
|
||
|
||
Args:
|
||
chat_id: 会话ID
|
||
state_data: 游戏状态
|
||
player: 玩家信息
|
||
target_id: 目标代号
|
||
|
||
Returns:
|
||
提示消息
|
||
"""
|
||
if player['role'] != 'seer':
|
||
return "❌ 只有预言家可以验人!"
|
||
|
||
current_phase = state_data['phase']
|
||
if not current_phase or not current_phase.startswith('night'):
|
||
return "❌ 只能在夜晚使用技能!"
|
||
|
||
# 查找目标
|
||
target = None
|
||
for p in state_data['players']:
|
||
if p['id'] == target_id:
|
||
target = p
|
||
break
|
||
|
||
if not target:
|
||
return f"❌ 找不到{target_id}号玩家!"
|
||
|
||
# 记录验人结果
|
||
result = 'wolf' if target['role'] == 'wolf' else 'good'
|
||
state_data['seer_result'][player['id']] = {'target': target_id, 'result': result}
|
||
self._save_game_state(chat_id, state_data)
|
||
|
||
# 私聊告诉预言家结果
|
||
result_text = "🐺 狼人" if result == 'wolf' else "✅ 好人"
|
||
msg = f"## 🔮 验人结果\n\n{target_id}号玩家的身份是:**{result_text}**"
|
||
await self._send_to_player(player['user_id'], msg, sender="系统")
|
||
|
||
return f"✅ 验人成功!已私聊发送结果"
|
||
|
||
async def _witch_save(self, chat_id: int, state_data: Dict, player: Dict, target_id: int) -> str:
|
||
"""女巫救人
|
||
|
||
Args:
|
||
chat_id: 会话ID
|
||
state_data: 游戏状态
|
||
player: 玩家信息
|
||
target_id: 目标代号
|
||
|
||
Returns:
|
||
提示消息
|
||
"""
|
||
if player['role'] != 'witch':
|
||
return "❌ 只有女巫可以救人!"
|
||
|
||
if state_data.get('witch_save', False):
|
||
return "❌ 解药已使用!"
|
||
|
||
current_phase = state_data['phase']
|
||
if not current_phase or not current_phase.startswith('night'):
|
||
return "❌ 只能在夜晚使用技能!"
|
||
|
||
# 查找目标
|
||
target = None
|
||
for p in state_data['players']:
|
||
if p['id'] == target_id:
|
||
target = p
|
||
break
|
||
|
||
if not target:
|
||
return f"❌ 找不到{target_id}号玩家!"
|
||
|
||
# 记录救人
|
||
state_data['witch_save'] = True
|
||
self._save_game_state(chat_id, state_data)
|
||
|
||
return f"✅ 救人成功:救了{target_id}号玩家"
|
||
|
||
async def _witch_poison(self, chat_id: int, state_data: Dict, player: Dict, target_id: int) -> str:
|
||
"""女巫毒人
|
||
|
||
Args:
|
||
chat_id: 会话ID
|
||
state_data: 游戏状态
|
||
player: 玩家信息
|
||
target_id: 目标代号
|
||
|
||
Returns:
|
||
提示消息
|
||
"""
|
||
if player['role'] != 'witch':
|
||
return "❌ 只有女巫可以毒人!"
|
||
|
||
if state_data.get('witch_poison') is not None:
|
||
return "❌ 毒药已使用!"
|
||
|
||
current_phase = state_data['phase']
|
||
if not current_phase or not current_phase.startswith('night'):
|
||
return "❌ 只能在夜晚使用技能!"
|
||
|
||
# 查找目标
|
||
target = None
|
||
for p in state_data['players']:
|
||
if p['id'] == target_id:
|
||
target = p
|
||
break
|
||
|
||
if not target:
|
||
return f"❌ 找不到{target_id}号玩家!"
|
||
|
||
if not target['alive']:
|
||
return f"❌ {target_id}号玩家已死亡!"
|
||
|
||
# 记录毒人
|
||
state_data['witch_poison'] = target_id
|
||
self._save_game_state(chat_id, state_data)
|
||
|
||
return f"✅ 毒人成功:毒了{target_id}号玩家"
|
||
|
||
def _show_status(self, chat_id: int) -> str:
|
||
"""显示游戏状态
|
||
|
||
Args:
|
||
chat_id: 会话ID
|
||
|
||
Returns:
|
||
状态消息
|
||
"""
|
||
state_data = self._get_game_state(chat_id)
|
||
if not state_data:
|
||
return "❌ 没有正在进行的游戏!"
|
||
|
||
status = state_data['status']
|
||
if status == 'open':
|
||
return f"## 🐺 狼人杀房间\n\n状态:等待玩家加入\n人数:{len(state_data['players'])}/{self.max_players}\n\n输入 `.werewolf join` 加入游戏"
|
||
|
||
if status != 'playing':
|
||
return "❌ 游戏未开始或已结束!"
|
||
|
||
# 显示玩家状态(只显示存活状态,不显示身份)
|
||
msg = f"## 🎮 游戏进行中\n\n"
|
||
msg += f"回合:第{state_data['round']}回合\n"
|
||
msg += f"阶段:{state_data['phase']}\n\n"
|
||
msg += f"**玩家状态**:\n"
|
||
|
||
alive_count = 0
|
||
dead_count = 0
|
||
for player in state_data['players']:
|
||
status_icon = "❤️" if player['alive'] else "💀"
|
||
msg += f"{status_icon} {player['id_label']}\n"
|
||
if player['alive']:
|
||
alive_count += 1
|
||
else:
|
||
dead_count += 1
|
||
|
||
msg += f"\n存活:{alive_count}人 死亡:{dead_count}人"
|
||
|
||
return msg
|
||
|
||
def _end_game(self, chat_id: int, user_id: int) -> str:
|
||
"""结束游戏(主持人专用)
|
||
|
||
Args:
|
||
chat_id: 会话ID
|
||
user_id: 用户ID
|
||
|
||
Returns:
|
||
提示消息
|
||
"""
|
||
state_data = self._get_game_state(chat_id)
|
||
if not state_data:
|
||
return "❌ 没有正在进行的游戏!"
|
||
|
||
if state_data['status'] == 'open':
|
||
return "❌ 游戏尚未开始,无法结束!"
|
||
|
||
if user_id != state_data['creator_id']:
|
||
return "❌ 只有主持人可以结束游戏!"
|
||
|
||
state_data['status'] = 'finished'
|
||
self._save_game_state(chat_id, state_data)
|
||
|
||
return "✅ 游戏已结束"
|
||
|
||
def get_help(self) -> str:
|
||
"""获取帮助信息
|
||
|
||
Returns:
|
||
帮助文本
|
||
"""
|
||
help_text = """## 🐺 狼人杀游戏帮助
|
||
|
||
### 基础操作
|
||
- `.werewolf open` - 主持人创建房间
|
||
- `.werewolf join` - 加入游戏(需要注册用户名和个人URL)
|
||
- `.werewolf start` - 主持人开始游戏
|
||
- `.werewolf status` - 查看游戏状态
|
||
- `.werewolf end` - 主持人结束游戏
|
||
|
||
### 私聊功能
|
||
- `.werewolf <玩家代号> <消息>` - 私聊指定玩家
|
||
- `.werewolf 狼人 <消息>` - 狼人群聊(仅狼人)
|
||
|
||
### 技能指令
|
||
- `.werewolf 杀 <id>` - 狼人投票刀人
|
||
- `.werewolf 验 <id>` - 预言家验人
|
||
- `.werewolf 救 <id>` - 女巫救人
|
||
- `.werewolf 毒 <id>` - 女巫毒人
|
||
|
||
### 游戏规则
|
||
**人数配置**:
|
||
- 6人:2狼 1预言家 1女巫 2平民
|
||
- 8人:2狼 1预言家 1女巫 4平民
|
||
- 10人:3狼 1预言家 1女巫 5平民
|
||
- 12人:4狼 1预言家 1女巫 6平民
|
||
|
||
**胜利条件**:
|
||
- 狼人阵营:杀死所有神职和平民
|
||
- 好人阵营:消灭所有狼人
|
||
|
||
**游戏流程**:
|
||
1. 主持人创建房间
|
||
2. 玩家加入游戏
|
||
3. 主持人开始游戏,玩家收到身份
|
||
4. 夜晚阶段:狼人刀人、预言家验人、女巫用药
|
||
5. 白天阶段:死亡公示、讨论发言、投票放逐
|
||
|
||
---
|
||
💡 提示:使用私聊功能前必须先注册用户名和个人URL
|
||
"""
|
||
return help_text
|
||
|