167 lines
5.0 KiB
Python
167 lines
5.0 KiB
Python
"""运势占卜游戏"""
|
||
import json
|
||
import random
|
||
import logging
|
||
import hashlib
|
||
from datetime import datetime
|
||
from pathlib import Path
|
||
from games.base import BaseGame
|
||
from utils.parser import CommandParser
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
class FortuneGame(BaseGame):
|
||
"""运势占卜游戏"""
|
||
|
||
def __init__(self):
|
||
"""初始化游戏"""
|
||
super().__init__()
|
||
self._fortunes = None
|
||
self._tarot = None
|
||
|
||
def _load_data(self):
|
||
"""懒加载运势数据"""
|
||
if self._fortunes is None:
|
||
try:
|
||
data_file = Path(__file__).parent.parent / "data" / "fortunes.json"
|
||
with open(data_file, 'r', encoding='utf-8') as f:
|
||
data = json.load(f)
|
||
self._fortunes = data.get('fortunes', [])
|
||
self._tarot = data.get('tarot', [])
|
||
logger.info("运势数据加载完成")
|
||
except Exception as e:
|
||
logger.error(f"加载运势数据失败: {e}")
|
||
self._fortunes = []
|
||
self._tarot = []
|
||
|
||
async def handle(self, command: str, chat_id: int, user_id: int) -> str:
|
||
"""处理运势占卜指令
|
||
|
||
Args:
|
||
command: 指令,如 ".fortune" 或 ".fortune tarot"
|
||
chat_id: 会话ID
|
||
user_id: 用户ID
|
||
|
||
Returns:
|
||
回复消息
|
||
"""
|
||
try:
|
||
# 加载数据
|
||
self._load_data()
|
||
|
||
# 提取参数
|
||
_, args = CommandParser.extract_command_args(command)
|
||
args = args.strip().lower()
|
||
|
||
# 塔罗牌
|
||
if args in ['tarot', '塔罗', '塔罗牌']:
|
||
return self._get_tarot(user_id)
|
||
|
||
# 默认:今日运势
|
||
return self._get_daily_fortune(user_id)
|
||
|
||
except Exception as e:
|
||
logger.error(f"处理运势占卜指令错误: {e}", exc_info=True)
|
||
return f"❌ 处理指令出错: {str(e)}"
|
||
|
||
def _get_daily_fortune(self, user_id: int) -> str:
|
||
"""获取今日运势
|
||
|
||
Args:
|
||
user_id: 用户ID
|
||
|
||
Returns:
|
||
运势信息
|
||
"""
|
||
if not self._fortunes:
|
||
return "❌ 运势数据加载失败"
|
||
|
||
# 基于日期和用户ID生成seed
|
||
# 同一用户同一天结果相同
|
||
today = datetime.now().strftime('%Y-%m-%d')
|
||
seed_str = f"{user_id}_{today}"
|
||
seed = int(hashlib.md5(seed_str.encode()).hexdigest(), 16) % (10 ** 8)
|
||
|
||
# 使用seed选择运势
|
||
random.seed(seed)
|
||
fortune = random.choice(self._fortunes)
|
||
|
||
# 生成幸运数字和幸运颜色(同样基于seed)
|
||
lucky_number = random.randint(1, 99)
|
||
lucky_colors = ["红色", "蓝色", "绿色", "黄色", "紫色", "粉色", "橙色"]
|
||
lucky_color = random.choice(lucky_colors)
|
||
|
||
# 重置随机seed
|
||
random.seed()
|
||
|
||
# 格式化输出
|
||
text = f"## 🔮 今日运势\n\n"
|
||
text += f"**日期**:{today}\n\n"
|
||
text += f"**运势**:{fortune['emoji']} <font color='{fortune['color']}'>{fortune['level']}</font>\n\n"
|
||
text += f"**运势解读**:{fortune['description']}\n\n"
|
||
text += f"**建议**:{fortune['advice']}\n\n"
|
||
text += f"**幸运数字**:{lucky_number}\n\n"
|
||
text += f"**幸运颜色**:{lucky_color}\n\n"
|
||
text += "---\n\n"
|
||
text += "💡 提示:运势仅供娱乐参考~"
|
||
|
||
return text
|
||
|
||
def _get_tarot(self, user_id: int) -> str:
|
||
"""抽塔罗牌
|
||
|
||
Args:
|
||
user_id: 用户ID
|
||
|
||
Returns:
|
||
塔罗牌信息
|
||
"""
|
||
if not self._tarot:
|
||
return "❌ 塔罗牌数据加载失败"
|
||
|
||
# 基于时间和用户ID生成seed(分钟级别变化)
|
||
now = datetime.now()
|
||
seed_str = f"{user_id}_{now.strftime('%Y-%m-%d-%H-%M')}"
|
||
seed = int(hashlib.md5(seed_str.encode()).hexdigest(), 16) % (10 ** 8)
|
||
|
||
# 使用seed选择塔罗牌
|
||
random.seed(seed)
|
||
card = random.choice(self._tarot)
|
||
|
||
# 重置随机seed
|
||
random.seed()
|
||
|
||
# 格式化输出
|
||
text = f"## 🃏 塔罗占卜\n\n"
|
||
text += f"**牌面**:{card['emoji']} {card['name']}\n\n"
|
||
text += f"**含义**:{card['meaning']}\n\n"
|
||
text += f"**建议**:{card['advice']}\n\n"
|
||
text += "---\n\n"
|
||
text += "💡 提示:塔罗牌指引方向,最终决定权在你手中~"
|
||
|
||
return text
|
||
|
||
def get_help(self) -> str:
|
||
"""获取帮助信息"""
|
||
return """## 🔮 运势占卜
|
||
|
||
### 基础用法
|
||
- `.fortune` - 查看今日运势
|
||
- `.运势` - 查看今日运势
|
||
- `.fortune tarot` - 抽塔罗牌
|
||
|
||
### 说明
|
||
- 同一天查询,运势结果相同
|
||
- 塔罗牌每分钟变化一次
|
||
- 仅供娱乐参考
|
||
|
||
### 示例
|
||
```
|
||
.fortune
|
||
.运势
|
||
.fortune tarot
|
||
```
|
||
"""
|
||
|