test(赛马插件): 添加模拟赛马测试命令

新增测试命令“测试模拟赛马”,用于验证赛马引擎的核心逻辑。该命令会:
- 自动创建包含8匹随机命名赛马的房间
- 运行赛马引擎直至比赛结束
- 验证进度渲染格式的正确性
- 输出比赛结果和进度片段

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

View File

@@ -2,7 +2,10 @@ from nonebot import on_command
from nonebot.adapters.onebot.v11 import Bot, Event, GroupMessageEvent, PrivateMessageEvent from nonebot.adapters.onebot.v11 import Bot, Event, GroupMessageEvent, PrivateMessageEvent
from . import plugin_config as config from . import plugin_config as config
from .commands import get_scope, check_access, room_store, points_service 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: async def check_tester(event: Event) -> bool:
@@ -104,3 +107,102 @@ async def handle_test_force_start(bot: Bot, event: Event):
return return
await test_force_start_cmd.finish("测试强制开赛命令") 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,
]
)
)