#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;
{
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");
}
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) {
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];
}
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) {
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;
}