近期兼职做了个小游戏,有感于暴雪的WOW竞技场排名系统,于是用简单实现了一个ELO Rating来记分。
WOW的排名系统暴雪自称是“ELO Like”,是对ELO Rating做了一些改进的。我们这里先介绍一下标准的ELO Rating。ELO等级分系统是用来计算一个人在双人对决性比赛里的相对的技能等级的一个系统,最早应用于国际象棋和围棋。简单的说,就是把“实力”这种比较“虚”的东西数字化的一种办法。这个系统是由一个物理学教授Arpad Elo创立的,他同时也是一位国际象棋的大师。众所周知,“实力”这个东西是很难判断的,但是实力也是一个客观存在的东西。Elo教授作出了一个假定:一个人的实力在短期内是一定的,并且遵从某一个正态分布函数;长期来看,一个人的实力是缓慢的变化的。并由于国际象棋中很难判别每一步甚至每一局的价值,Elo教授引入了统计学,用统计一段时期内棋手的输赢的办法来衡量该棋手的实力,同时作出第二个假定:某一特定实力范畴里,相互之间的差别一般可预期,不会出现太大意外。比如强手未必每盘都赢另一个比他弱的选手,但是总体来说胜率要高。具体的数学公式这里就不列出来了,有兴趣的朋友去Google搜索下就找到。
下面是Java实现的一些片段:
public class SimpleEloRatingSystem {
public static double DEFAULT_ELO_K_FACTOR = 24.0;
public static String K_FACTOR_STRING="0-2099=32,2100-2399=24,2490-3000=16";
public final static double WIN = 1.0;
public final static double DRAW = 0.5;
public final static double LOSS = 0.0;
public KFactor [] kFactors = {};
private SimpleEloRatingSystem () {
if (K_FACTOR_STRING != null) {
StringTokenizer st1 = new StringTokenizer (K_FACTOR_STRING, ",");
kFactors = new KFactor [st1.countTokens()];
int index = 0;
while (st1.hasMoreTokens()) {
String kfr = st1.nextToken();
StringTokenizer st2 = new StringTokenizer (kfr, "=");
String range = st2.nextToken();
double value = Double.parseDouble (st2.nextToken());
st2 = new StringTokenizer (range, "-");
int startIndex = Integer.parseInt(st2.nextToken());
int endIndex = Integer.parseInt(st2.nextToken());
kFactors [index++] = new KFactor (startIndex, endIndex, value);
}
}
}
public int getNewRating (int rating, int opponentRating, int resultType) {
switch (resultType) {
case Constants.WIN:
return getNewRating (rating, opponentRating, WIN);
case Constants.LOSE:
return getNewRating (rating, opponentRating, LOSS);
case Constants.DRAW:
return getNewRating (rating, opponentRating, DRAW);
}
return -1;
}
public int getNewRating(int rating, int opponentRating, double score) {
double kFactor = getKFactor(rating);
double expectedScore = getExpectedScore(rating, opponentRating);
int newRating = calculateNewRating(rating, score, expectedScore, kFactor);
return newRating;
}
private int calculateNewRating(int oldRating, double score, double expectedScore, double kFactor) {
return oldRating + (int) (kFactor * (score - expectedScore));
}
private double getKFactor (int rating) {
// Return the correct k factor.
for (int i = 0; i < kFactors.length; i++)
if (rating >= kFactors[i].getStartIndex() &&
rating <= kFactors[i].getEndIndex())
{
return kFactors[i].value;
}
return DEFAULT_ELO_K_FACTOR;
}
private double getExpectedScore (int rating, int opponentRating) {
return 1.0 / (1.0 + Math.pow(10.0, ((double) (opponentRating - rating) / 400.0)));
}
public class KFactor {
private int startIndex, endIndex;
private double value;
public KFactor (int startIndex, int endIndex, double value) {
this.startIndex = startIndex;
this.endIndex = endIndex;
this.value = value;
}
public int getStartIndex () { return startIndex; }
public int getEndIndex () { return endIndex; }
public double getValue () { return value; }
public String toString () {
return "kfactor: " + startIndex + " " + endIndex + " " + value;
}
}
}
分享到:
相关推荐
A simple implementation for the famous ELO Rating System. This resource contains a document(Chinese) that specifies the algorithm of ELO Rating and give some examples that shows to users how to ...
在游戏对战中,服务器需要实现一套公平的匹配算法,如Elo评级系统或MMR(Matchmaking Rating)系统,确保玩家能够找到实力相当的对手。同时,服务器要保证游戏状态的一致性,可能需要用到状态机或者基于事件驱动的...
后端Web应用程序的服务器端组件使用Java和Spring Framework以及MySQL和Hibernate。技术领域Maven-依赖关系管理和构建JUni5和Jupiter-测试Lombok-带注释的构造函数和getter / setter生成SLF4J-测井,注入...
在Java编程环境中,实现Elo Rating系统可以帮助我们为各种竞赛或比赛创建一个公平且动态的排名机制。本篇文章将深入探讨Elo Rating的基本原理、计算公式以及如何在Java中实现这一算法。 Elo Rating的核心思想是通过...
每个选手都有一个Elo评分,胜利会增加分数,失败则减少分数,具体增减量取决于比赛结果与预期结果的差距。 2. **EloRater的计算**:EloRater在计算时,会考虑双方棋手的当前Elo评分、比赛结果(胜、负、平)以及...
总的来说,Go Rating Estimator是一款专为围棋爱好者打造的实用工具,结合了开源精神与专业技术,旨在提供一个预测比赛积分变化的有效途径,从而助力玩家提升竞技状态,享受更加精彩的围棋比赛。通过参与开源社区,...
在这个项目“peer-prediction-analysis”中,我们看到的是一个用于分析此类实验数据的Java实现。 首先,让我们深入理解对等预测的基本原理。在对等预测实验中,每个参与者都需要预测其他参与者的某些行为或结果,如...