Files
WPSBot/games/guess.py
2025-10-28 13:00:35 +08:00

241 lines
7.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""猜数字游戏"""
import random
import logging
import time
from games.base import BaseGame
from utils.parser import CommandParser
from config import GAME_CONFIG
logger = logging.getLogger(__name__)
class GuessGame(BaseGame):
"""猜数字游戏"""
def __init__(self):
"""初始化游戏"""
super().__init__()
self.config = GAME_CONFIG.get('guess', {})
self.min_number = self.config.get('min_number', 1)
self.max_number = self.config.get('max_number', 100)
self.max_attempts = self.config.get('max_attempts', 10)
async def handle(self, command: str, chat_id: int, user_id: int) -> str:
"""处理猜数字指令
Args:
command: 指令,如 ".guess start"".guess 50"
chat_id: 会话ID
user_id: 用户ID
Returns:
回复消息
"""
try:
# 提取参数
_, args = CommandParser.extract_command_args(command)
args = args.strip().lower()
# 开始游戏
if args in ['start', '开始']:
return self._start_game(chat_id, user_id)
# 结束游戏
if args in ['stop', '结束', 'end']:
return self._stop_game(chat_id, user_id)
# 尝试解析为数字
try:
guess = int(args)
return self._make_guess(chat_id, user_id, guess)
except ValueError:
return self.get_help()
except Exception as e:
logger.error(f"处理猜数字指令错误: {e}", exc_info=True)
return f"❌ 处理指令出错: {str(e)}"
def _start_game(self, chat_id: int, user_id: int) -> str:
"""开始新游戏
Args:
chat_id: 会话ID
user_id: 用户ID
Returns:
提示消息
"""
# 检查是否已有进行中的游戏
state = self.db.get_game_state(chat_id, user_id, 'guess')
if state:
state_data = state['state_data']
attempts = state_data.get('attempts', 0)
return f"⚠️ 你已经有一个进行中的游戏了!\n\n" \
f"已经猜了 {attempts} 次,继续猜测或输入 `.guess stop` 结束游戏"
# 生成随机数
target = random.randint(self.min_number, self.max_number)
# 保存游戏状态
state_data = {
'target': target,
'attempts': 0,
'guesses': [],
'max_attempts': self.max_attempts
}
self.db.save_game_state(chat_id, user_id, 'guess', state_data)
text = f"## 🔢 猜数字游戏开始!\n\n"
text += f"我想了一个 **{self.min_number}** 到 **{self.max_number}** 之间的数字\n\n"
text += f"你有 **{self.max_attempts}** 次机会猜对它\n\n"
text += f"输入 `.guess 数字` 开始猜测\n\n"
text += f"输入 `.guess stop` 结束游戏"
return text
def _make_guess(self, chat_id: int, user_id: int, guess: int) -> str:
"""进行猜测
Args:
chat_id: 会话ID
user_id: 用户ID
guess: 猜测的数字
Returns:
结果消息
"""
# 检查游戏状态
state = self.db.get_game_state(chat_id, user_id, 'guess')
if not state:
return f"⚠️ 还没有开始游戏呢!\n\n输入 `.guess start` 开始游戏"
state_data = state['state_data']
target = state_data['target']
attempts = state_data['attempts']
guesses = state_data['guesses']
max_attempts = state_data['max_attempts']
# 检查数字范围
if guess < self.min_number or guess > self.max_number:
return f"❌ 请输入 {self.min_number}{self.max_number} 之间的数字"
# 检查是否已经猜过
if guess in guesses:
return f"⚠️ 你已经猜过 {guess} 了!\n\n已猜过:{', '.join(map(str, sorted(guesses)))}"
# 更新状态
attempts += 1
guesses.append(guess)
# 判断结果
if guess == target:
# 猜对了!
self.db.delete_game_state(chat_id, user_id, 'guess')
self.db.update_game_stats(user_id, 'guess', win=True)
text = f"## 🎉 恭喜猜对了!\n\n"
text += f"**答案**<font color='#4CAF50'>{target}</font>\n\n"
text += f"**用了**{attempts}\n\n"
if attempts == 1:
text += "太神了!一次就猜中!🎯"
elif attempts <= 3:
text += "真厉害!运气爆棚!✨"
elif attempts <= 6:
text += "不错哦!🌟"
else:
text += "虽然用了不少次,但最终还是猜对了!💪"
return text
# 没猜对
if attempts >= max_attempts:
# 次数用完了
self.db.delete_game_state(chat_id, user_id, 'guess')
self.db.update_game_stats(user_id, 'guess', loss=True)
text = f"## 😢 游戏结束\n\n"
text += f"很遗憾,次数用完了\n\n"
text += f"**答案是**<font color='#F44336'>{target}</font>\n\n"
text += f"下次再来挑战吧!"
return text
# 继续猜
state_data['attempts'] = attempts
state_data['guesses'] = guesses
self.db.save_game_state(chat_id, user_id, 'guess', state_data)
# 提示大小
hint = "太大了 📉" if guess > target else "太小了 📈"
remaining = max_attempts - attempts
text = f"## ❌ {hint}\n\n"
text += f"**第 {attempts} 次猜测**{guess}\n\n"
text += f"**剩余机会**{remaining}\n\n"
# 给一些范围提示
smaller_guesses = [g for g in guesses if g < target]
larger_guesses = [g for g in guesses if g > target]
if smaller_guesses and larger_guesses:
min_larger = min(larger_guesses)
max_smaller = max(smaller_guesses)
text += f"💡 提示:答案在 **{max_smaller}** 和 **{min_larger}** 之间\n\n"
text += f"已猜过:{', '.join(map(str, sorted(guesses)))}"
return text
def _stop_game(self, chat_id: int, user_id: int) -> str:
"""结束游戏
Args:
chat_id: 会话ID
user_id: 用户ID
Returns:
提示消息
"""
state = self.db.get_game_state(chat_id, user_id, 'guess')
if not state:
return "⚠️ 当前没有进行中的游戏"
state_data = state['state_data']
target = state_data['target']
attempts = state_data['attempts']
self.db.delete_game_state(chat_id, user_id, 'guess')
text = f"## 🔢 游戏已结束\n\n"
text += f"**答案是**{target}\n\n"
text += f"你猜了 {attempts}\n\n"
text += "下次再来挑战吧!"
return text
def get_help(self) -> str:
"""获取帮助信息"""
return f"""## 🔢 猜数字游戏
### 基础用法
- `.guess start` - 开始游戏
- `.guess 数字` - 猜测数字
- `.guess stop` - 结束游戏
### 游戏规则
- 范围:{self.min_number} - {self.max_number}
- 机会:{self.max_attempts}
- 每次猜测后会提示"太大""太小"
- 猜对即可获胜
### 示例
```
.guess start # 开始游戏
.guess 50 # 猜50
.guess 75 # 猜75
.guess stop # 放弃游戏
```
"""