2 This file is part of Cute Chess.
4 Cute Chess is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 Cute Chess is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with Cute Chess. If not, see <http://www.gnu.org/licenses/>.
18 #include "enginematch.h"
21 #include <chessplayer.h>
22 #include <playerbuilder.h>
23 #include <chessgame.h>
24 #include <polyglotbook.h>
25 #include <tournament.h>
26 #include <gamemanager.h>
29 EngineMatch::EngineMatch(Tournament
* tournament
, QObject
* parent
)
31 m_tournament(tournament
),
35 Q_ASSERT(tournament
!= 0);
40 EngineMatch::~EngineMatch()
45 OpeningBook
* EngineMatch::addOpeningBook(const QString
& fileName
)
47 if (fileName
.isEmpty())
50 if (m_books
.contains(fileName
))
51 return m_books
[fileName
];
53 PolyglotBook
* book
= new PolyglotBook
;
54 if (!book
->read(fileName
))
57 qWarning("Can't read opening book file %s", qPrintable(fileName
));
61 m_books
[fileName
] = book
;
65 void EngineMatch::start()
67 connect(m_tournament
, SIGNAL(finished()),
68 this, SLOT(onTournamentFinished()));
69 connect(m_tournament
, SIGNAL(gameStarted(ChessGame
*, int, int, int)),
70 this, SLOT(onGameStarted(ChessGame
*, int)));
71 connect(m_tournament
, SIGNAL(gameFinished(ChessGame
*, int, int, int)),
72 this, SLOT(onGameFinished(ChessGame
*, int)));
75 connect(m_tournament
->gameManager(), SIGNAL(debugMessage(QString
)),
76 this, SLOT(print(QString
)));
78 QMetaObject::invokeMethod(m_tournament
, "start", Qt::QueuedConnection
);
81 void EngineMatch::stop()
83 QMetaObject::invokeMethod(m_tournament
, "stop", Qt::QueuedConnection
);
86 void EngineMatch::setDebugMode(bool debug
)
91 void EngineMatch::setRatingInterval(int interval
)
93 Q_ASSERT(interval
>= 0);
94 m_ratingInterval
= interval
;
97 void EngineMatch::onGameStarted(ChessGame
* game
, int number
)
101 qDebug("Started game %d of %d (%s vs %s)",
103 m_tournament
->finalGameCount(),
104 qPrintable(game
->player(Chess::Side::White
)->name()),
105 qPrintable(game
->player(Chess::Side::Black
)->name()));
108 void EngineMatch::onGameFinished(ChessGame
* game
, int number
)
112 Chess::Result
result(game
->result());
113 qDebug("Finished game %d (%s vs %s): %s",
115 qPrintable(game
->player(Chess::Side::White
)->name()),
116 qPrintable(game
->player(Chess::Side::Black
)->name()),
117 qPrintable(result
.toVerboseString()));
119 if (m_tournament
->playerCount() == 2)
121 Tournament::PlayerData fcp
= m_tournament
->playerAt(0);
122 Tournament::PlayerData scp
= m_tournament
->playerAt(1);
123 int totalResults
= fcp
.wins
+ fcp
.losses
+ fcp
.draws
;
124 qDebug("Score of %s vs %s: %d - %d - %d [%.2f] %d",
125 qPrintable(fcp
.builder
->name()),
126 qPrintable(scp
.builder
->name()),
127 fcp
.wins
, scp
.wins
, fcp
.draws
,
128 double(fcp
.wins
* 2 + fcp
.draws
) / (totalResults
* 2),
132 if (m_ratingInterval
!= 0
133 && (m_tournament
->finishedGameCount() % m_ratingInterval
) == 0)
137 void EngineMatch::onTournamentFinished()
139 if (m_ratingInterval
== 0
140 || m_tournament
->finishedGameCount() % m_ratingInterval
!= 0)
143 qDebug("Finished match");
144 connect(m_tournament
->gameManager(), SIGNAL(finished()),
145 this, SIGNAL(finished()));
146 m_tournament
->gameManager()->finish();
149 void EngineMatch::print(const QString
& msg
)
151 qDebug("%d %s", m_startTime
.elapsed(), qPrintable(msg
));
162 void EngineMatch::printRanking()
164 QMultiMap
<qreal
, RankingData
> ranking
;
166 for (int i
= 0; i
< m_tournament
->playerCount(); i
++)
168 Tournament::PlayerData
player(m_tournament
->playerAt(i
));
170 int score
= player
.wins
* 2 + player
.draws
;
171 int total
= (player
.wins
+ player
.losses
+ player
.draws
) * 2;
175 qreal ratio
= qreal(score
) / qreal(total
);
176 qreal eloDiff
= -400.0 * std::log(1.0 / ratio
- 1.0) / std::log(10.0);
178 if (m_tournament
->playerCount() == 2)
180 qDebug("ELO difference: %.0f", eloDiff
);
184 RankingData data
= { player
.builder
->name(),
187 qreal(player
.draws
* 2) / qreal(total
) };
188 ranking
.insert(-eloDiff
, data
);
191 if (!ranking
.isEmpty())
192 qDebug("%4s %-23s %7s %7s %7s %7s",
193 "Rank", "Name", "ELO", "Games", "Score", "Draws");
196 QMultiMap
<qreal
, RankingData
>::const_iterator it
;
197 for (it
= ranking
.constBegin(); it
!= ranking
.constEnd(); ++it
)
199 const RankingData
& data
= it
.value();
200 qDebug("%4d %-23s %7.0f %7d %6.0f%% %6.0f%%",
202 qPrintable(data
.name
),