1+ /*
2+ Bit-Genie is an open-source, UCI-compliant chess engine written by
3+ Aryan Parekh - https://github.com/Aryan1508/Bit-Genie
4+
5+ Bit-Genie is free software: you can redistribute it and/or modify
6+ it under the terms of the GNU General Public License as published by
7+ the Free Software Foundation, either version 3 of the License, or
8+ (at your option) any later version.
9+
10+ Bit-Genie is distributed in the hope that it will be useful,
11+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+ GNU General Public License for more details.
14+
15+ You should have received a copy of the GNU General Public License
16+ along with this program. If not, see <http://www.gnu.org/licenses/>.
17+ */
18+ #include " game.h"
19+
20+ #define DRAW_STRING (" [0.5]" )
21+ #define WHITE_WIN_STRING (" [1.0]" )
22+ #define BLACK_WIN_STRING (" [0.0]" )
23+
24+ Game::Game (std::ofstream &output_file, std::mt19937 &rng)
25+ : output_file(output_file), rng(rng) {}
26+
27+ bool Game::filter_position () {
28+ return (qsearch (search, MIN_EVAL, MAX_EVAL) == search.position .static_evaluation ()) && !search.position .king_in_check ();
29+ }
30+
31+ bool Game::make_book_move () {
32+ if (is_mated ())
33+ return false ;
34+
35+ Movelist movelist;
36+ search.position .generate_legal (movelist);
37+
38+ std::uniform_int_distribution distribution (0 , static_cast <int >(movelist.size () - 1 ));
39+ int rand_index = distribution (rng);
40+
41+ search.position .apply_move (movelist[rand_index]);
42+ ply++;
43+ return true ;
44+ }
45+
46+ void Game::save_position (int search_score) {
47+ saved_positions.push_back ({ search.position .get_fen (), search_score });
48+ }
49+
50+ bool Game::is_mated () const {
51+ Movelist movelist;
52+ search.position .generate_legal (movelist);
53+ return movelist.size () == 0 ;
54+ }
55+
56+ void Game::new_game () {
57+ ply = 0 ;
58+ search.position .set_fen (" rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" );
59+ saved_positions.clear ();
60+ search.reset ();
61+ }
62+
63+ void Game::save_game (std::string const &result) {
64+ for (auto const &saved_position : saved_positions) {
65+ std::string line = saved_position.first + " " + result + " " + std::to_string (saved_position.second );
66+ output_file << line << ' \n ' ;
67+ }
68+ }
69+
70+ SearchResult Game::search_position () {
71+ return ::search_position (search, false );
72+ }
73+
74+ void Game::run () {
75+ std::string wdl_string;
76+ int draw_score_counter = 0 , win_score_counter = 0 ;
77+
78+ while (true ) {
79+ /* TODO: command line arg */
80+ if (ply < 8 ) {
81+ if (!make_book_move ())
82+ break ;
83+ continue ;
84+ }
85+
86+ if (search.position .drawn ()) {
87+ wdl_string = DRAW_STRING;
88+ break ;
89+ }
90+
91+ if (is_mated ()) {
92+ if (search.position .king_in_check ())
93+ wdl_string = search.position .get_side () == CLR_WHITE ? BLACK_WIN_STRING : WHITE_WIN_STRING;
94+ else
95+ wdl_string = DRAW_STRING;
96+ break ;
97+ }
98+
99+ auto result = search_position ();
100+ int white_relative_score = search.position .get_side () == CLR_WHITE ? result.score : -result.score ;
101+
102+ // TODO command line arg
103+ if (result.score >= 1000 && ply == 8 )
104+ return ;
105+
106+ if (filter_position ())
107+ save_position (white_relative_score);
108+
109+ // TODO command line arg
110+ bool is_draw_score = std::abs (result.score ) <= 20 ;
111+ bool is_win_score = std::abs (result.score ) >= 1000 ;
112+
113+ draw_score_counter = is_draw_score ? draw_score_counter + 1 : 0 ;
114+ win_score_counter = is_win_score ? win_score_counter + 1 : 0 ;
115+
116+ // TODO command line arg
117+ if (draw_score_counter >= 12 ) {
118+ wdl_string = DRAW_STRING;
119+ break ;
120+ }
121+
122+ if (win_score_counter >= 4 ) {
123+ wdl_string = white_relative_score > 0 ? WHITE_WIN_STRING : BLACK_WIN_STRING;
124+ break ;
125+ }
126+
127+ search.position .apply_move (result.best_move );
128+ search.reset_counters ();
129+ ply++;
130+ }
131+ save_game (wdl_string);
132+ }
0 commit comments