all-up-in-your-elo 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. data/.document +5 -0
  2. data/Gemfile +14 -0
  3. data/Gemfile.lock +22 -0
  4. data/LICENSE.txt +20 -0
  5. data/README.rdoc +42 -0
  6. data/Rakefile +54 -0
  7. data/VERSION +1 -0
  8. data/all-up-in-your-elo.gemspec +148 -0
  9. data/ext/bayeselo/.gitignore +4 -0
  10. data/ext/bayeselo/CBradleyTerry.cpp +670 -0
  11. data/ext/bayeselo/CBradleyTerry.h +137 -0
  12. data/ext/bayeselo/CCDistribution.cpp +135 -0
  13. data/ext/bayeselo/CCDistribution.h +44 -0
  14. data/ext/bayeselo/CCDistributionCUI.cpp +104 -0
  15. data/ext/bayeselo/CCDistributionCUI.h +38 -0
  16. data/ext/bayeselo/CCondensedResults.cpp +253 -0
  17. data/ext/bayeselo/CCondensedResults.h +64 -0
  18. data/ext/bayeselo/CDiscretization.h +40 -0
  19. data/ext/bayeselo/CDistribution.cpp +123 -0
  20. data/ext/bayeselo/CDistribution.h +58 -0
  21. data/ext/bayeselo/CDistributionCollection.cpp +34 -0
  22. data/ext/bayeselo/CDistributionCollection.h +29 -0
  23. data/ext/bayeselo/CEloRatingCUI.cpp +1046 -0
  24. data/ext/bayeselo/CEloRatingCUI.h +67 -0
  25. data/ext/bayeselo/CIndirectCompare.h +28 -0
  26. data/ext/bayeselo/CJointBayesian.cpp +111 -0
  27. data/ext/bayeselo/CJointBayesian.h +38 -0
  28. data/ext/bayeselo/CLUDecomposition.cpp +154 -0
  29. data/ext/bayeselo/CLUDecomposition.h +36 -0
  30. data/ext/bayeselo/CMatrix.cpp +48 -0
  31. data/ext/bayeselo/CMatrix.h +35 -0
  32. data/ext/bayeselo/CMatrixIO.cpp +27 -0
  33. data/ext/bayeselo/CMatrixIO.h +17 -0
  34. data/ext/bayeselo/CPredictionCUI.cpp +393 -0
  35. data/ext/bayeselo/CPredictionCUI.h +50 -0
  36. data/ext/bayeselo/CResultSet.cpp +245 -0
  37. data/ext/bayeselo/CResultSet.h +50 -0
  38. data/ext/bayeselo/CResultSetCUI.cpp +355 -0
  39. data/ext/bayeselo/CResultSetCUI.h +44 -0
  40. data/ext/bayeselo/CTimeIO.cpp +58 -0
  41. data/ext/bayeselo/CTimeIO.h +19 -0
  42. data/ext/bayeselo/CVector.cpp +110 -0
  43. data/ext/bayeselo/CVector.h +42 -0
  44. data/ext/bayeselo/EloDataFromFile.cpp +120 -0
  45. data/ext/bayeselo/EloDataFromFile.h +21 -0
  46. data/ext/bayeselo/README +8 -0
  47. data/ext/bayeselo/ReadLineToString.cpp +32 -0
  48. data/ext/bayeselo/ReadLineToString.h +18 -0
  49. data/ext/bayeselo/chtime.cpp +56 -0
  50. data/ext/bayeselo/chtime.h +61 -0
  51. data/ext/bayeselo/chtimer.h +27 -0
  52. data/ext/bayeselo/clktimer.cpp +178 -0
  53. data/ext/bayeselo/clktimer.h +29 -0
  54. data/ext/bayeselo/consolui.cpp +538 -0
  55. data/ext/bayeselo/consolui.h +154 -0
  56. data/ext/bayeselo/const.cpp +79 -0
  57. data/ext/bayeselo/const.h +42 -0
  58. data/ext/bayeselo/date.cpp +96 -0
  59. data/ext/bayeselo/date.h +44 -0
  60. data/ext/bayeselo/debug.h +58 -0
  61. data/ext/bayeselo/elomain.cpp +26 -0
  62. data/ext/bayeselo/eloratings.cpp +76 -0
  63. data/ext/bayeselo/extconf.rb +6 -0
  64. data/ext/bayeselo/list.h +367 -0
  65. data/ext/bayeselo/listi.h +125 -0
  66. data/ext/bayeselo/move.cpp +249 -0
  67. data/ext/bayeselo/move.h +139 -0
  68. data/ext/bayeselo/pgn.h +62 -0
  69. data/ext/bayeselo/pgnlex.cpp +432 -0
  70. data/ext/bayeselo/pgnlex.h +105 -0
  71. data/ext/bayeselo/pgnstr.cpp +126 -0
  72. data/ext/bayeselo/piece.h +44 -0
  73. data/ext/bayeselo/player.h +31 -0
  74. data/ext/bayeselo/position.h +89 -0
  75. data/ext/bayeselo/random.cpp +114 -0
  76. data/ext/bayeselo/random.h +63 -0
  77. data/ext/bayeselo/readstr.cpp +51 -0
  78. data/ext/bayeselo/readstr.h +19 -0
  79. data/ext/bayeselo/square.h +61 -0
  80. data/ext/bayeselo/str.cpp +81 -0
  81. data/ext/bayeselo/str.h +71 -0
  82. data/ext/bayeselo/version.cpp +30 -0
  83. data/ext/bayeselo/version.h +28 -0
  84. data/ext/bayeselo/version_number.h +1 -0
  85. data/lib/elo_ratings.rb +9 -0
  86. data/lib/elo_ratings/c_bayeselo.rb +5 -0
  87. data/lib/elo_ratings/results.rb +41 -0
  88. data/test/elo_ratings/test_c_bayeselo.rb +84 -0
  89. data/test/elo_ratings/test_results.rb +41 -0
  90. data/test/helper.rb +19 -0
  91. metadata +233 -0
@@ -0,0 +1,35 @@
1
+ /////////////////////////////////////////////////////////////////////////////
2
+ //
3
+ // CMatrix.h
4
+ //
5
+ // R�mi Coulom
6
+ //
7
+ // February, 2005
8
+ //
9
+ /////////////////////////////////////////////////////////////////////////////
10
+ #ifndef Math_CMatrix_Declared
11
+ #define Math_CMatrix_Declared
12
+
13
+ #include "CVector.h"
14
+
15
+ class CMatrix: public CVector
16
+ {
17
+ private: ///////////////////////////////////////////////////////////////////
18
+ int Rows;
19
+ int Columns;
20
+
21
+ public: ////////////////////////////////////////////////////////////////////
22
+ CMatrix(int RowsInit = 0, int ColumnsInit = 0);
23
+
24
+ void SetSize(int RowsInit, int ColumnsInit);
25
+ int GetRows() const {return Rows;}
26
+ int GetColumns() const {return Columns;}
27
+
28
+ double GetElement(int i, int j) const {return (*this)[i * Columns + j];}
29
+ void SetElement(int i, int j, double x) {(*this)[i * Columns + j] = x;}
30
+ void AddToElement(int i, int j, double x) {(*this)[i * Columns + j] += x;}
31
+
32
+ void SetProductByTranspose(const CMatrix &mA, const CMatrix &mB);
33
+ };
34
+
35
+ #endif
@@ -0,0 +1,27 @@
1
+ /////////////////////////////////////////////////////////////////////////////
2
+ //
3
+ // R�mi Coulom
4
+ //
5
+ // February, 2005
6
+ //
7
+ /////////////////////////////////////////////////////////////////////////////
8
+ #include "CMatrixIO.h"
9
+ #include "CMatrix.h"
10
+
11
+ #include <iostream>
12
+ #include <iomanip>
13
+
14
+ /////////////////////////////////////////////////////////////////////////////
15
+ // Output operator for matrices
16
+ /////////////////////////////////////////////////////////////////////////////
17
+ std::ostream &operator<<(std::ostream &out, const CMatrix &m)
18
+ {
19
+ for (int i = 0; i < m.GetRows(); i++)
20
+ {
21
+ for (int j = 0; j < m.GetColumns(); j++)
22
+ out << std::setw(12) << m.GetElement(i, j) << ' ';
23
+ out << '\n';
24
+ }
25
+
26
+ return out;
27
+ }
@@ -0,0 +1,17 @@
1
+ /////////////////////////////////////////////////////////////////////////////
2
+ //
3
+ // R�mi Coulom
4
+ //
5
+ // February, 2005
6
+ //
7
+ /////////////////////////////////////////////////////////////////////////////
8
+ #ifndef CMatrixIO_Declared
9
+ #define CMatrixIO_Declared
10
+
11
+ #include <iosfwd>
12
+
13
+ class CMatrix;
14
+
15
+ std::ostream &operator<<(std::ostream &out, const CMatrix &m);
16
+
17
+ #endif
@@ -0,0 +1,393 @@
1
+ ////////////////////////////////////////////////////////////////////////////
2
+ //
3
+ // Remi Coulom
4
+ //
5
+ // December, 2005
6
+ //
7
+ ////////////////////////////////////////////////////////////////////////////
8
+ #include "CPredictionCUI.h"
9
+ #include "CEloRatingCUI.h"
10
+ #include "CResultSetCUI.h"
11
+ #include "CIndirectCompare.h"
12
+ #include "random.h"
13
+
14
+ #include <iostream>
15
+ #include <sstream>
16
+ #include <iomanip>
17
+ #include <algorithm>
18
+ #include <cmath>
19
+
20
+ ////////////////////////////////////////////////////////////////////////////
21
+ // Command strings
22
+ ////////////////////////////////////////////////////////////////////////////
23
+ const char * const CPredictionCUI::tszCommands[] =
24
+ {
25
+ "?",
26
+ "results",
27
+ "players",
28
+ "elo",
29
+ "stddev",
30
+ "simulations",
31
+ "rounds",
32
+ "lossscore",
33
+ "drawscore",
34
+ "winscore",
35
+ "multiplier",
36
+ "simulate",
37
+ 0
38
+ };
39
+
40
+ ////////////////////////////////////////////////////////////////////////////
41
+ // Constructor
42
+ ////////////////////////////////////////////////////////////////////////////
43
+ CPredictionCUI::CPredictionCUI(CEloRatingCUI &ercuiInit, int openmode) :
44
+ CConsoleUI(&ercuiInit, openmode),
45
+ ercui(ercuiInit),
46
+ vbtvariance(ercui.crs.GetPlayers()),
47
+ Simulations(100000),
48
+ Rounds(1),
49
+ ScoreMultiplier(0.5)
50
+ {
51
+ tScore[0] = 0;
52
+ tScore[1] = 1;
53
+ tScore[2] = 2;
54
+
55
+ ercui.bt.GetVariance(&vbtvariance[0]);
56
+ }
57
+
58
+ ////////////////////////////////////////////////////////////////////////////
59
+ // Local prompt
60
+ ////////////////////////////////////////////////////////////////////////////
61
+ void CPredictionCUI::PrintLocalPrompt(std::ostream &out)
62
+ {
63
+ out << "Prediction";
64
+ }
65
+
66
+ ////////////////////////////////////////////////////////////////////////////
67
+ // Process commands
68
+ ////////////////////////////////////////////////////////////////////////////
69
+ int CPredictionCUI::ProcessCommand(const char *pszCommand,
70
+ const char *pszParameters,
71
+ std::istream &in,
72
+ std::ostream &out)
73
+ {
74
+ enum
75
+ {
76
+ IDC_Help,
77
+ IDC_Results,
78
+ IDC_Players,
79
+ IDC_Elo,
80
+ IDC_StdDev,
81
+ IDC_Simulations,
82
+ IDC_Rounds,
83
+ IDC_LossScore,
84
+ IDC_DrawScore,
85
+ IDC_WinScore,
86
+ IDC_Multiplier,
87
+ IDC_Simulate
88
+ };
89
+
90
+ switch (ArrayLookup(pszCommand, tszCommands))
91
+ {
92
+ case IDC_Help: ///////////////////////////////////////////////////////////
93
+ CConsoleUI::ProcessCommand(pszCommand, pszParameters, in, out);
94
+ out << "Prediction commands\n";
95
+ out << "~~~~~~~~~~~~~~~~~~~\n";
96
+ out << "results ......... open interface to define players and results\n";
97
+ out << "players ......... list players\n";
98
+ out << "elo n [x] ....... get[set] elo of player number n\n";
99
+ out << "stddev n [x] .... get[set] standard deviation of player number n\n";
100
+ out << '\n';
101
+ out << "simulations [n] . get[set] number of simulations\n";
102
+ out << "rounds [n] ...... get[set] number of (double) rounds\n";
103
+ out << "lossscore [n] ... get[set] score obtained when losing\n";
104
+ out << "drawscore [n] ... get[set] score obtained when drawing\n";
105
+ out << "winscore [n] .... get[set] score obtained when winning\n";
106
+ out << "multiplier [x] .. get[set] score multiplier\n";
107
+ out << '\n';
108
+ out << "simulate [n]..... run simulations (n = rng seed)\n";
109
+ break;
110
+
111
+ case IDC_Results: ////////////////////////////////////////////////////////
112
+ {
113
+ //
114
+ // Open a rscui to get a list of players and results
115
+ //
116
+ CResultSetCUI rscui(rs, vecName, this);
117
+ rscui.MainLoop(in, out);
118
+
119
+ //
120
+ // Find player ratings and variances in ercui
121
+ //
122
+ velo.resize(vecName.size());
123
+ vStdDev.resize(vecName.size());
124
+ for (unsigned i = 0; i < vecName.size(); i++)
125
+ {
126
+ velo[i] = 0;
127
+ vStdDev[i] = 1000;
128
+ for (int j = ercui.vecName.size(); --j >= 0;)
129
+ if (ercui.vecName[j] == vecName[i])
130
+ {
131
+ velo[i] = ercui.bt.GetElo(j);
132
+ vStdDev[i] = std::sqrt(vbtvariance[j]);
133
+ }
134
+ }
135
+ }
136
+ break;
137
+
138
+ case IDC_Players: ////////////////////////////////////////////////////////
139
+ {
140
+ out << std::setw(3) << "Num" << ' ';
141
+ out << std::setw(20) << "Name" << ' ';
142
+ out << std::setw(8) << "Elo" << ' ';
143
+ out << std::setw(8) << "Std.Dev." << '\n';
144
+ for (unsigned i = 0; i < vecName.size(); i++)
145
+ {
146
+ out << std::setw(3) << i << ' ';
147
+ out << std::setw(20) << vecName[i] << ' ';
148
+ out << std::setw(8) << velo[i] << ' ';
149
+ out << std::setw(8) << vStdDev[i] << '\n';
150
+ }
151
+ out << "(" << vecName.size() << " players)\n";
152
+ }
153
+ break;
154
+
155
+ case IDC_Elo: ////////////////////////////////////////////////////////////
156
+ {
157
+ std::istringstream is(pszParameters);
158
+ unsigned Player = 0;
159
+ is >> Player;
160
+ if (Player < velo.size())
161
+ {
162
+ is >> velo[Player];
163
+ out << velo[Player] << '\n';
164
+ }
165
+ }
166
+ break;
167
+
168
+ case IDC_StdDev: /////////////////////////////////////////////////////////
169
+ {
170
+ std::istringstream is(pszParameters);
171
+ unsigned Player = 0;
172
+ is >> Player;
173
+ if (Player < vStdDev.size())
174
+ {
175
+ is >> vStdDev[Player];
176
+ out << vStdDev[Player] << '\n';
177
+ }
178
+ }
179
+ break;
180
+
181
+ case IDC_Simulations: ////////////////////////////////////////////////////
182
+ GetSet<int>(Simulations, pszParameters, out);
183
+ break;
184
+
185
+ case IDC_Rounds: /////////////////////////////////////////////////////////
186
+ GetSet<int>(Rounds, pszParameters, out);
187
+ break;
188
+
189
+ case IDC_LossScore: //////////////////////////////////////////////////////
190
+ GetSet<int>(tScore[0], pszParameters, out);
191
+ break;
192
+
193
+ case IDC_DrawScore: //////////////////////////////////////////////////////
194
+ GetSet<int>(tScore[1], pszParameters, out);
195
+ break;
196
+
197
+ case IDC_WinScore: ///////////////////////////////////////////////////////
198
+ GetSet<int>(tScore[2], pszParameters, out);
199
+ break;
200
+
201
+ case IDC_Multiplier: /////////////////////////////////////////////////////
202
+ GetSet<double>(ScoreMultiplier, pszParameters, out);
203
+ break;
204
+
205
+ case IDC_Simulate: ///////////////////////////////////////////////////////
206
+ {
207
+ int Seed = 0;
208
+ std::istringstream(pszParameters) >> Seed;
209
+ CRandom<unsigned> rnd(Seed);
210
+ int Players = vecName.size();
211
+ std::vector<int> vGames(Players * Players);
212
+ std::vector<int> vScore(Players);
213
+
214
+ //
215
+ // Reset arrays
216
+ //
217
+ for (int i = Players * Players; --i >= 0;)
218
+ vGames[i] = 0;
219
+ for (int i = Players; --i >= 0;)
220
+ vScore[i] = 0;
221
+
222
+ //
223
+ // Add games that have already been played
224
+ //
225
+ for (int i = rs.GetGames(); --i >= 0;)
226
+ {
227
+ int White = rs.GetWhite(i);
228
+ int Black = rs.GetBlack(i);
229
+ int Result = rs.GetResult(i);
230
+ int Index = White + Players * Black;
231
+ if (vGames[Index] < Rounds)
232
+ {
233
+ vGames[Index]++;
234
+ vScore[White] += tScore[Result];
235
+ vScore[Black] += tScore[2 - Result];
236
+ }
237
+ else
238
+ out << "warning: more games than rounds\n";
239
+ }
240
+
241
+ //
242
+ // Arrays to receive cumulative information
243
+ //
244
+ std::vector<int> vTotalScore(Players);
245
+ std::vector<int> vTotalVariance(Players);
246
+ std::vector<int> vTotalRank(Players);
247
+ for (int i = Players; --i >= 0;)
248
+ {
249
+ vTotalScore[i] = 0;
250
+ vTotalVariance[i] = 0;
251
+ vTotalRank[i] = 0;
252
+ }
253
+ std::vector<int> vRankDistribution(Players * Players);
254
+ for (int i = Players * Players; --i >= 0;)
255
+ vRankDistribution[i] = 0;
256
+
257
+ //
258
+ // Permutation vector to rank players
259
+ //
260
+ std::vector<int> vPermutation(Players);
261
+ for (int i = Players; --i >= 0;)
262
+ vPermutation[i] = i;
263
+
264
+ //
265
+ // Run simulations
266
+ //
267
+ for (int i = Simulations; --i >= 0;)
268
+ {
269
+ std::vector<int> vLocalScore = vScore;
270
+ std::vector<double> veloRandom = velo;
271
+
272
+ for (int j = Players; --j >= 0;)
273
+ veloRandom[j] += rnd.NextGaussian() * vStdDev[j];
274
+
275
+ for (int White = Players; --White >= 0;)
276
+ for (int Black = Players; --Black >= 0;)
277
+ if (White != Black)
278
+ {
279
+ int Index = White + Players * Black;
280
+
281
+ double eloDelta = veloRandom[White] - veloRandom[Black];
282
+ double xWin = ercui.bt.WinProbability(eloDelta);
283
+ double xLoss = xWin + ercui.bt.LossProbability(eloDelta);
284
+
285
+ for (int r = Rounds - vGames[Index]; --r >= 0;)
286
+ {
287
+ double x = rnd.NextDouble();
288
+ int Result = 1;
289
+ if (x < xWin)
290
+ Result = 2;
291
+ else if (x < xLoss)
292
+ Result = 0;
293
+ vLocalScore[White] += tScore[Result];
294
+ vLocalScore[Black] += tScore[2 - Result];
295
+ }
296
+ }
297
+
298
+ std::sort(vPermutation.begin(),
299
+ vPermutation.end(),
300
+ CIndirectCompare<int>(&vLocalScore[0]));
301
+
302
+ for (int Player = Players; --Player >= 0;)
303
+ {
304
+ vTotalScore[Player] += vLocalScore[Player];
305
+ vTotalVariance[Player] += vLocalScore[Player] * vLocalScore[Player];
306
+ vTotalRank[vPermutation[Player]] += Player;
307
+ vRankDistribution[Player + Players * vPermutation[Player]]++;
308
+ }
309
+ }
310
+
311
+ //
312
+ // Find maximum name length
313
+ //
314
+ unsigned MaxNameLength = 11;
315
+ for (int i = Players; --i >= 0;)
316
+ if (vecName[i].length() > MaxNameLength)
317
+ MaxNameLength = vecName[i].length();
318
+
319
+ //
320
+ // Sort players according to expected score
321
+ //
322
+ std::sort(vPermutation.begin(),
323
+ vPermutation.end(),
324
+ CIndirectCompare<int>(&vTotalScore[0]));
325
+
326
+ //
327
+ // Print summary of simulations
328
+ //
329
+ std::ios::fmtflags f = out.flags();
330
+
331
+ out.setf(std::ios::fixed, std::ios::floatfield);
332
+ out.precision(2);
333
+
334
+ out.setf(std::ios::right, std::ios::adjustfield);
335
+ out << std::setw(4) << "Rank" << ' ';
336
+ out.setf(std::ios::left, std::ios::adjustfield);
337
+ out << std::setw(MaxNameLength + 1) << "Player name";
338
+ out.setf(std::ios::right, std::ios::adjustfield);
339
+ out << std::setw(8) << "Points";
340
+ out << std::setw(8) << "EPoints";
341
+ out << std::setw(8) << "StdDev";
342
+ out << std::setw(8) << "ERank";
343
+ out << " ";
344
+ for (int k = 0; k < Players; k++)
345
+ out << std::setw(3) << k + 1;
346
+ out << '\n';
347
+
348
+ for (int i = 0; i < Players; i++)
349
+ {
350
+ int j = vPermutation[i];
351
+
352
+ float Score = float(vTotalScore[j] * ScoreMultiplier) / float(Simulations);
353
+ float Score2 =
354
+ float(vTotalVariance[j] * ScoreMultiplier * ScoreMultiplier) /
355
+ float(Simulations);
356
+ float Variance = Score2 - Score * Score;
357
+
358
+ out.setf(std::ios::right, std::ios::adjustfield);
359
+ out << std::setw(4) << i + 1 << ' ';
360
+ out.setf(std::ios::left, std::ios::adjustfield);
361
+ out << std::setw(MaxNameLength + 1) << vecName[j];
362
+ out.setf(std::ios::right, std::ios::adjustfield);
363
+ out << std::setw(8);
364
+ out.precision(1);
365
+ out << float(vScore[j] * ScoreMultiplier);
366
+ out << std::setw(8);
367
+ out.precision(2);
368
+ out << Score;
369
+ out << std::setw(8);
370
+ out << std::sqrt(Variance);
371
+ out << std::setw(8);
372
+ out << float(vTotalRank[j]) / float(Simulations) + 1.0;
373
+ out << " ";
374
+ for (int k = 0; k < Players; k++)
375
+ {
376
+ double x = (100.0 * vRankDistribution[k + Players * j]) /
377
+ float(Simulations);
378
+ out << std::setw(3) << int(x + 0.5);
379
+ }
380
+
381
+ out << '\n';
382
+ }
383
+
384
+ out.flags(f);
385
+ }
386
+ break;
387
+
388
+ default: /////////////////////////////////////////////////////////////////
389
+ return CConsoleUI::ProcessCommand(pszCommand, pszParameters, in, out);
390
+ }
391
+
392
+ return PC_Continue;
393
+ }