c++ - 玩了一定数量的游戏后如何更新 ELO 评级?

标签 c++

我有一份 FIFA 19 两名球员之间的比赛列​​表,我希望根据所参加的比赛使用该数据更新我在这两名球员之间的 ELO 评分。我正在尝试使用此数据不断更新最初从 1000 开始的 ELO 评级。

我尝试使用按引用传递,但不确定我应该如何实现它,因为 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 巴萨 2 皇马 3

经过计算,第一局结束后,每个人的评分应该是990。第二局结束后,P1应该是970,P2应该是990。

但是第一局之后实际输出是1000。 第二场比赛后: P1: 1000 P2: 1020

最佳答案

问题是您到处都在使用整数进行涉及小数的计算。例如,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 因为它更精确而且不少于高效。

关于c++ - 玩了一定数量的游戏后如何更新 ELO 评级?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56625206/

相关文章:

c++ - LIBUSB编译错误

c++ - 超过 4 个字节的整数是什么类型?

c++ - 仅由非常大的随机输入引起的分段故障核心在出队前转储到 pqueue 堆中

c++ - c99 : 63 characters of an internal name are significant?

c++ - 确定非对象变量是否在 C++ 中初始化

c++ - Guid.NewGuid() 的 C++ 版本是什么?

c++ - C++列表/队列的顶部返回值

c++ - 将轴坐标转换为像素坐标

c++ - 错误 : invalid initialization of reference of type

c++ - std::transform 产生奇怪的输出