Files
DanDingNoneBot/danding_bot/plugins/group_horse_racing/test_commands.py
Mr.Xia c0798d127b test(赛马插件): 添加模拟赛马测试命令
新增测试命令“测试模拟赛马”,用于验证赛马引擎的核心逻辑。该命令会:
- 自动创建包含8匹随机命名赛马的房间
- 运行赛马引擎直至比赛结束
- 验证进度渲染格式的正确性
- 输出比赛结果和进度片段

这有助于在开发过程中快速验证赛马功能的完整性和正确性。
2026-04-04 17:08:45 +08:00

209 lines
6.7 KiB
Python
Raw 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.

from nonebot import on_command
from nonebot.adapters.onebot.v11 import Bot, Event, GroupMessageEvent, PrivateMessageEvent
from . import plugin_config as config
from .commands import get_scope, check_access, room_store, points_service, race_engine
from .models import Horse, HorseState, RoomState
import random
async def check_tester(event: Event) -> bool:
"""Check if user is a tester."""
if not config.TEST_MODE:
return False
return event.user_id in config.TESTERS
test_reset_points_cmd = on_command("测试重置积分", priority=5)
@test_reset_points_cmd.handle()
async def handle_test_reset_points(bot: Bot, event: Event):
"""Reset user points to 1000 for testing."""
if not await check_tester(event):
await test_reset_points_cmd.finish("权限不足")
return
success, _ = await points_service.set_points(event.user_id, 1000, "测试重置积分")
if success:
await test_reset_points_cmd.finish("积分已重置为1000")
else:
await test_reset_points_cmd.finish("重置失败")
test_set_points_cmd = on_command("测试设置积分", priority=5)
@test_set_points_cmd.handle()
async def handle_test_set_points(bot: Bot, event: Event):
"""Set user points for testing."""
if not await check_tester(event):
await test_set_points_cmd.finish("权限不足")
return
# Get the message text and extract amount
msg = str(event.get_message()).strip()
# Remove command prefix
parts = msg.split()
if len(parts) < 2:
await test_set_points_cmd.finish("请使用: /测试设置积分 <金额>")
return
try:
amount = int(parts[1])
if amount < 0:
await test_set_points_cmd.finish("金额必须为非负数")
return
except ValueError:
await test_set_points_cmd.finish("金额必须是整数")
return
success, _ = await points_service.set_points(event.user_id, amount, f"测试设置积分为{amount}")
if success:
await test_set_points_cmd.finish(f"积分已设置为 {amount}")
else:
await test_set_points_cmd.finish("设置失败")
test_query_points_cmd = on_command("测试查询积分", priority=5)
@test_query_points_cmd.handle()
async def handle_test_query_points(bot: Bot, event: Event):
"""Query user points for testing."""
if not await check_tester(event):
await test_query_points_cmd.finish("权限不足")
return
balance = await points_service.get_balance(event.user_id)
await test_query_points_cmd.finish(f"当前积分: {balance}")
test_clear_room_cmd = on_command("测试清空房间", priority=5)
@test_clear_room_cmd.handle()
async def handle_test_clear_room(bot: Bot, event: Event):
"""Clear test room."""
if not await check_tester(event):
await test_clear_room_cmd.finish("权限不足")
return
scope = get_scope(event)
room_store.delete_room(scope)
await test_clear_room_cmd.finish("房间已清空")
test_force_start_cmd = on_command("测试强制开赛", priority=5)
@test_force_start_cmd.handle()
async def handle_test_force_start(bot: Bot, event: Event):
"""Force start race for testing."""
if not await check_tester(event):
await test_force_start_cmd.finish("权限不足")
return
await test_force_start_cmd.finish("测试强制开赛命令")
def _generate_random_horse_names(count: int) -> list[str]:
prefixes = ["赤焰", "踏雪", "追风", "流星", "疾电", "破晓", "青岚", "玄影", "星尘", "霜刃", "烈阳", "苍穹"]
cores = ["", "", "", "", "", "", "", "", "", "", "", ""]
suffixes = ["", "", "", "", "", "", "", "", "", ""]
names: set[str] = set()
attempts = 0
while len(names) < count and attempts < 500:
attempts += 1
name = f"{random.choice(prefixes)}{random.choice(cores)}{random.choice(suffixes)}"
if len(name) > 10:
name = name[:10]
names.add(name)
while len(names) < count:
names.add(f"测试马{len(names) + 1}")
return list(names)[:count]
test_simulate_race_cmd = on_command("测试模拟赛马", priority=5)
@test_simulate_race_cmd.handle()
async def handle_test_simulate_race(bot: Bot, event: Event):
if not await check_tester(event):
await test_simulate_race_cmd.finish("权限不足")
return
scope = get_scope(event)
lock = room_store.get_lock(scope)
async with lock:
race_engine.stop_race(scope)
room_store.delete_room(scope)
room = room_store.create_room(scope)
horse_names = _generate_random_horse_names(8)
for idx, horse_name in enumerate(horse_names, start=1):
owner_id = f"sim_user_{idx}"
room.horses[horse_name] = Horse(owner_id=owner_id, name=horse_name, state=HorseState.RACING)
room.state = RoomState.RUNNING
progress_samples: list[str] = []
last_progress = ""
finished = []
for _ in range(1_000):
finished = race_engine.tick(room)
last_progress = race_engine.format_progress(room)
if len(progress_samples) < 3:
progress_samples.append(last_progress)
if finished:
break
if not finished:
race_engine.stop_race(scope)
room_store.delete_room(scope)
await test_simulate_race_cmd.finish("模拟失败:超过最大回合仍未结束")
return
champion = race_engine.determine_champion(finished)
room.champion_name = champion.name
room.state = RoomState.FINISHED
expected_lines = 1 + len(room.horses)
actual_lines = len(last_progress.splitlines())
if actual_lines != expected_lines:
race_engine.stop_race(scope)
room_store.delete_room(scope)
await test_simulate_race_cmd.finish(f"模拟失败:进度渲染行数不匹配(期望{expected_lines},实际{actual_lines}")
return
missing_names = [name for name in room.horses.keys() if name not in last_progress]
if missing_names:
race_engine.stop_race(scope)
room_store.delete_room(scope)
await test_simulate_race_cmd.finish(f"模拟失败:进度渲染缺少马名:{', '.join(missing_names)}")
return
race_engine.stop_race(scope)
room_store.delete_room(scope)
sample_block = "\n\n".join(progress_samples[-2:] + [last_progress] if len(progress_samples) >= 2 else [last_progress])
await test_simulate_race_cmd.finish(
"\n".join(
[
"模拟赛马完成",
f"参赛马匹:{', '.join(horse_names)}",
f"冠军:{room.champion_name}",
f"总回合:{room.tick_count}",
"进度片段:",
sample_block,
]
)
)