feat(赛马插件): 调整参与奖励并优化赛马显示对齐

- 将参与奖励从50点降低到20点以平衡经济系统
- 为所有马主添加参与奖励计算和发放逻辑
- 优化赛况显示中的马名对齐,支持中文字符宽度计算
This commit is contained in:
2026-04-06 23:21:21 +08:00
parent aca33820fc
commit 498d39b676
3 changed files with 21 additions and 2 deletions

View File

@@ -146,6 +146,10 @@ def _describe_points_delta(delta: int) -> str:
def _build_point_changes(room: Room, odds: dict[str, float]) -> tuple[dict[str, int], dict[str, str]]: def _build_point_changes(room: Room, odds: dict[str, float]) -> tuple[dict[str, int], dict[str, str]]:
point_changes: dict[str, int] = {} point_changes: dict[str, int] = {}
# Participation reward for all horse owners
for horse in room.horses.values():
point_changes[horse.owner_id] = point_changes.get(horse.owner_id, 0) + config.PARTICIPANT_REWARD
for bet in room.bets: for bet in room.bets:
point_changes[bet.user_id] = point_changes.get(bet.user_id, 0) - bet.amount point_changes[bet.user_id] = point_changes.get(bet.user_id, 0) - bet.amount
@@ -202,6 +206,10 @@ async def settle_race(room: Room) -> RaceResult | None:
if not champion: if not champion:
return None return None
# Reward all participants
for horse in room.horses.values():
await points_service.reward_participant(horse.owner_id)
# Reward champion owner # Reward champion owner
await points_service.reward_champion(champion.owner_id) await points_service.reward_champion(champion.owner_id)

View File

@@ -16,7 +16,7 @@ class Config(BaseSettings):
ALLOWED_GROUPS: set[int] = Field(default_factory=set) ALLOWED_GROUPS: set[int] = Field(default_factory=set)
# 奖励配置 # 奖励配置
PARTICIPANT_REWARD: int = 50 PARTICIPANT_REWARD: int = 20
CHAMPION_REWARD: int = 200 CHAMPION_REWARD: int = 200
MIN_BET: int = 10 MIN_BET: int = 10
MIN_ODDS: float = 1.2 MIN_ODDS: float = 1.2

View File

@@ -58,10 +58,21 @@ class RaceEngine:
lines = [f"【第{room.tick_count}回合】"] lines = [f"【第{room.tick_count}回合】"]
sorted_horses = sorted(room.horses.values(), key=lambda h: h.index) sorted_horses = sorted(room.horses.values(), key=lambda h: h.index)
# Calculate max display width for name alignment
# Each CJK/fullwidth char counts as 2, others as 1
def _display_width(s: str) -> int:
w = 0
for ch in s:
w += 2 if '\u4e00' <= ch <= '\u9fff' or '\u3000' <= ch <= '\u303f' or '\uff00' <= ch <= '\uffef' else 1
return w
max_name_width = max(_display_width(h.name) for h in sorted_horses)
for horse in sorted_horses: for horse in sorted_horses:
progress = min(horse.position / distance, 1.0) progress = min(horse.position / distance, 1.0)
filled = int(progress * bar_width) filled = int(progress * bar_width)
bar = "" * filled + "" * (bar_width - filled) bar = "" * filled + "" * (bar_width - filled)
lines.append(f" {horse.index:02d}{horse.name} |{bar}| {horse.position:.1f}m") pad = " " * (max_name_width - _display_width(horse.name))
lines.append(f" {horse.index:02d}{horse.name}{pad} |{bar}| {horse.position:.1f}m")
return "\n".join(lines) return "\n".join(lines)