Rev 116 | Rev 130 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 116 | Rev 119 | ||
|---|---|---|---|
| Line 24... | Line 24... | ||
| 24 | bool PlayerEngine_Init (player_t *player) |
24 | bool PlayerEngine_Init (player_t *player) |
| 25 | { |
25 | { |
| 26 | // this function starts a chess engine as a child process. This process's stdin and |
26 | // this function starts a chess engine as a child process. This process's stdin and |
| 27 | // stdout are redirected to the handles we give it, so that we may read/write to it. |
27 | // stdout are redirected to the handles we give it, so that we may read/write to it. |
| 28 | 28 | ||
| - | 29 | engineprogram_t *program; |
|
| 29 | wchar_t widechar_buffer[256]; |
30 | wchar_t widechar_buffer[256]; |
| 30 | SYSTEM_INFO sysinfo; |
31 | SYSTEM_INFO sysinfo; |
| 31 | SECURITY_ATTRIBUTES saAttr; |
32 | SECURITY_ATTRIBUTES saAttr; |
| 32 | STARTUPINFO si; |
33 | STARTUPINFO si; |
| 33 | int try_index; |
34 | int try_index; |
| Line 38... | Line 39... | ||
| 38 | hChessEngineStdinWr = NULL; |
39 | hChessEngineStdinWr = NULL; |
| 39 | hChessEngineStdoutRd = NULL; |
40 | hChessEngineStdoutRd = NULL; |
| 40 | hChessEngineStdoutWr = NULL; |
41 | hChessEngineStdoutWr = NULL; |
| 41 | player->wants_hint = false; |
42 | player->wants_hint = false; |
| 42 | 43 | ||
| 43 | // |
44 | // quick access to engine program |
| 44 |
|
45 | program = &options.engine.programs[options.engine.selected_program]; |
| 45 | 46 | ||
| 46 | // build the chess engine module path and pathname |
47 | // build the chess engine module path and pathname |
| 47 | swprintf_s (chessenginemodule_path, WCHAR_SIZEOF (chessenginemodule_path), L"%s/engines/%s", app_path, |
48 | swprintf_s (chessenginemodule_path, WCHAR_SIZEOF (chessenginemodule_path), L"%s/engines/%s", app_path, program->folder); |
| 48 | swprintf_s (chessenginemodule_pathname, WCHAR_SIZEOF (chessenginemodule_pathname), L"%s/engines/%s/%s", app_path, |
49 | swprintf_s (chessenginemodule_pathname, WCHAR_SIZEOF (chessenginemodule_pathname), L"%s/engines/%s/%s", app_path, program->folder, program->cmdline); |
| 49 | 50 | ||
| 50 | // prepare the pipes' security attributes |
51 | // prepare the pipes' security attributes |
| 51 | memset (&saAttr, 0, sizeof (saAttr)); |
52 | memset (&saAttr, 0, sizeof (saAttr)); |
| 52 | saAttr.nLength = sizeof (SECURITY_ATTRIBUTES); |
53 | saAttr.nLength = sizeof (SECURITY_ATTRIBUTES); |
| 53 | saAttr.bInheritHandle = true; // set the bInheritHandle flag so pipe handles are inherited |
54 | saAttr.bInheritHandle = true; // set the bInheritHandle flag so pipe handles are inherited |
| Line 66... | Line 67... | ||
| 66 | si.dwFlags = STARTF_USESTDHANDLES; |
67 | si.dwFlags = STARTF_USESTDHANDLES; |
| 67 | si.hStdInput = hChessEngineStdinRd; |
68 | si.hStdInput = hChessEngineStdinRd; |
| 68 | si.hStdOutput = hChessEngineStdoutWr; |
69 | si.hStdOutput = hChessEngineStdoutWr; |
| 69 | si.hStdError = hChessEngineStdoutWr; |
70 | si.hStdError = hChessEngineStdoutWr; |
| 70 | if (!CreateProcess (chessenginemodule_pathname, // module pathname |
71 | if (!CreateProcess (chessenginemodule_pathname, // module pathname |
| 71 |
|
72 | program->cmdline, // command line |
| 72 | NULL, NULL, |
73 | NULL, NULL, |
| 73 | true, // handles are inherited |
74 | true, // handles are inherited |
| 74 | CREATE_NO_WINDOW | DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP, |
75 | CREATE_NO_WINDOW | DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP, |
| 75 | NULL, |
76 | NULL, |
| 76 | chessenginemodule_path, // process path |
77 | chessenginemodule_path, // process path |
| Line 100... | Line 101... | ||
| 100 | // has the engine process not spoken yet ? |
101 | // has the engine process not spoken yet ? |
| 101 | if (player->recvbuffer[0] == 0) |
102 | if (player->recvbuffer[0] == 0) |
| 102 | { |
103 | { |
| 103 | messagebox.hWndParent = hMainWnd; |
104 | messagebox.hWndParent = hMainWnd; |
| 104 | wcscpy_s (messagebox.title, WCHAR_SIZEOF (messagebox.title), LOCALIZE (L"ImportantMessage")); |
105 | wcscpy_s (messagebox.title, WCHAR_SIZEOF (messagebox.title), LOCALIZE (L"ImportantMessage")); |
| 105 |
|
106 | swprintf_s (messagebox.text, WCHAR_SIZEOF (messagebox.text), LOCALIZE (L"Error_ChessEngineInitializationFailed"), program->folder); |
| 106 | messagebox.flags = MB_ICONWARNING | MB_OK; |
107 | messagebox.flags = MB_ICONWARNING | MB_OK; |
| 107 | DialogBox_Message (&messagebox); // display a modeless error message box |
108 | DialogBox_Message (&messagebox); // display a modeless error message box |
| 108 | 109 | ||
| 109 | PlayerEngine_Shutdown (player); // on error, shutdown the engine |
110 | PlayerEngine_Shutdown (player); // on error, shutdown the engine |
| 110 | return (false); |
111 | return (false); |
| Line 112... | Line 113... | ||
| 112 | 113 | ||
| 113 | // eventually initialize the debug log file |
114 | // eventually initialize the debug log file |
| 114 | Debug_Init (L"Chess engine output.txt"); |
115 | Debug_Init (L"Chess engine output.txt"); |
| 115 | 116 | ||
| 116 | // build the init file full qualified path name and try to open it |
117 | // build the init file full qualified path name and try to open it |
| 117 | swprintf_s (chessengineinitfile_pathname, WCHAR_SIZEOF (chessengineinitfile_pathname), L"%s/engines/%s/init.txt", app_path, |
118 | swprintf_s (chessengineinitfile_pathname, WCHAR_SIZEOF (chessengineinitfile_pathname), L"%s/engines/%s/init.txt", app_path, program->folder); |
| 118 | _wfopen_s (&fp, chessengineinitfile_pathname, L"r"); |
119 | _wfopen_s (&fp, chessengineinitfile_pathname, L"r"); |
| 119 | 120 | ||
| 120 | // could the init file be opened ? |
121 | // could the init file be opened ? |
| 121 | if (fp != NULL) |
122 | if (fp != NULL) |
| 122 | { |
123 | { |
| Line 139... | Line 140... | ||
| 139 | 140 | ||
| 140 | fclose (fp); // finished, close the file |
141 | fclose (fp); // finished, close the file |
| 141 | } |
142 | } |
| 142 | 143 | ||
| 143 | // everything's okay, set engine name as the player's name |
144 | // everything's okay, set engine name as the player's name |
| 144 | wcscpy_s (player->name, WCHAR_SIZEOF (player->name), |
145 | wcscpy_s (player->name, WCHAR_SIZEOF (player->name), program->name); |
| 145 | 146 | ||
| 146 | return (true); // finished |
147 | return (true); // finished |
| 147 | } |
148 | } |
| 148 | 149 | ||
| 149 | 150 | ||
| Line 154... | Line 155... | ||
| 154 | unsigned long exit_code; |
155 | unsigned long exit_code; |
| 155 | unsigned long handle_flags; |
156 | unsigned long handle_flags; |
| 156 | int attempt_index; |
157 | int attempt_index; |
| 157 | 158 | ||
| 158 | // send the engine a quit command |
159 | // send the engine a quit command |
| 159 | Player_SendBuffer_Add (player, 1000, options.engine. |
160 | Player_SendBuffer_Add (player, 1000, options.engine.programs[options.engine.selected_program].command_quit); |
| 160 | Player_SendBuffer_Add (player, 1000, L"\n"); // since the format string was read from the options, don't forget to end it with a carriage return |
161 | Player_SendBuffer_Add (player, 1000, L"\n"); // since the format string was read from the options, don't forget to end it with a carriage return |
| 161 | PlayerEngine_Send (player); |
162 | PlayerEngine_Send (player); |
| 162 | 163 | ||
| 163 | // close the pipe handles |
164 | // close the pipe handles |
| 164 | if (hChessEngineStdinRd) |
165 | if (hChessEngineStdinRd) |
| Line 211... | Line 212... | ||
| 211 | 212 | ||
| 212 | bool PlayerEngine_Think (player_t *player) |
213 | bool PlayerEngine_Think (player_t *player) |
| 213 | { |
214 | { |
| 214 | // this function reads and writes any necessary data from and to the chess engine. Returns TRUE if scene needs to be updated. |
215 | // this function reads and writes any necessary data from and to the chess engine. Returns TRUE if scene needs to be updated. |
| 215 | 216 | ||
| - | 217 | engineprogram_t *program; |
|
| 216 | wchar_t line_buffer[256]; |
218 | wchar_t line_buffer[256]; |
| 217 | wchar_t *line_pointer; |
219 | wchar_t *line_pointer; |
| 218 | wchar_t *move_string; |
220 | wchar_t *move_string; |
| 219 | int char_index; |
221 | int char_index; |
| 220 | int length; |
222 | int length; |
| 221 | boardmove_t move; |
223 | boardmove_t move; |
| 222 | player_t *current_player; |
224 | player_t *current_player; |
| 223 | player_t *opposite_player; |
225 | player_t *opposite_player; |
| 224 | bool do_update; |
226 | bool do_update; |
| - | 227 | ||
| - | 228 | // quick access to chess engine program |
|
| - | 229 | program = &options.engine.programs[options.engine.selected_program]; |
|
| 225 | 230 | ||
| 226 | // don't update the scene until told otherwise |
231 | // don't update the scene until told otherwise |
| 227 | do_update = false; |
232 | do_update = false; |
| 228 | 233 | ||
| 229 | // get current and opposite players |
234 | // get current and opposite players |
| Line 331... | Line 336... | ||
| 331 | // has the game ended already ? |
336 | // has the game ended already ? |
| 332 | if (the_board.game_state > STATE_PLAYING) |
337 | if (the_board.game_state > STATE_PLAYING) |
| 333 | continue; // ignore all that the engine tells us. Game is over already. |
338 | continue; // ignore all that the engine tells us. Game is over already. |
| 334 | 339 | ||
| 335 | // else is it a normal move ? |
340 | // else is it a normal move ? |
| 336 | else if ((move_string = wcsstr (line_buffer, |
341 | else if ((move_string = wcsstr (line_buffer, program->replystring_move)) != NULL) |
| 337 | move_string += wcslen ( |
342 | move_string += wcslen (program->replystring_move); // go to the parsable data |
| 338 | 343 | ||
| 339 | // else it's any other sort of line |
344 | // else it's any other sort of line |
| 340 | else |
345 | else |
| 341 | continue; // skip lines that don't contain any valid move data |
346 | continue; // skip lines that don't contain any valid move data |
| 342 | 347 | ||
| Line 359... | Line 364... | ||
| 359 | 364 | ||
| 360 | // is it NOT a hint, are blunders allowed, should we do one now AND can we do one now ? |
365 | // is it NOT a hint, are blunders allowed, should we do one now AND can we do one now ? |
| 361 | if (!is_hint_pending && (options.engine.blunder_chances > 0) && (rand () % 100 < options.engine.blunder_chances) |
366 | if (!is_hint_pending && (options.engine.blunder_chances > 0) && (rand () % 100 < options.engine.blunder_chances) |
| 362 | && Move_FindRandomMove (&the_board.moves[the_board.move_count - 1], player->color, &move)) |
367 | && Move_FindRandomMove (&the_board.moves[the_board.move_count - 1], player->color, &move)) |
| 363 | { |
368 | { |
| 364 | Player_SendBuffer_Add (player, 1000, |
369 | Player_SendBuffer_Add (player, 1000, program->command_force, Move_BuildString (&move)); // send the blunderous move to the engine |
| 365 | Player_SendBuffer_Add (player, 1000, L"\n"); // since the format string was read from the options, don't forget to end it with a carriage return |
370 | Player_SendBuffer_Add (player, 1000, L"\n"); // since the format string was read from the options, don't forget to end it with a carriage return |
| 366 | if ( |
371 | if (_wcsnicmp (program->name, L"Crafty", 6) == 0) |
| 367 | Player_SendBuffer_Add (player, 1000, L"disp\n"); |
372 | Player_SendBuffer_Add (player, 1000, L"disp\n"); |
| 368 | Debug_Log (L"===Discarding engine move, forcing a blunderous move (%s) instead===\n", Move_BuildString (&move)); // blunder |
373 | Debug_Log (L"===Discarding engine move, forcing a blunderous move (%s) instead===\n", Move_BuildString (&move)); // blunder |
| 369 | } |
374 | } |
| 370 | 375 | ||
| 371 | // mark the engine's selected and hovered squares |
376 | // mark the engine's selected and hovered squares |
| Line 399... | Line 404... | ||
| 399 | Debug_Log (L"===Hint received, rebuilding board and telling engine to backup 1 move===\n"); |
404 | Debug_Log (L"===Hint received, rebuilding board and telling engine to backup 1 move===\n"); |
| 400 | Debug_Log (L"===setting up board using FEN string===\n"); |
405 | Debug_Log (L"===setting up board using FEN string===\n"); |
| 401 | 406 | ||
| 402 | // instruct it about its allowed search depth BEFORE each table set (this ensures engine will be "ready" to handle the command) |
407 | // instruct it about its allowed search depth BEFORE each table set (this ensures engine will be "ready" to handle the command) |
| 403 | // then get the current game state in FEN format and feed it to the engine |
408 | // then get the current game state in FEN format and feed it to the engine |
| 404 | Player_SendBuffer_Add (player, 1000, |
409 | Player_SendBuffer_Add (player, 1000, program->command_sd, options.engine.depth); |
| 405 | Player_SendBuffer_Add (player, 1000, L"\n"); // since the format string was read from the options, don't forget to end it with a carriage return |
410 | Player_SendBuffer_Add (player, 1000, L"\n"); // since the format string was read from the options, don't forget to end it with a carriage return |
| 406 | Player_SendBuffer_Add (player, 1000, |
411 | Player_SendBuffer_Add (player, 1000, program->command_setboard, the_board.moves[the_board.move_count - 1].fen_string); |
| 407 | Player_SendBuffer_Add (player, 1000, L"\n"); // since the format string was read from the options, don't forget to end it with a carriage return |
412 | Player_SendBuffer_Add (player, 1000, L"\n"); // since the format string was read from the options, don't forget to end it with a carriage return |
| 408 | 413 | ||
| 409 | if ( |
414 | if (_wcsnicmp (program->name, L"Crafty", 6) == 0) |
| 410 | Player_SendBuffer_Add (player, 1000, L"disp\n"); |
415 | Player_SendBuffer_Add (player, 1000, L"disp\n"); |
| 411 | } |
416 | } |
| 412 | 417 | ||
| 413 | do_update = true; // remember to update the 3D scene |
418 | do_update = true; // remember to update the 3D scene |
| 414 | } |
419 | } |
| Line 434... | Line 439... | ||
| 434 | if (the_board.was_setup) |
439 | if (the_board.was_setup) |
| 435 | { |
440 | { |
| 436 | Debug_Log (L"===Got board setup notification from interface===\n"); |
441 | Debug_Log (L"===Got board setup notification from interface===\n"); |
| 437 | 442 | ||
| 438 | // send a new game command to the chess engine |
443 | // send a new game command to the chess engine |
| 439 | Player_SendBuffer_Add (player, 1000, |
444 | Player_SendBuffer_Add (player, 1000, program->command_new); |
| 440 | Player_SendBuffer_Add (player, 1000, L"\n"); // since the format string was read from the options, don't forget to end it with a carriage return |
445 | Player_SendBuffer_Add (player, 1000, L"\n"); // since the format string was read from the options, don't forget to end it with a carriage return |
| 441 | 446 | ||
| 442 | // just set up the board from its Forsyth-Edwards notation |
447 | // just set up the board from its Forsyth-Edwards notation |
| 443 | Debug_Log (L"===setting up board using FEN string===\n"); |
448 | Debug_Log (L"===setting up board using FEN string===\n"); |
| 444 | 449 | ||
| 445 | // instruct it about its allowed search depth BEFORE each table set (this ensures engine will be "ready" to handle the command) |
450 | // instruct it about its allowed search depth BEFORE each table set (this ensures engine will be "ready" to handle the command) |
| 446 | // then get the current game state in FEN format and feed it to the engine |
451 | // then get the current game state in FEN format and feed it to the engine |
| 447 | Player_SendBuffer_Add (player, 1000, |
452 | Player_SendBuffer_Add (player, 1000, program->command_sd, options.engine.depth); |
| 448 | Player_SendBuffer_Add (player, 1000, L"\n"); // since the format string was read from the options, don't forget to end it with a carriage return |
453 | Player_SendBuffer_Add (player, 1000, L"\n"); // since the format string was read from the options, don't forget to end it with a carriage return |
| 449 | Player_SendBuffer_Add (player, 1000, |
454 | Player_SendBuffer_Add (player, 1000, program->command_setboard, the_board.moves[the_board.move_count - 1].fen_string); |
| 450 | Player_SendBuffer_Add (player, 1000, L"\n"); // since the format string was read from the options, don't forget to end it with a carriage return |
455 | Player_SendBuffer_Add (player, 1000, L"\n"); // since the format string was read from the options, don't forget to end it with a carriage return |
| 451 | 456 | ||
| 452 | current_obstinacy = 0; // reset current obstinacy |
457 | current_obstinacy = 0; // reset current obstinacy |
| 453 | is_hint_pending = false; // no hint was requested so far |
458 | is_hint_pending = false; // no hint was requested so far |
| 454 | 459 | ||
| 455 | if ( |
460 | if (_wcsnicmp (program->name, L"Crafty", 6) == 0) |
| 456 | Player_SendBuffer_Add (player, 1000, L"disp\n"); |
461 | Player_SendBuffer_Add (player, 1000, L"disp\n"); |
| 457 | } |
462 | } |
| 458 | 463 | ||
| 459 | // have we been notified that players are swapping colors ? (N.B. when this happens in human vs. computer mode, it's always that the human player is *GIVING* his turn) |
464 | // have we been notified that players are swapping colors ? (N.B. when this happens in human vs. computer mode, it's always that the human player is *GIVING* his turn) |
| 460 | if (the_board.want_playerswap) |
465 | if (the_board.want_playerswap) |
| 461 | { |
466 | { |
| 462 | Debug_Log (L"===Got player SWAP notification from interface===\n"); |
467 | Debug_Log (L"===Got player SWAP notification from interface===\n"); |
| 463 | Player_SendBuffer_Add (player, 1000, |
468 | Player_SendBuffer_Add (player, 1000, program->command_go); // tell engine it's now the current player |
| 464 | Player_SendBuffer_Add (player, 1000, L"\n"); // since the format string was read from the options, don't forget to end it with a carriage return |
469 | Player_SendBuffer_Add (player, 1000, L"\n"); // since the format string was read from the options, don't forget to end it with a carriage return |
| 465 | } |
470 | } |
| 466 | 471 | ||
| 467 | // have we been notified that the current player just changed ? |
472 | // have we been notified that the current player just changed ? |
| 468 | if (the_board.has_playerchanged) |
473 | if (the_board.has_playerchanged) |
| Line 474... | Line 479... | ||
| 474 | { |
479 | { |
| 475 | // is it NOT a board setup AND has at least one move been played (meaning it was just the other's turn before) ? |
480 | // is it NOT a board setup AND has at least one move been played (meaning it was just the other's turn before) ? |
| 476 | if (!the_board.was_setup && (the_board.move_count > 1)) |
481 | if (!the_board.was_setup && (the_board.move_count > 1)) |
| 477 | { |
482 | { |
| 478 | Debug_Log (L"===Player just played, sending the chosen move to engine===\n"); |
483 | Debug_Log (L"===Player just played, sending the chosen move to engine===\n"); |
| 479 | if ( |
484 | if (_wcsnicmp (program->name, L"Crafty", 6) == 0) |
| 480 | Player_SendBuffer_Add (player, 1000, L"disp\n"); |
485 | Player_SendBuffer_Add (player, 1000, L"disp\n"); |
| 481 | 486 | ||
| 482 | // instruct it about its allowed search depth BEFORE each move (this ensures engine will be "ready" to handle the command) |
487 | // instruct it about its allowed search depth BEFORE each move (this ensures engine will be "ready" to handle the command) |
| 483 | // then build the move string, and send the move string to the engine |
488 | // then build the move string, and send the move string to the engine |
| 484 | Player_SendBuffer_Add (player, 1000, |
489 | Player_SendBuffer_Add (player, 1000, program->command_sd, options.engine.depth); |
| 485 | Player_SendBuffer_Add (player, 1000, L"\n"); // since the format string was read from the options, don't forget to end it with a carriage return |
490 | Player_SendBuffer_Add (player, 1000, L"\n"); // since the format string was read from the options, don't forget to end it with a carriage return |
| 486 | Player_SendBuffer_Add (player, 1000, |
491 | Player_SendBuffer_Add (player, 1000, program->command_move, Move_BuildString (&the_board.moves[the_board.move_count - 1])); |
| 487 | Player_SendBuffer_Add (player, 1000, L"\n"); // end the send buffer with a carriage return |
492 | Player_SendBuffer_Add (player, 1000, L"\n"); // end the send buffer with a carriage return |
| 488 | } |
493 | } |
| 489 | 494 | ||
| 490 | // else game has not started yet, but it's our turn |
495 | // else game has not started yet, but it's our turn |
| 491 | else |
496 | else |
| 492 | { |
497 | { |
| 493 | Player_SendBuffer_Add (player, 1000, |
498 | Player_SendBuffer_Add (player, 1000, program->command_go); // so let's start the game |
| 494 | Player_SendBuffer_Add (player, 1000, L"\n"); // since the format string was read from the options, don't forget to end it with a carriage return |
499 | Player_SendBuffer_Add (player, 1000, L"\n"); // since the format string was read from the options, don't forget to end it with a carriage return |
| 495 | } |
500 | } |
| 496 | } |
501 | } |
| 497 | } |
502 | } |
| 498 | 503 | ||
| Line 505... | Line 510... | ||
| 505 | // does our opponent want a hint ? |
510 | // does our opponent want a hint ? |
| 506 | if (current_player->wants_hint) |
511 | if (current_player->wants_hint) |
| 507 | { |
512 | { |
| 508 | current_player->wants_hint = false; // don't ask twice |
513 | current_player->wants_hint = false; // don't ask twice |
| 509 | Debug_Log (L"===Hint requested, asking engine for it===\n"); |
514 | Debug_Log (L"===Hint requested, asking engine for it===\n"); |
| 510 | Player_SendBuffer_Add (player, 1000, |
515 | Player_SendBuffer_Add (player, 1000, program->command_go); // tell the computer to analyze this position |
| 511 | Player_SendBuffer_Add (player, 1000, L"\n"); // since the format string was read from the options, don't forget to end it with a carriage return |
516 | Player_SendBuffer_Add (player, 1000, L"\n"); // since the format string was read from the options, don't forget to end it with a carriage return |
| 512 | is_hint_pending = true; // remember a hint is pending |
517 | is_hint_pending = true; // remember a hint is pending |
| 513 | 518 | ||
| 514 | // FIXME: move to scene.cpp |
519 | // FIXME: move to scene.cpp |
| 515 | Scene_SetText (&the_scene.gui.central_text, 50.0f, 40.0f, -1, ALIGN_CENTER, ALIGN_CENTER, ALIGN_CENTER, centermsg_fontindex, RGBA_TO_RGBACOLOR (255, 255, 255, 191), |
520 | Scene_SetText (&the_scene.gui.central_text, 50.0f, 40.0f, -1, ALIGN_CENTER, ALIGN_CENTER, ALIGN_CENTER, centermsg_fontindex, RGBA_TO_RGBACOLOR (255, 255, 255, 191), |
| Line 532... | Line 537... | ||
| 532 | // just set up the board from its Forsyth-Edwards notation |
537 | // just set up the board from its Forsyth-Edwards notation |
| 533 | Debug_Log (L"===setting up board using FEN string===\n"); |
538 | Debug_Log (L"===setting up board using FEN string===\n"); |
| 534 | 539 | ||
| 535 | // instruct it about its allowed search depth BEFORE each table set (this ensures engine will be "ready" to handle the command) |
540 | // instruct it about its allowed search depth BEFORE each table set (this ensures engine will be "ready" to handle the command) |
| 536 | // then get the current game state in FEN format and feed it to the engine |
541 | // then get the current game state in FEN format and feed it to the engine |
| 537 | Player_SendBuffer_Add (player, 1000, |
542 | Player_SendBuffer_Add (player, 1000, program->command_sd, options.engine.depth); |
| 538 | Player_SendBuffer_Add (player, 1000, L"\n"); // since the format string was read from the options, don't forget to end it with a carriage return |
543 | Player_SendBuffer_Add (player, 1000, L"\n"); // since the format string was read from the options, don't forget to end it with a carriage return |
| 539 | Player_SendBuffer_Add (player, 1000, |
544 | Player_SendBuffer_Add (player, 1000, program->command_setboard, the_board.moves[the_board.move_count - 1].fen_string); |
| 540 | Player_SendBuffer_Add (player, 1000, L"\n"); // since the format string was read from the options, don't forget to end it with a carriage return |
545 | Player_SendBuffer_Add (player, 1000, L"\n"); // since the format string was read from the options, don't forget to end it with a carriage return |
| 541 | 546 | ||
| 542 | if ( |
547 | if (_wcsnicmp (program->name, L"Crafty", 6) == 0) |
| 543 | Player_SendBuffer_Add (player, 1000, L"disp\n"); |
548 | Player_SendBuffer_Add (player, 1000, L"disp\n"); |
| 544 | 549 | ||
| 545 | do_update = true; // remember to update the 3D scene |
550 | do_update = true; // remember to update the 3D scene |
| 546 | } |
551 | } |
| 547 | } |
552 | } |