基本公式
- Rn: 玩家比赛结束后的竞技分
- Ro: 玩家比赛前的竞技分
- K: 加成系数
- G: 胜负对局分
- Ge: 玩家预期得分
K取值范围
K值是一个常量系数,按照国际象棋里的标准, K值对于大师选手为16,对于一般选手是32
例如实际游戏中可以这么运用:
- 初学者 < 1000.0 K = 32.0 + (胜/负 * 32.0)
- 有经验者 < 1500.0 K = 32.0 + (胜/负 * 16.0)
- 熟练者 < 2000.0 K = 32.0
- 专家 < 2200.0 K = 20.0
- 大师 < 2400.0 K = 15.0
- 宗师 > 2400.0 K = 10.0
胜负取值
G取值范围
- 胜利 G = 1.0
- 平局 G = 0.5
- 失败 G = 0.0
Ge计算公式
1 2
| D = Rb - Ra Ge = 1 / (1 + pow(10, D / 400.0))
|
分母400是一个平衡的、万金油的值,让多数玩家积分保持标准正态分布的值
1 vs 1到N vs N扩展计算
从1 vs 1计算到N vs N计算,需要变化的是Ge值的计算。
1
| D = (Ra / A队总分 * B队总分) - Ra
|
ELO 1v1简单算法实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| #ifndef _ELORATING_H_ #define _ELORATING_H_
#include <math.h>
static const unsigned int deno = 400;
static const double novice = 1000.0; static const double someExp = 1500.0; static const double skill = 2000.0; static const double expert = 2200.0; static const double master = 2400.0;
static inline unsigned int adaptationK(double score, bool isWin) { return score < novice ? (32.0 + (isWin ? 32.0 : 0.0)) : score < someExp ? (32.0 + (isWin ? 16.0 : 0.0)) : score < skill ? 32.0 : score < expert ? 20.0 : score < master ? 15.0 : 10.0; }
static inline double getWinRate(double a, double b) { return 1.0 / (1.0 + pow(10, (b - a) / deno)); }
static inline double getScoreChg(double a, double b, bool isWin, bool isDraw) { double g = isDraw ? 0.5 : (isWin ? 1.0 : 0.0); double winRate = getWinRate(a, b); return (g - winRate) * adaptationK(a, isWin); }
static inline double calcResult(double a, double b, bool isWin, bool isDraw) { return (a + getScoreChg(a, b, isWin, isDraw)); }
#endif
|