Introducing Lazy Move Generation
[purplehaze.git] / src / main.cpp
blob78037b727afba2f151b0bacb636c8dcce41d29a8
1 /* PurpleHaze 2.0.0
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/>.
18 #include <iostream>
19 #include <fstream>
20 #include <sstream>
21 #include <string>
22 #include <assert.h>
23 #include <stdio.h>
24 #include <time.h>
26 #include "common.h"
27 #include "game.h"
28 #include "xboard.h"
30 using namespace std;
32 string version = "PurpleHaze 2.0.0";
34 string prompt() {
35 string cmd;
36 cout << "> ";
37 cin >> cmd;
38 return cmd;
41 int main() {
42 cout << version << endl;
43 cout << endl;
45 cout << "Hash: " << sizeof(Hash) << endl;
46 cout << "Piece: " << sizeof(Piece) << endl;
47 cout << "Move: " << sizeof(Move) << endl;
48 cout << "ExtendedMove: " << sizeof(ExtendedMove) << endl;
49 cout << "Transposition: " << sizeof(Transposition) << endl;
50 cout << "Node: " << sizeof(Node) << endl;
51 cout << endl;
53 cout << "Compiled with options:";
54 #ifdef NMP
55 cout << " NMP";
56 #endif
57 #ifdef TT
58 cout << " TT";
59 #endif
60 cout << endl << endl;
62 string default_fen =
63 "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
65 // Parse commands from CLI
66 string cmd = prompt();
67 while (cmd != "quit" && cmd != "exit") {
68 if (cmd == "xboard") { // Xboard protocol mode
69 Xboard xboard;
70 xboard.loop();
71 return 0;
73 else if (cmd == "version") {
74 cout << version << endl;
76 else if (cmd == "setboard") {
77 // Get FEN
78 getline(cin, default_fen);
79 default_fen.erase(0, 1); // Remove the first whitespace
81 else if (cmd == "perft") {
82 Game game;
83 game.init(default_fen);
84 for (int i = 1; ; ++i) {
85 clock_t start = clock();
86 int perft_result = game.perft(i);
87 double perft_time = double(clock() - start) / CLOCKS_PER_SEC;
88 cout << "Perft(" << i << ") = " << perft_result;
89 cout << " (" << perft_time << " secs, ";
90 cout << perft_result / perft_time << " nps)" << endl;
93 else if (cmd == "divide") {
94 int depth = 0;
95 cin >> depth;
96 cout << endl;
97 Game game;
98 game.init(default_fen);
99 Color c = game.current_node().get_turn_color();
100 int nodes_count = 0;
101 int moves_count = 0;
102 Moves moves(game.board, game.pieces, game.current_node());
103 Move move;
104 while (!(move = moves.next()).is_null()) {
105 game.make_move(move);
106 if (!game.is_check(c)) {
107 int cnt = game.perft(depth - 1);
108 nodes_count += cnt;
109 moves_count++;
110 cout << move << " " << cnt << endl;
112 game.undo_move(move);
114 cout << endl;
115 cout << "Moves: " << moves_count << endl;
116 cout << "Nodes: " << nodes_count << endl;
118 else if (cmd == "testsuite") {
119 // Get EPD test suite
120 string filename;
121 cin >> filename;
122 ifstream epdfile;
123 epdfile.open(filename);
124 if (!epdfile.is_open()) {
125 cout << "Cannot open '" << filename;
126 cout << "': No such file or directory" << endl;
129 // Get time per move (optional)
130 string seconds;
131 getline(cin, seconds);
132 int time = 10;
133 if (seconds != "") {
134 istringstream iss(seconds);
135 iss >> time;
138 cout << "Loading '" << filename << "', ";
139 cout << time << "s per move" << endl; // In seconds
141 // Load game protocol
142 Protocol proto;
143 proto.set_output_thinking(false);
144 proto.set_time(1, time);
146 // Read positions in file
147 int res = 0;
148 int i = 0;
149 while (epdfile.good()) {
150 proto.new_game();
151 string line;
152 getline(epdfile, line);
153 size_t fensep = line.find(" bm ");
154 size_t bmsep = line.find(";");
155 if (fensep == string::npos || bmsep == string::npos) continue;
157 // Load position in game
158 string fen = line.substr(0, fensep);
159 cout << "Loading position #" << i + 1 << " '" << fen << "' ";
160 proto.set_board(fen);
162 // Search best move and test it
163 string best_move = line.substr(fensep + 4, bmsep - fensep - 4);
164 cout << "bm " << best_move;
165 string move = proto.search_move(true);
166 cout << " => " << move;
167 if (best_move == move) {
168 cout << " OK" << endl;
169 ++res;
171 else {
172 cout << " KO" << endl;
174 ++i;
176 cout << "Result: " << res << "/" << i << endl;
178 epdfile.close();
180 cmd = prompt();
182 return 0;