1.调整冒险任务的单位2.提升冒险任务的收益

This commit is contained in:
2025-10-31 17:37:02 +08:00
parent c1e3082f08
commit e99d8f4914
2 changed files with 184 additions and 32 deletions

View File

@@ -0,0 +1,80 @@
# 背景
文件名2025-10-31_1_change-adventure-time-to-seconds.md
创建于2025-10-31_17:30:37
创建者admin
主分支main
任务分支main
Yolo模式Off
# 任务描述
将冒险系统的计时单位从分钟更改为秒。需要修改所有相关的时间计算、验证逻辑、显示文本和帮助信息。
## 后续需求
支持时间格式输入(如 `1h30m10s`),并在显示时按时分秒格式显示,避免只显示秒数过于冗余。
# 项目概览
修改 `games/adventure.py` 文件,将冒险时间单位从分钟改为秒。
# 分析
当前代码中所有时间相关逻辑都以分钟为单位:
- 默认值1分钟
- 参数验证至少1分钟
- 时间计算:`cost_time * 60` 转换为秒
- 显示文本:所有提示信息都显示"分钟"
- 奖励计算:倍率 × 分钟数
- 放弃冒险:按分钟计算已消耗时间
需要将所有相关逻辑改为秒为单位。
# 提议的解决方案
将所有时间单位从分钟改为秒:
1. 修改默认值和参数验证
2. 移除时间计算中的 `* 60` 转换
3. 更新所有显示文本
4. 简化剩余时间显示逻辑(直接显示秒)
5. 更新帮助信息
# 当前执行步骤:"已完成"
# 任务进度
## 2025-10-31_17:32:32
- 已修改games/adventure.py
- 更改:
1. 修改默认值注释:从"1分钟"改为"1秒"
2. 修改函数文档cost_time参数从"(分钟)"改为"(秒)"
3. 修改参数验证:错误提示从"至少需要1分钟"改为"至少需要1秒"
4. 移除时间转换:将`end_time = start_time + saved_cost_time * 60`改为`end_time = start_time + saved_cost_time`
5. 更新显示文本:所有"分钟"改为"秒"(冒险结果、冒险进行中、冒险开始、冒险放弃)
6. 简化剩余时间显示:移除分钟/秒的转换逻辑,直接显示秒数
7. 修改放弃冒险逻辑时间计算改为直接使用秒数elapsed_seconds移除分钟转换
8. 更新帮助信息:所有"分钟"改为"秒"
- 原因:将冒险系统计时单位从分钟改为秒,使时间控制更精确
- 阻碍因素:无
- 状态:成功
## 2025-10-31_17:35:06
- 已修改games/adventure.py
- 更改:
1. 添加 `re` 模块导入,用于正则表达式解析
2. 新增 `_parse_time_string` 方法:解析时间格式字符串,支持以下格式:
- 纯数字(按秒):`60` -> 60秒
- 时分秒组合:`1h30m10s` -> 5410秒
- 分钟秒组合:`30m10s` -> 1810秒
- 只有小时:`1h` -> 3600秒
- 只有分钟:`30m` -> 1800秒
- 只有秒:`10s` -> 10秒
3. 新增 `_format_time` 方法:将秒数格式化为 "X时X分X秒" 格式自动省略为0的部分
4. 修改 `handle` 方法:使用 `_parse_time_string` 解析时间参数,提供格式错误提示
5. 更新所有时间显示位置:
- 冒险结果:使用 `_format_time` 格式化消耗时间
- 冒险进行中:使用 `_format_time` 格式化剩余时间和总时长
- 冒险开始:使用 `_format_time` 格式化持续时间
- 冒险放弃:使用 `_format_time` 格式化已计入时间
6. 更新帮助信息:添加时间格式说明和示例
- 原因:支持更灵活的时间输入格式,提升用户体验;时间显示按时分秒格式,避免冗长的秒数显示
- 阻碍因素:无
- 状态:待确认
# 最终审查

View File

@@ -2,6 +2,7 @@
import random
import time
import logging
import re
from datetime import datetime
from games.base import BaseGame
from utils.parser import CommandParser
@@ -22,19 +23,86 @@ class AdventureGame(BaseGame):
# 奖品池配置
self.prize_pool: List[Tuple[int, float, str]] = [
# (权重, 倍率, 描述)
(500, 0.5, "少量积分"),
(350, 1, "中等积分"),
(300, 1, "少量积分"),
(250, 2, "中等积分"),
(200, 2, "大量积分"),
(100, 5, "丰厚积分"),
(50, 10, "丰厚积分"),
(10, 100, "🌟 巨额积分"),
(1, 1000, "💎 传说积分"),
(150, 5, "丰厚积分"),
(100, 10, "丰厚积分"),
(50, 100, "🌟 巨额积分"),
(10, 1000, "💎 传说积分"),
]
self.total_weight: int = 0
for weight,_,_ in self.prize_pool:
self.total_weight += weight
def _parse_time_string(self, time_str: str) -> int:
"""解析时间字符串,支持 h/m/s 格式
支持的格式示例:
- "1h30m10s" -> 5410秒
- "30m" -> 1800秒
- "10s" -> 10秒
- "1h30m" -> 5400秒
- "3600" -> 3600秒纯数字按秒处理
Args:
time_str: 时间字符串
Returns:
解析后的秒数如果解析失败返回None
"""
if not time_str:
return None
# 如果是纯数字,直接返回
if time_str.isdigit():
return int(time_str)
# 使用正则表达式匹配 h/m/s 格式,确保整个字符串匹配
pattern = r'^(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?$'
match = re.match(pattern, time_str.lower())
if not match:
return None
hours = int(match.group(1) or 0)
minutes = int(match.group(2) or 0)
seconds = int(match.group(3) or 0)
# 如果所有值都是0返回None
if hours == 0 and minutes == 0 and seconds == 0:
return None
total_seconds = hours * 3600 + minutes * 60 + seconds
return total_seconds
def _format_time(self, seconds: int) -> str:
"""将秒数格式化为 "X时X分X秒" 格式
Args:
seconds: 秒数
Returns:
格式化的时间字符串,如 "1时30分10秒""30分10秒""10秒"
"""
if seconds < 0:
seconds = 0
hours = seconds // 3600
minutes = (seconds % 3600) // 60
secs = seconds % 60
parts = []
if hours > 0:
parts.append(f"{hours}")
if minutes > 0:
parts.append(f"{minutes}")
if secs > 0 or not parts:
parts.append(f"{secs}")
return "".join(parts)
async def handle(self, command: str, chat_id: int, user_id: int) -> str:
"""处理冒险相关指令
@@ -60,12 +128,16 @@ class AdventureGame(BaseGame):
if args in ['abandon', '放弃']:
return await self._abandon_adventure(chat_id, user_id)
# 默认冒险耗时1分钟
# 默认冒险耗时1
else:
# 解析消耗时间
cost_time = 1 # 默认消耗1分钟
if args.isdigit():
cost_time = int(args)
cost_time = 1 # 默认消耗1
if args:
parsed_time = self._parse_time_string(args)
if parsed_time is not None:
cost_time = parsed_time
else:
return f"❌ 时间格式错误!请使用以下格式:\n- 纯数字(秒):`.adventure 60`\n- 时分秒格式:`.adventure 1h30m10s`\n- 分钟秒格式:`.adventure 30m10s`\n- 只有秒:`.adventure 10s`"
return await self._perform_adventure(chat_id, user_id, cost_time)
@@ -79,14 +151,14 @@ class AdventureGame(BaseGame):
Args:
chat_id: 会话ID使用0作为用户级标识
user_id: 用户ID
cost_time: 消耗时间(分钟
cost_time: 消耗时间(
Returns:
抽奖结果消息
"""
# 参数验证
if cost_time < 1:
return "❌ 冒险时间至少需要1分钟"
return "❌ 冒险时间至少需要1"
# 查询冒险状态使用chat_id=0表示用户级状态
state = self.db.get_game_state(0, user_id, 'adventure')
@@ -98,7 +170,7 @@ class AdventureGame(BaseGame):
state_data = state['state_data']
start_time = state_data.get('start_time', 0)
saved_cost_time = state_data.get('cost_time', 1)
end_time = start_time + saved_cost_time * 60
end_time = start_time + saved_cost_time
remaining_seconds = end_time - current_time
# 情况1.1:冒险已完成(时间已到或过期)
@@ -120,8 +192,9 @@ class AdventureGame(BaseGame):
updated_points = self.db.get_user_points(user_id)
# 格式化输出
time_str = self._format_time(saved_cost_time)
text = f"## ⚡️ 冒险结果\n\n"
text += f"**消耗时间**: {saved_cost_time} 分钟\n\n"
text += f"**消耗时间**: {time_str}\n\n"
text += f"**{reward['description']}**: 获得 {reward_points} 积分\n\n"
text += f"**当前积分**: {updated_points['points']}\n\n"
text += "---\n\n"
@@ -130,17 +203,12 @@ class AdventureGame(BaseGame):
return text
# 情况1.2:冒险未完成,返回等待提示
remaining_minutes = remaining_seconds // 60
remaining_secs = remaining_seconds % 60
if remaining_minutes > 0:
wait_msg = f"{remaining_minutes}{remaining_secs}"
else:
wait_msg = f"{remaining_secs}"
wait_msg = self._format_time(remaining_seconds)
saved_time_str = self._format_time(saved_cost_time)
text = f"## ⚡️ 冒险进行中\n\n"
text += f"你正在进行一次冒险,还需等待 **{wait_msg}** 才能完成。\n\n"
text += f"**当前冒险时长**: {saved_cost_time} 分钟\n\n"
text += f"**当前冒险时长**: {saved_time_str}\n\n"
text += "---\n\n"
text += "💡 提示:冒险期间无法进行炼金,请耐心等待!"
@@ -162,12 +230,13 @@ class AdventureGame(BaseGame):
self.db.save_game_state(0, user_id, 'adventure', state_data)
# 计算预计完成时间
end_time = current_time + cost_time * 60
end_time = current_time + cost_time
end_datetime = datetime.fromtimestamp(end_time)
end_time_str = end_datetime.strftime('%H:%M:%S')
cost_time_str = self._format_time(cost_time)
text = f"## ⚡️ 冒险开始\n\n"
text += f"你已经开始了冒险之旅,本次冒险将持续 **{cost_time}** 分钟\n\n"
text += f"你已经开始了冒险之旅,本次冒险将持续 **{cost_time_str}**。\n\n"
text += f"**预计完成时间**: {end_time_str}\n\n"
text += "---\n\n"
text += "💡 提示:冒险期间无法进行炼金,完成后使用 `.adventure` 获取奖励!"
@@ -200,9 +269,8 @@ class AdventureGame(BaseGame):
current_time = int(time.time())
elapsed_seconds = max(0, current_time - int(start_time))
elapsed_minutes = elapsed_seconds // 60
if elapsed_minutes < 1:
elapsed_minutes = 1
if elapsed_seconds < 1:
elapsed_seconds = 1
# 计算最低倍率
try:
@@ -211,7 +279,7 @@ class AdventureGame(BaseGame):
# 兜底若奖池异常按0.5处理
min_multiplier = 0.5
reward_points = int(min_multiplier * elapsed_minutes)
reward_points = int(min_multiplier * elapsed_seconds)
if reward_points < 0:
reward_points = 0
@@ -224,8 +292,9 @@ class AdventureGame(BaseGame):
updated_points = self.db.get_user_points(user_id)
# 输出
elapsed_time_str = self._format_time(elapsed_seconds)
text = f"## ⚡️ 冒险放弃\n\n"
text += f"**已计入时间**: {elapsed_minutes} 分钟\n\n"
text += f"**已计入时间**: {elapsed_time_str}\n\n"
text += f"**最低倍率**: {min_multiplier}\n\n"
text += f"**获得积分**: {reward_points}\n\n"
text += f"**当前积分**: {updated_points['points']}\n\n"
@@ -272,9 +341,12 @@ class AdventureGame(BaseGame):
"""
text = f"## ⚡️ 冒险系统\n\n"
text += f"### 基础用法\n"
text += f"- `.adventure` - 消耗1分钟进行冒险\n"
text += f"- `.adventure time` - 消耗time分钟进行冒险, 最少一分钟\n"
text += f"- `.adventure` - 消耗1进行冒险\n"
text += f"- `.adventure 60` - 消耗60秒进行冒险\n"
text += f"- `.adventure 1h30m10s` - 消耗1小时30分10秒进行冒险\n"
text += f"- `.adventure 30m` - 消耗30分钟进行冒险\n"
text += f"- `.adventure 10s` - 消耗10秒进行冒险\n\n"
text += f"**时间格式说明**:支持时分秒组合,如 `1h30m10s`、`30m`、`10s`,也支持纯数字(按秒计算)。\n\n"
text += f"### 其他功能\n"
text += f"- `.adventure abandon` - 放弃当前冒险,按最低倍率结算已冒险时间\n"
text += f"- `.adventure 放弃` - 放弃当前冒险,按最低倍率结算已冒险时间\n"