Files
bl/logic/service/fight/md/elo-rating-system.md
昔念 cf74930e6e refactor: 删除战斗模块冗余代码,增加克洛斯地心入口
- 移除了 fight 包下多个冗余的结构体和接口定义
- 删除了未使用的战斗状态机和技能限制效果相关代码
- 移除了多余的 XML 注释内容
2025-08-24 20:35:08 +08:00

244 lines
5.1 KiB
Go
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

# ELO评级系统
## 概述
为匹配框架引入了ELO评级系统为每个规则集单独维护ELO评级提供更精确的玩家技能评估和匹配质量
## 核心特性
### 🎯 规则集分离
- 每个规则集如休闲模式竞技模式独立维护ELO评级
- 玩家在不同规则集下有不同的ELO分数
- 支持无限扩展新的规则集
### 📊 标准ELO算法
- 基于经典ELO评级系统
- 期望得分计算`1 / (1 + 10^((对手ELO - 自己ELO) / 400))`
- 新ELO = 旧ELO + K * (实际得分 - 期望得分)
- 支持胜利(1)失败(0)平局(0.5)
### 动态K因子
- **新手** (< 30): K = 32 (快速调整)
- **普通** (30-100): K = 24 (中等调整)
- **老手** (> 100): K = 16 (稳定调整)
### 🛡 安全边界
- ELO范围100 - 3000
- 初始ELO1200
- 自动记录历史最高ELO
## 数据库设计
### player_elo_ratings
```sql
CREATE TABLE player_elo_ratings (
player_id TEXT NOT NULL, -- 玩家ID
rule_set_id TEXT NOT NULL, -- 规则集ID
elo_rating INTEGER DEFAULT 1200, -- 当前ELO评级
games_played INTEGER DEFAULT 0, -- 游戏场次
wins INTEGER DEFAULT 0, -- 胜利次数
losses INTEGER DEFAULT 0, -- 失败次数
draws INTEGER DEFAULT 0, -- 平局次数
highest_elo INTEGER DEFAULT 1200, -- 历史最高ELO
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
PRIMARY KEY (player_id, rule_set_id)
);
```
### 核心函数
- `get_or_create_player_elo()` - 获取或创建ELO记录
- `update_player_elo()` - 更新单个玩家ELO
- `batch_update_player_elos()` - 批量更新ELO战斗结束
- `get_elo_leaderboard()` - 获取排行榜
## API端点
### 排行榜
```
GET /api/v1/elo/leaderboard/:ruleSetId?limit=50&offset=0
```
### 玩家ELO信息
```
GET /api/v1/elo/player/:playerId/:ruleSetId
GET /api/v1/elo/player/:playerId # 所有规则集
```
### 统计信息
```
GET /api/v1/elo/statistics/:ruleSetId
```
### 战斗预测
```
GET /api/v1/elo/predict/:playerAId/:playerBId/:ruleSetId
```
### 配置信息
```
GET /api/v1/elo/config
GET /api/v1/elo/win-rate/:eloDifference
```
## 系统集成
### 战斗结束自动更新
战斗结束时`battleReportService` 会自动
1. 获取两个玩家的当前ELO
2. 根据战斗结果计算新ELO
3. 原子性批量更新数据库
4. 记录详细日志
```typescript
// 在 battleReportService.ts 中
if (battleData.ruleSetId && battleResult !== 'abandoned') {
await eloService.processBattleEloUpdate(
battleData.playerAId,
battleData.playerBId,
winnerId,
battleData.ruleSetId
)
}
```
### 匹配系统集成
匹配系统已支持规则集分离ELO系统可以
- 基于ELO进行更精确的匹配
- 预测战斗结果概率
- 提供匹配质量评估
## 部署步骤
### 1. 数据库迁移
在Supabase SQL编辑器中执行
```sql
-- 执行ELO系统迁移
\i packages/database/sql/06_add_elo_system.sql
```
### 2. 服务器更新
ELO系统已集成到现有服务器中无需额外配置
### 3. 测试验证
```bash
# 测试ELO计算逻辑
cd packages/server && npx tsx src/test-elo.ts
# 启动服务器测试API
node dist/cli.js server --port 8102
```
## 使用示例
### 获取排行榜
```bash
curl "http://localhost:8102/api/v1/elo/leaderboard/casual_standard_ruleset?limit=10"
```
### 查看玩家ELO
```bash
curl "http://localhost:8102/api/v1/elo/player/player123/casual_standard_ruleset"
```
### 预测战斗结果
```bash
curl "http://localhost:8102/api/v1/elo/predict/player1/player2/competitive_ruleset"
```
## 配置选项
ELO系统支持运行时配置调整
```typescript
const eloService = new EloService(repository, calculationService)
// 更新配置
eloService.updateEloConfig({
initialElo: 1500,
kFactor: {
newbie: 40,
normal: 20,
veteran: 10
},
minElo: 200,
maxElo: 2800
})
```
## 监控和日志
### 日志记录
- ELO更新详细日志
- 计算过程追踪
- 错误处理和恢复
### 性能监控
- 数据库查询优化
- 批量更新性能
- API响应时间
## 未来扩展
### 可能的增强功能
1. **季度重置** - 定期重置ELO评级
2. **衰减机制** - 长期不活跃玩家ELO衰减
3. **匹配优化** - 基于ELO的智能匹配
4. **成就系统** - ELO里程碑奖励
5. **数据分析** - ELO分布统计和趋势分析
### 扩展新规则集
添加新规则集只需
1. 在规则系统中定义新规则集
2. ELO系统自动支持无需代码修改
3. 玩家首次游戏时自动创建ELO记录
## 故障排除
### 常见问题
1. **ELO记录不存在**
- 系统会自动创建初始记录
- 检查规则集ID是否正确
2. **ELO更新失败**
- 检查数据库连接
- 查看服务器日志
- 验证战斗数据完整性
3. **API响应错误**
- 确认数据库迁移已执行
- 检查API路由注册
- 验证请求参数格式
### 调试工具
```bash
# 测试ELO计算
npx tsx packages/server/src/test-elo.ts
# 检查数据库表
SELECT * FROM player_elo_ratings LIMIT 10;
# 查看API状态
curl "http://localhost:8102/api/v1/elo/config"
```