玩了一定数量的游戏后,如何更新ELO评分?

时间:2019-06-17 05:31:12

标签: c++

我有两个FIFA 19球员之间打过的比赛清单,并希望根据这些数据来更新我在两个球员之间的ELO评分。我正在尝试使用这些数据来不断更新ELO评分,该评分最初是从1000开始的。

我尝试使用按引用传递,但不确定如何将其实现,因为2个不同的函数调用相同的评级变量。

#include <iostream>
#include <cmath>
#include <string>
#include <fstream>
#include <vector>
#include <sstream>
using namespace std;

const int K = 20; //constant used in http://clubelo.com/Ranking

//tokenize and extract the number of goals only
vector <string> tokenize(string s){
    vector <string> tokens;
    stringstream check1(s);
    string intermediate;

    // Tokenizing w.r.t. space ' '
    while(getline(check1, intermediate, ' ')){
        tokens.push_back(intermediate);
    }

    return tokens;
}

//calculating goal difference to calculate ELO rating
int GoalDifference (int goalsA, int goalsB){
    int GoalDiff = abs(goalsA - goalsB);
    int G;

    if (GoalDiff == 0 || GoalDiff == 1)
        G = 1;
    else if (GoalDiff == 2)
        G = 3/2;
    else
        G = (11+GoalDiff)/8;

    return G;
}

//determine the result of the match by looking at goals
int result (int goalsA,int goalsB){
    int result;

    if (goalsA == goalsB)
        result = 0.5;
    else if (goalsA>goalsB)
        result = 1;
    else
        result = 0;

    return result;
}

// Function to calculate the Probability
float Probability(int rating1,int rating2){
    return 1.0 / (1.0 *pow(10, 1.0 * ((rating1 - rating2)) / 400)+1);
}

//calculating new ELO rating
int ELOratings (int rating, int goalsa, int goalsb, int probability){
    int deltapoints = K* GoalDifference(goalsa, goalsb) * (result(goalsa, goalsb) - probability);

    return rating + deltapoints;
}

int main(){
    int Ratinga = 1000, Ratingb = 1000;
    int goalsA, goalsB, probA, probB, ELOp1, ELOp2;

    ifstream inputFile;
    string input;
    inputFile.open("Scores of P1 vs P2.txt");
    vector <string> ScoreTokens;

    while (!inputFile.eof()) {
        getline(inputFile,input);
        ScoreTokens = tokenize(input);
        goalsA = stoi(ScoreTokens[1]);
        goalsB = stoi(ScoreTokens[3]);

        probA = Probability(Ratinga, Ratingb);
        probB = Probability(Ratingb, Ratinga);

        ELOp1 = ELOratings(Ratinga, goalsA, goalsB, probA);
        ELOp2 = ELOratings(Ratingb, goalsB, goalsA, probB);

        cout << "The new rating for P1 is: " << ELOp1 << endl;
        cout << "The new rating for P2 is: " << ELOp2 << endl << endl;
    }

    return 0;
}

以下是得分以及我如何提取数据的信息: P1 VS P2 利物浦2联2 Barca 2 Real 3

经过计算,在第一场比赛之后,每人的得分应为990。在第二场比赛之后,P1应该为970,P2应该为990。

但是在第一局之后实际的输出是1000。 第二局之后: P1:1000 P2:1020

1 个答案:

答案 0 :(得分:1)

问题是,您到处都使用整数进行涉及小数的计算。例如3/2等于1(不是1.5),因为它是整数除法,所以结果是整数。

这是固定的功能

//calculating goal difference to calculate ELO rating
double GoalDifference (int goalsA, int goalsB){
    int GoalDiff = abs(goalsA - goalsB);
    double G;

    if (GoalDiff == 0 || GoalDiff == 1)
        G = 1.0;
    else if (GoalDiff == 2)
        G = 1.5;
    else
        G = (11+GoalDiff)/8.0;

    return G;
}

请注意,返回结果也已更改为double,因为结果是小数。但是goalsAgoalsB仍然是整数,因为它们实际上是整数。

基本上,您需要检查代码,并在每一点问自己数字是整数还是小数,并进行适当的更改。

顺便说一句,floatdouble都可以用于分数,但总的来说,您应该选择double,因为它更精确且效率也不低。