]> git.sesse.net Git - wloh/blobdiff - mcwordfeud.cpp
Fix a leftover 1700 value in the README.
[wloh] / mcwordfeud.cpp
index 0010010d89a5d002a105ad6267b8ceedf3f0a9cd..63b98e1ae33f578ca63aa4754a6b5ca15a1cb7b0 100644 (file)
@@ -7,13 +7,18 @@
 #include <vector>
 #include <string>
 #include <algorithm>
+#include <Eigen/Cholesky>
+#include <Eigen/Dense>
 
 #include "ziggurat.hpp"
 
 using namespace std;
+using namespace Eigen;
 
 #define MAX_PLAYERS 16
 
+float match_stddev = 70.0f;
+
 struct player {
        int player_index;
        int points, margin;
@@ -66,6 +71,11 @@ int main(int argc, char **argv)
 {
        int trials = atoi(argv[1]);
 
+       if (scanf("%f", &match_stddev) != 1) {
+               fprintf(stderr, "Could't read match stddev\n");
+               exit(1);
+       }
+
        int num_players;
        if (scanf("%d", &num_players) != 1) {
                fprintf(stderr, "Could't read number of players\n");
@@ -73,13 +83,13 @@ int main(int argc, char **argv)
        }
 
        if (num_players > MAX_PLAYERS) {
-               fprintf(stderr, "Max %d players supported\n");
+               fprintf(stderr, "Max %d players supported\n", MAX_PLAYERS);
                exit(1);
        }
 
        vector<string> players;
        map<string, int> player_map;
-       float ratings[MAX_PLAYERS];
+       Matrix<float, Dynamic, 1, 0, MAX_PLAYERS, 1> ratings(num_players);
        bool has_scores[MAX_PLAYERS][MAX_PLAYERS];
        for (int pl1 = 0; pl1 < num_players; ++pl1) {
                for (int pl2 = 0; pl2 < num_players; ++pl2) {
@@ -96,14 +106,28 @@ int main(int argc, char **argv)
                        fprintf(stderr, "Couldn't read player %d\n", i);
                        exit(1);
                }
-               if (ret != 2) {
-                       rating = 1500.0f;
+               if (ret < 2) {
+                       rating = 500.0f;
                }
 
                players.push_back(buf);
                player_map[buf] = i;
-               ratings[i] = rating;
+               ratings(i) = rating;
+       }
+
+       Matrix<float, Dynamic, Dynamic, 0, MAX_PLAYERS, MAX_PLAYERS> ratings_cov(num_players, num_players);
+       for (int i = 0; i < num_players; ++i) {
+               for (int j = 0; j < num_players; ++j) {
+                       float f;
+                       if (scanf("%f", &f) != 1) {
+                               fprintf(stderr, "Couldn't read covariance matrix element (%d,%d)\n", i, j);
+                               exit(1);
+                       }
+                       ratings_cov(i, j) = f;
+               }
        }
+       Matrix<float, Dynamic, Dynamic, 0, MAX_PLAYERS, MAX_PLAYERS> ratings_cholesky =
+               ratings_cov.llt().matrixLLT();
 
        for ( ;; ) {
                char pl1[256], pl2[256];
@@ -136,6 +160,13 @@ int main(int argc, char **argv)
        }
 
        for (int i = 0; i < trials; ++i) {
+               // draw true strength for all players
+               Matrix<float, Dynamic, 1, 0, MAX_PLAYERS, 1> drawn_normals(num_players);
+               for (int p = 0; p < num_players; ++p) {
+                       drawn_normals(p) = draw_gaussian(0.0f, 1.0f);
+               }
+               Matrix<float, Dynamic, 1, 0, MAX_PLAYERS, 1> drawn_ratings = ratings_cholesky * drawn_normals + ratings;
+
                // draw the missing matches
                for (int pl1 = 0; pl1 < num_players; ++pl1) {
                        for (int pl2 = pl1 + 1; pl2 < num_players; ++pl2) {
@@ -143,9 +174,9 @@ int main(int argc, char **argv)
                                        continue;
                                }
 
-                               float mu = ratings[pl1] - ratings[pl2];
+                               float mu = drawn_ratings(pl1) - drawn_ratings(pl2);
                                
-                               int score = lrintf(draw_gaussian(mu, 82.9f));
+                               int score = lrintf(draw_gaussian(mu, match_stddev));
                                scores[pl1][pl2] = score;
                                scores[pl2][pl1] = -score;
                        }