libscid 0.1.0
Chess applications made easy.
Loading...
Searching...
No Matches
tree.h
1/*
2* Copyright (C) 1999 Shane Hudson
3* Copyright (C) 2015-2020 Fulvio Benini
4
5* This file is part of Scid (Shane's Chess Information Database).
6*
7* Scid is free software: you can redistribute it and/or modify
8* it under the terms of the GNU General Public License as published by
9* the Free Software Foundation.
10*
11* Scid is distributed in the hope that it will be useful,
12* but WITHOUT ANY WARRANTY; without even the implied warranty of
13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14* GNU General Public License for more details.
15*
16* You should have received a copy of the GNU General Public License
17* along with Scid. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#pragma once
21
22#include "scid/core/fullmove.h"
23#include "scid/core/game_result.h"
24#include "scid/database/common.h"
25#include "scid/database/game_id.h"
26
27namespace scid::database {
28
29struct TreeNode {
30 unsigned long long eloWhiteSum = 0; // Sum of white Elos.
31 unsigned long long eloBlackSum = 0; // Sum of bLack Elos.
32 unsigned long long yearSum = 0; // Sum of years.
33 gamenumT freq[scid::core::NUM_RESULT_TYPES] = {}; // freq[0] is the total count.
34 gamenumT eloCount = 0; // Count of games with an Elo.
35 gamenumT yearCount = 0; // Count of games with year != 0.
37
38public:
39 explicit TreeNode(scid::core::FullMove m) : move(m) {}
40
41 void add(scid::core::resultT result, int eloW, int eloB, unsigned year) {
42 static_assert(scid::core::RESULT_None == 0);
43 freq[0]++; // total count of games
44 if (result != scid::core::RESULT_None) {
45 freq[result]++;
46 }
47 if (eloW > 0 && eloB > 0) {
48 ++eloCount;
49 eloWhiteSum += eloW;
50 eloBlackSum += eloB;
51 }
52 if (year > 0) {
53 yearSum += year;
54 ++yearCount;
55 }
56 }
57
60 int score() const {
61 auto n = freq[scid::core::RESULT_White] + freq[scid::core::RESULT_Draw] + freq[scid::core::RESULT_Black];
62 auto res = 1000ull * freq[scid::core::RESULT_White] + 500ull * freq[scid::core::RESULT_Draw];
63 return n ? static_cast<int>(res / n) : 500;
64 }
65
66 double eloPerformance() const {
67 if (eloCount == 0)
68 return 0;
69
70 int score = (this->score() + 5) / 10;
71 auto eloOpp = eloBlackSum;
72 if (move.getColor() != scid::core::WHITE) {
73 score = 100 - score;
74 eloOpp = eloWhiteSum;
75 }
76 return 1.0 * eloOpp / eloCount + FIDE_ratingTable[score];
77 }
78
79 double avgElo() const {
80 if (eloCount == 0)
81 return 0;
82
83 auto elo = (move.getColor() == scid::core::WHITE) ? eloWhiteSum : eloBlackSum;
84 return 1.0 * elo / eloCount;
85 }
86
87 double avgYear() const { return yearCount ? 1.0 * yearSum / yearCount : 0; }
88
89 double percDraws() const {
90 return freq[0] ? 100.0 * freq[scid::core::RESULT_Draw] / freq[0] : 0;
91 }
92
93 static auto cmp_ngames_desc() {
94 return
95 [](auto const& a, auto const& b) { return a.freq[0] > b.freq[0]; };
96 }
97
98private:
99 // FIDE table 8.1a of conversion from fractional score (from 0 to 1 with
100 // 0.01 increments) into rating differences.
101 static constexpr short FIDE_ratingTable[] = {
102 -800, -677, -589, -538, -501, -470, -444, -422, -401, -383, -366, -351,
103 -336, -322, -309, -296, -284, -273, -262, -251, -240, -230, -220, -211,
104 -202, -193, -184, -175, -166, -158, -149, -141, -133, -125, -117, -110,
105 -102, -95, -87, -80, -72, -65, -57, -50, -43, -36, -29, -21,
106 -14, -7, 0, 7, 14, 21, 29, 36, 43, 50, 57, 65,
107 72, 80, 87, 95, 102, 110, 117, 125, 133, 141, 149, 158,
108 166, 175, 184, 193, 202, 211, 220, 230, 240, 251, 262, 273,
109 284, 296, 309, 322, 336, 351, 366, 383, 401, 422, 444, 470,
110 501, 538, 589, 677, 800};
111};
112
113} // namespace scid::database
Definition fullmove.h:14
Compact encoded move representation.
class StrRange - parse a string interpreting its content as 1 or 2 integers separated by whitespace.
Definition common.h:30
Definition tree.h:29
int score() const
Definition tree.h:60