feat(赛马): 为马匹添加序号并优化积分结算展示

- 为 Horse 模型添加 index 字段,用于唯一标识马匹序号
- 在报名时自动分配递增序号,并在所有展示中使用固定序号排序
- 新增积分变化计算功能,在比赛结果中展示每位用户的积分变化和总结描述
- 支持通过序号或马匹名下注,优化用户交互体验
- 添加用户上次马名记忆功能,允许重复使用马名报名
- 更新测试用例以验证序号展示和积分变化功能
This commit is contained in:
2026-04-04 22:43:46 +08:00
parent 2214e22b80
commit 64020cb0e6
5 changed files with 190 additions and 56 deletions

View File

@@ -258,7 +258,8 @@ async def handle_test_simulate_race(bot: Bot, event: Event):
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.horses[horse_name] = Horse(owner_id=owner_id, name=horse_name, index=idx, state=HorseState.RACING)
room.next_horse_index = len(horse_names) + 1
bet_amount = max(commands_mod.config.MIN_BET, 10)
room.bets.append(Bet(user_id="bettor_1", horse_name=horse_names[0], amount=bet_amount))
@@ -282,15 +283,31 @@ async def handle_test_simulate_race(bot: Bot, event: Event):
if "比赛开始!" not in messages[0]:
await test_simulate_race_cmd.send("完全模拟失败:未发送开赛消息")
return
for idx, horse_name in enumerate(horse_names, start=1):
if f"{idx:02d}{horse_name}" not in messages[0]:
await test_simulate_race_cmd.send("完全模拟失败:开赛名单未按序号展示")
return
if not any("【第" in msg and "回合】" in msg for msg in messages):
progress_messages = [msg for msg in messages if "【第" in msg and "回合】" in msg]
if not progress_messages:
await test_simulate_race_cmd.send("完全模拟失败:未发送回合进度消息")
return
progress_lines = progress_messages[0].splitlines()[1:]
if len(progress_lines) != len(horse_names):
await test_simulate_race_cmd.send("完全模拟失败:回合进度展示条目数量不匹配")
return
for idx, line in enumerate(progress_lines, start=1):
if not line.strip().startswith(f"{idx:02d}"):
await test_simulate_race_cmd.send("完全模拟失败:回合进度未按报名序号固定排序")
return
result_msg = messages[-1]
if "比赛结束!冠军:" not in result_msg:
await test_simulate_race_cmd.send("完全模拟失败:未发送结束结算消息")
return
if "积分变化:" not in result_msg:
await test_simulate_race_cmd.send("完全模拟失败:未发送积分变化总结")
return
if not fake_room_store.saved_results:
await test_simulate_race_cmd.send("完全模拟失败:未写入赛史结果(内存)")
@@ -300,6 +317,12 @@ async def handle_test_simulate_race(bot: Bot, event: Event):
if saved.champion_name not in room.horses:
await test_simulate_race_cmd.send("完全模拟失败:赛史冠军不在参赛马匹中")
return
if not saved.point_changes:
await test_simulate_race_cmd.send("完全模拟失败:赛史未记录积分变化")
return
if not saved.point_change_summaries:
await test_simulate_race_cmd.send("完全模拟失败:赛史未记录积分变化总结")
return
champion_owner_id = room.horses[saved.champion_name].owner_id
reward_champion_calls = [c for c in fake_points_service.calls if c[0] == "reward_champion"]
@@ -321,6 +344,7 @@ async def handle_test_simulate_race(bot: Bot, event: Event):
f"总回合:{saved.duration_ticks}",
f"消息条数:{len(messages)}(开赛/进度/结算均已覆盖)",
f"结算调用:{len(fake_points_service.calls)}(冠军/参赛/下注派奖)",
f"积分变化用户数:{len(saved.point_changes)}",
f"过程展示:{'开启' if stream_progress else '关闭'}",
]
)