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 random
import time import time
import logging import logging
import re
from datetime import datetime from datetime import datetime
from games.base import BaseGame from games.base import BaseGame
from utils.parser import CommandParser from utils.parser import CommandParser
@@ -22,19 +23,86 @@ class AdventureGame(BaseGame):
# 奖品池配置 # 奖品池配置
self.prize_pool: List[Tuple[int, float, str]] = [ self.prize_pool: List[Tuple[int, float, str]] = [
# (权重, 倍率, 描述) # (权重, 倍率, 描述)
(500, 0.5, "少量积分"), (300, 1, "少量积分"),
(350, 1, "中等积分"), (250, 2, "中等积分"),
(200, 2, "大量积分"), (200, 2, "大量积分"),
(100, 5, "丰厚积分"), (150, 5, "丰厚积分"),
(50, 10, "丰厚积分"), (100, 10, "丰厚积分"),
(10, 100, "🌟 巨额积分"), (50, 100, "🌟 巨额积分"),
(1, 1000, "💎 传说积分"), (10, 1000, "💎 传说积分"),
] ]
self.total_weight: int = 0 self.total_weight: int = 0
for weight,_,_ in self.prize_pool: for weight,_,_ in self.prize_pool:
self.total_weight += weight 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: async def handle(self, command: str, chat_id: int, user_id: int) -> str:
"""处理冒险相关指令 """处理冒险相关指令
@@ -60,12 +128,16 @@ class AdventureGame(BaseGame):
if args in ['abandon', '放弃']: if args in ['abandon', '放弃']:
return await self._abandon_adventure(chat_id, user_id) return await self._abandon_adventure(chat_id, user_id)
# 默认冒险耗时1分钟 # 默认冒险耗时1
else: else:
# 解析消耗时间 # 解析消耗时间
cost_time = 1 # 默认消耗1分钟 cost_time = 1 # 默认消耗1
if args.isdigit(): if args:
cost_time = int(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) return await self._perform_adventure(chat_id, user_id, cost_time)
@@ -79,14 +151,14 @@ class AdventureGame(BaseGame):
Args: Args:
chat_id: 会话ID使用0作为用户级标识 chat_id: 会话ID使用0作为用户级标识
user_id: 用户ID user_id: 用户ID
cost_time: 消耗时间(分钟 cost_time: 消耗时间(
Returns: Returns:
抽奖结果消息 抽奖结果消息
""" """
# 参数验证 # 参数验证
if cost_time < 1: if cost_time < 1:
return "❌ 冒险时间至少需要1分钟" return "❌ 冒险时间至少需要1"
# 查询冒险状态使用chat_id=0表示用户级状态 # 查询冒险状态使用chat_id=0表示用户级状态
state = self.db.get_game_state(0, user_id, 'adventure') state = self.db.get_game_state(0, user_id, 'adventure')
@@ -98,7 +170,7 @@ class AdventureGame(BaseGame):
state_data = state['state_data'] state_data = state['state_data']
start_time = state_data.get('start_time', 0) start_time = state_data.get('start_time', 0)
saved_cost_time = state_data.get('cost_time', 1) 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 remaining_seconds = end_time - current_time
# 情况1.1:冒险已完成(时间已到或过期) # 情况1.1:冒险已完成(时间已到或过期)
@@ -120,8 +192,9 @@ class AdventureGame(BaseGame):
updated_points = self.db.get_user_points(user_id) updated_points = self.db.get_user_points(user_id)
# 格式化输出 # 格式化输出
time_str = self._format_time(saved_cost_time)
text = f"## ⚡️ 冒险结果\n\n" 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"**{reward['description']}**: 获得 {reward_points} 积分\n\n"
text += f"**当前积分**: {updated_points['points']}\n\n" text += f"**当前积分**: {updated_points['points']}\n\n"
text += "---\n\n" text += "---\n\n"
@@ -130,17 +203,12 @@ class AdventureGame(BaseGame):
return text return text
# 情况1.2:冒险未完成,返回等待提示 # 情况1.2:冒险未完成,返回等待提示
remaining_minutes = remaining_seconds // 60 wait_msg = self._format_time(remaining_seconds)
remaining_secs = remaining_seconds % 60 saved_time_str = self._format_time(saved_cost_time)
if remaining_minutes > 0:
wait_msg = f"{remaining_minutes}{remaining_secs}"
else:
wait_msg = f"{remaining_secs}"
text = f"## ⚡️ 冒险进行中\n\n" text = f"## ⚡️ 冒险进行中\n\n"
text += f"你正在进行一次冒险,还需等待 **{wait_msg}** 才能完成。\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 += "---\n\n"
text += "💡 提示:冒险期间无法进行炼金,请耐心等待!" text += "💡 提示:冒险期间无法进行炼金,请耐心等待!"
@@ -162,12 +230,13 @@ class AdventureGame(BaseGame):
self.db.save_game_state(0, user_id, 'adventure', state_data) 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_datetime = datetime.fromtimestamp(end_time)
end_time_str = end_datetime.strftime('%H:%M:%S') end_time_str = end_datetime.strftime('%H:%M:%S')
cost_time_str = self._format_time(cost_time)
text = f"## ⚡️ 冒险开始\n\n" 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 += f"**预计完成时间**: {end_time_str}\n\n"
text += "---\n\n" text += "---\n\n"
text += "💡 提示:冒险期间无法进行炼金,完成后使用 `.adventure` 获取奖励!" text += "💡 提示:冒险期间无法进行炼金,完成后使用 `.adventure` 获取奖励!"
@@ -200,9 +269,8 @@ class AdventureGame(BaseGame):
current_time = int(time.time()) current_time = int(time.time())
elapsed_seconds = max(0, current_time - int(start_time)) elapsed_seconds = max(0, current_time - int(start_time))
elapsed_minutes = elapsed_seconds // 60 if elapsed_seconds < 1:
if elapsed_minutes < 1: elapsed_seconds = 1
elapsed_minutes = 1
# 计算最低倍率 # 计算最低倍率
try: try:
@@ -211,7 +279,7 @@ class AdventureGame(BaseGame):
# 兜底若奖池异常按0.5处理 # 兜底若奖池异常按0.5处理
min_multiplier = 0.5 min_multiplier = 0.5
reward_points = int(min_multiplier * elapsed_minutes) reward_points = int(min_multiplier * elapsed_seconds)
if reward_points < 0: if reward_points < 0:
reward_points = 0 reward_points = 0
@@ -224,8 +292,9 @@ class AdventureGame(BaseGame):
updated_points = self.db.get_user_points(user_id) updated_points = self.db.get_user_points(user_id)
# 输出 # 输出
elapsed_time_str = self._format_time(elapsed_seconds)
text = f"## ⚡️ 冒险放弃\n\n" 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"**最低倍率**: {min_multiplier}\n\n"
text += f"**获得积分**: {reward_points}\n\n" text += f"**获得积分**: {reward_points}\n\n"
text += f"**当前积分**: {updated_points['points']}\n\n" text += f"**当前积分**: {updated_points['points']}\n\n"
@@ -272,9 +341,12 @@ class AdventureGame(BaseGame):
""" """
text = f"## ⚡️ 冒险系统\n\n" text = f"## ⚡️ 冒险系统\n\n"
text += f"### 基础用法\n" text += f"### 基础用法\n"
text += f"- `.adventure` - 消耗1分钟进行冒险\n" text += f"- `.adventure` - 消耗1进行冒险\n"
text += f"- `.adventure time` - 消耗time分钟进行冒险, 最少一分钟\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"### 其他功能\n"
text += f"- `.adventure abandon` - 放弃当前冒险,按最低倍率结算已冒险时间\n" text += f"- `.adventure abandon` - 放弃当前冒险,按最低倍率结算已冒险时间\n"
text += f"- `.adventure 放弃` - 放弃当前冒险,按最低倍率结算已冒险时间\n" text += f"- `.adventure 放弃` - 放弃当前冒险,按最低倍率结算已冒险时间\n"