2 * Copyright (C) 2007-2011 Vincent Ollivier
4 * This program 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 * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
31 void Game::print_thinking_header() {
32 if (!output_thinking
) return;
33 cout
<< setw(4) << "ply";
34 cout
<< setw(WIDE
) << "score";
35 cout
<< setw(WIDE
) << "time";
36 cout
<< setw(WIDE
) << "nodes";
37 cout
<< setw(WIDE
) << "pv";
41 void Game::print_thinking(int depth
, int score
, Move m
) {
42 if (!output_thinking
) return;
43 cout
<< setw(4) << depth
;
44 cout
<< setw(WIDE
) << score
;
45 cout
<< setw(WIDE
) << time
.get_elapsed_time();
46 cout
<< setw(WIDE
) << nodes_count
;
47 cout
<< setw(WIDE
- 3) << " ";
48 int ply
= current_node().get_ply();
49 if (ply
% 2 != 0) cout
<< 1 + (ply
/ 2) << ". ...";
51 assert(is_legal(m
) || assert_msg(
52 endl
<< board
<< endl
<<
53 "m = " << output_move(m
) << " (" << m
<< ")" << endl
<<
54 "m is en passant: " << m
.is_en_passant()
57 cout
<< output_principal_variation(depth
, m
) << endl
;
60 string
Game::output_principal_variation(int depth
, Move m
) {
63 int ply
= current_node().get_ply();
64 if (ply
% 2 == 0) stream
<< 1 + (ply
/ 2) << ". ";
65 stream
<< output_move(m
);
66 Node pos
= current_node();
68 if (is_check(current_node().get_turn_color())) stream
<< "+";
70 // Find next move in TT
71 Transposition trans
= tt
.lookup(current_node().hash());
74 cout << "value=" << trans.get_value();
75 cout << ", bound=" << trans.get_bound();
76 cout << ", depth=" << trans.get_depth();
77 cout << ", move=" << trans.get_best_move() << endl;
79 Move move
= trans
.get_best_move();
80 if (depth
> 0 && is_legal(move
) && trans
.get_bound() < 3) {
81 stream
<< output_principal_variation(depth
- 1, move
);
85 assert(pos
.hash() == current_node().hash());
89 string
Game::output_move(Move m
) {
94 if (m
.get_castle_side() == QUEEN
) stream
<< "O-";
95 return stream
.str() + "O-O";
99 Square from
= m
.get_orig();
100 Piece p
= board
.get_piece(from
);
101 PieceType t
= p
.get_type();
102 if (t
> PAWN
) stream
<< Piece(WHITE
, t
); // Upper case
105 if (m
.is_capture()) {
106 if (t
== PAWN
) stream
<< char('a' + m
.get_orig_file());
107 else { // Disambiguation
108 Color c
= current_node().get_turn_color(); // FIXME invert color
109 Square to
= m
.get_dest();
110 for (int i
= 0; i
< pieces
.get_nb_pieces(c
, t
); ++i
) {
111 Square s
= pieces
.get_position(c
, t
, i
);
112 if (s
!= from
&& board
.can_attack(t
, s
, to
)) {
113 stream
<< char('a' + m
.get_orig_file());
122 stream
<< output_square(m
.get_dest_file(), m
.get_dest_rank());
125 if (m
.is_promotion()) {
126 stream
<< "=" << Piece(WHITE
, m
.get_promotion_type());
132 string
Game::output_square(File f
, Rank r
) {
133 ostringstream stream
;
134 stream
<< char('a' + f
) << char('1' + r
);
138 void Game::print_tt_stats() {
141 for (int i
= 0; i
< tt
.size(); ++i
) {
142 if (tt
.at(i
).is_empty()) continue;
143 Hash h
= tt
.at(i
).get_hash();
146 //cout << "0: " << 64 - z << ", 1: " << z << endl;
151 cout
<< "Zobrist: " << hex
<< current_node().hash() << dec
<< endl
;
152 cout
<< "TT Size: " << TT_SIZE
/ 1024 / 1024 << "Mb" << endl
;
153 cout
<< "Entries: " << tt
.size() << endl
;
154 cout
<< "Usage: " << tt
.get_usage();
155 float percent_usage
= (100 * tt
.get_usage()) / float(tt
.size());
156 cout
<< " (" << percent_usage
<< "%)" << endl
;
157 float percent_zeros
= (100.0 * zeros
) / (64.0 * tt
.get_usage());
158 cout
<< "0's: " << percent_zeros
<< "%" << endl
;
159 float percent_ones
= (100.0 * ones
) / (64.0 * tt
.get_usage());
160 cout
<< "1's: " << percent_ones
<< "%" << endl
;
162 cout
<< "Lookups: " << tt
.get_nb_lookups() << endl
;
164 cout
<< "Hits: " << tt
.get_nb_hits();
165 float percent_hits
= (100 * tt
.get_nb_hits()) /
166 float(tt
.get_nb_lookups());
167 cout
<< " (" << percent_hits
<< "%)" << endl
;
169 cout
<< "Index Collisions: " << tt
.get_nb_collisions();
170 float percent_collisions
= (100 * tt
.get_nb_collisions()) /
171 float(tt
.get_nb_lookups());
172 cout
<< " (" << percent_collisions
<< "%)" << endl
;
174 cout
<< "Misses: " << tt
.get_nb_misses();
175 float percent_misses
= (100 * tt
.get_nb_misses()) /
176 float(tt
.get_nb_lookups());
177 cout
<< " (" << percent_misses
<< "%)" << endl
;