初始化
This commit is contained in:
193
games/rps.py
Normal file
193
games/rps.py
Normal file
@@ -0,0 +1,193 @@
|
||||
"""石头剪刀布游戏"""
|
||||
import random
|
||||
import logging
|
||||
from games.base import BaseGame
|
||||
from utils.parser import CommandParser
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RPSGame(BaseGame):
|
||||
"""石头剪刀布游戏"""
|
||||
|
||||
# 选择列表
|
||||
CHOICES = ["石头", "剪刀", "布"]
|
||||
|
||||
# 胜负关系:key 击败 value
|
||||
WINS_AGAINST = {
|
||||
"石头": "剪刀",
|
||||
"剪刀": "布",
|
||||
"布": "石头"
|
||||
}
|
||||
|
||||
# 英文/表情符号映射
|
||||
CHOICE_MAP = {
|
||||
"石头": "石头", "rock": "石头", "🪨": "石头", "👊": "石头",
|
||||
"剪刀": "剪刀", "scissors": "剪刀", "✂️": "剪刀", "✌️": "剪刀",
|
||||
"布": "布", "paper": "布", "📄": "布", "✋": "布"
|
||||
}
|
||||
|
||||
async def handle(self, command: str, chat_id: int, user_id: int) -> str:
|
||||
"""处理石头剪刀布指令
|
||||
|
||||
Args:
|
||||
command: 指令,如 ".rps 石头" 或 ".rps stats"
|
||||
chat_id: 会话ID
|
||||
user_id: 用户ID
|
||||
|
||||
Returns:
|
||||
回复消息
|
||||
"""
|
||||
try:
|
||||
# 提取参数
|
||||
_, args = CommandParser.extract_command_args(command)
|
||||
args = args.strip()
|
||||
|
||||
# 查看战绩
|
||||
if args in ['stats', '战绩', '统计']:
|
||||
return self._get_stats(user_id)
|
||||
|
||||
# 没有参数,显示帮助
|
||||
if not args:
|
||||
return self.get_help()
|
||||
|
||||
# 解析用户选择
|
||||
player_choice = self._parse_choice(args)
|
||||
if not player_choice:
|
||||
return f"❌ 无效的选择:{args}\n\n{self.get_help()}"
|
||||
|
||||
# 机器人随机选择
|
||||
bot_choice = random.choice(self.CHOICES)
|
||||
|
||||
# 判定胜负
|
||||
result = self._judge(player_choice, bot_choice)
|
||||
|
||||
# 更新统计
|
||||
if result == 'win':
|
||||
self.db.update_game_stats(user_id, 'rps', win=True)
|
||||
elif result == 'loss':
|
||||
self.db.update_game_stats(user_id, 'rps', loss=True)
|
||||
elif result == 'draw':
|
||||
self.db.update_game_stats(user_id, 'rps', draw=True)
|
||||
|
||||
# 格式化输出
|
||||
return self._format_result(player_choice, bot_choice, result)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"处理石头剪刀布指令错误: {e}", exc_info=True)
|
||||
return f"❌ 处理指令出错: {str(e)}"
|
||||
|
||||
def _parse_choice(self, choice_str: str) -> str:
|
||||
"""解析用户选择
|
||||
|
||||
Args:
|
||||
choice_str: 用户输入的选择
|
||||
|
||||
Returns:
|
||||
标准化的选择(石头/剪刀/布)或空字符串
|
||||
"""
|
||||
choice_str = choice_str.lower().strip()
|
||||
return self.CHOICE_MAP.get(choice_str, "")
|
||||
|
||||
def _judge(self, player: str, bot: str) -> str:
|
||||
"""判定胜负
|
||||
|
||||
Args:
|
||||
player: 玩家选择
|
||||
bot: 机器人选择
|
||||
|
||||
Returns:
|
||||
'win', 'loss', 或 'draw'
|
||||
"""
|
||||
if player == bot:
|
||||
return 'draw'
|
||||
elif self.WINS_AGAINST[player] == bot:
|
||||
return 'win'
|
||||
else:
|
||||
return 'loss'
|
||||
|
||||
def _format_result(self, player_choice: str, bot_choice: str, result: str) -> str:
|
||||
"""格式化游戏结果
|
||||
|
||||
Args:
|
||||
player_choice: 玩家选择
|
||||
bot_choice: 机器人选择
|
||||
result: 游戏结果
|
||||
|
||||
Returns:
|
||||
格式化的Markdown消息
|
||||
"""
|
||||
# 表情符号映射
|
||||
emoji_map = {
|
||||
"石头": "🪨",
|
||||
"剪刀": "✂️",
|
||||
"布": "📄"
|
||||
}
|
||||
|
||||
text = f"## ✊ 石头剪刀布\n\n"
|
||||
text += f"**你出**:{emoji_map[player_choice]} {player_choice}\n\n"
|
||||
text += f"**我出**:{emoji_map[bot_choice]} {bot_choice}\n\n"
|
||||
|
||||
if result == 'win':
|
||||
text += "**结果**:<font color='#4CAF50'>🎉 你赢了!</font>\n"
|
||||
elif result == 'loss':
|
||||
text += "**结果**:<font color='#F44336'>😢 你输了!</font>\n"
|
||||
else:
|
||||
text += "**结果**:<font color='#FFC107'>🤝 平局!</font>\n"
|
||||
|
||||
return text
|
||||
|
||||
def _get_stats(self, user_id: int) -> str:
|
||||
"""获取用户战绩
|
||||
|
||||
Args:
|
||||
user_id: 用户ID
|
||||
|
||||
Returns:
|
||||
战绩信息
|
||||
"""
|
||||
stats = self.db.get_game_stats(user_id, 'rps')
|
||||
|
||||
total = stats['total_plays']
|
||||
if total == 0:
|
||||
return "📊 你还没有玩过石头剪刀布呢~\n\n快来试试吧!输入 `.rps 石头/剪刀/布` 开始游戏"
|
||||
|
||||
wins = stats['wins']
|
||||
losses = stats['losses']
|
||||
draws = stats['draws']
|
||||
win_rate = (wins / total * 100) if total > 0 else 0
|
||||
|
||||
text = f"## 📊 石头剪刀布战绩\n\n"
|
||||
text += f"**总局数**:{total} 局\n\n"
|
||||
text += f"**胜利**:{wins} 次 🎉\n\n"
|
||||
text += f"**失败**:{losses} 次 😢\n\n"
|
||||
text += f"**平局**:{draws} 次 🤝\n\n"
|
||||
text += f"**胜率**:<font color='#4CAF50'>{win_rate:.1f}%</font>\n"
|
||||
|
||||
return text
|
||||
|
||||
def get_help(self) -> str:
|
||||
"""获取帮助信息"""
|
||||
return """## ✊ 石头剪刀布
|
||||
|
||||
### 基础用法
|
||||
- `.rps 石头` - 出石头
|
||||
- `.rps 剪刀` - 出剪刀
|
||||
- `.rps 布` - 出布
|
||||
|
||||
### 其他指令
|
||||
- `.rps stats` - 查看战绩
|
||||
|
||||
### 支持的输入
|
||||
- 中文:石头、剪刀、布
|
||||
- 英文:rock、scissors、paper
|
||||
- 表情:🪨 ✂️ 📄
|
||||
|
||||
### 示例
|
||||
```
|
||||
.rps 石头
|
||||
.rps rock
|
||||
.rps 🪨
|
||||
```
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user