Rev 48 | Rev 53 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 48 | Rev 50 | ||
---|---|---|---|
Line 11... | Line 11... | ||
11 | static HANDLE hChessEngineStdinRd; |
11 | static HANDLE hChessEngineStdinRd; |
12 | static HANDLE hChessEngineStdinWr; |
12 | static HANDLE hChessEngineStdinWr; |
13 | static HANDLE hChessEngineStdoutRd; |
13 | static HANDLE hChessEngineStdoutRd; |
14 | static HANDLE hChessEngineStdoutWr; |
14 | static HANDLE hChessEngineStdoutWr; |
15 | static int current_obstinacy; |
15 | static int current_obstinacy; |
- | 16 | static bool is_hint_pending; |
|
16 | 17 | ||
17 | // prototypes of local functions |
18 | // prototypes of local functions |
18 | static void PlayerEngine_Recv (player_t *player); |
19 | static void PlayerEngine_Recv (player_t *player); |
19 | static void PlayerEngine_Send (player_t *player); |
20 | static void PlayerEngine_Send (player_t *player); |
20 | static wchar_t *Move_BuildString (boardmove_t *move); |
21 | static wchar_t *Move_BuildString (boardmove_t *move); |
Line 195... | Line 196... | ||
195 | int length; |
196 | int length; |
196 | boardmove_t move; |
197 | boardmove_t move; |
197 | player_t *current_player; |
198 | player_t *current_player; |
198 | player_t *opposite_player; |
199 | player_t *opposite_player; |
199 | bool do_update; |
200 | bool do_update; |
200 | bool is_hint; |
- | |
201 | 201 | ||
202 | // don't update the scene until told otherwise |
202 | // don't update the scene until told otherwise |
203 | do_update = false; |
203 | do_update = false; |
204 | 204 | ||
205 | // get current and opposite players |
205 | // get current and opposite players |
Line 269... | Line 269... | ||
269 | } |
269 | } |
270 | 270 | ||
271 | // has the game ended already ? |
271 | // has the game ended already ? |
272 | if (the_board.game_state > STATE_PLAYING) |
272 | if (the_board.game_state > STATE_PLAYING) |
273 | continue; // ignore all that the engine tells us. Game is over already. |
273 | continue; // ignore all that the engine tells us. Game is over already. |
274 | - | ||
275 | // is it a hint ? |
- | |
276 | if ((move_string = wcsstr (line_buffer, options.engine.program_options.replystring_hint)) != NULL) |
- | |
277 | { |
- | |
278 | move_string += wcslen (options.engine.program_options.replystring_hint); // go to the parsable data |
- | |
279 | is_hint = true; |
- | |
280 | } |
- | |
281 | 274 | ||
282 | // else is it a normal move ? |
275 | // else is it a normal move ? |
283 | else if ((move_string = wcsstr (line_buffer, options.engine.program_options.replystring_move)) != NULL) |
276 | else if ((move_string = wcsstr (line_buffer, options.engine.program_options.replystring_move)) != NULL) |
284 | { |
- | |
285 | move_string += wcslen (options.engine.program_options.replystring_move); // go to the parsable data |
277 | move_string += wcslen (options.engine.program_options.replystring_move); // go to the parsable data |
286 | is_hint = false; |
- | |
287 | } |
- | |
288 | 278 | ||
289 | // else it's any other sort of line |
279 | // else it's any other sort of line |
290 | else |
280 | else |
291 | continue; // skip lines that don't contain any valid move data |
281 | continue; // skip lines that don't contain any valid move data |
292 | 282 | ||
Line 306... | Line 296... | ||
306 | Debug_Log (L"===Skipping line (invalid move syntax)===\n%s", move_string); |
296 | Debug_Log (L"===Skipping line (invalid move syntax)===\n%s", move_string); |
307 | continue; // so now, if there are NOT two digits AND it's not a kind of castle, it can't be a move so skip that line |
297 | continue; // so now, if there are NOT two digits AND it's not a kind of castle, it can't be a move so skip that line |
308 | } |
298 | } |
309 | 299 | ||
310 | // is it NOT a hint, are blunders allowed, should we do one now AND can we do one now ? |
300 | // is it NOT a hint, are blunders allowed, should we do one now AND can we do one now ? |
311 | if (! |
301 | if (!is_hint_pending && (options.engine.blunder_chances > 0) && (rand () % 100 < options.engine.blunder_chances) |
312 | && Move_FindRandomMove (&the_board.moves[the_board.move_count - 1], player->color, &move)) |
302 | && Move_FindRandomMove (&the_board.moves[the_board.move_count - 1], player->color, &move)) |
313 | { |
303 | { |
314 | Player_SendBuffer_Add (player, 1000, options.engine.program_options.command_force, Move_BuildString (&move)); // send the blunderous move to the engine |
304 | Player_SendBuffer_Add (player, 1000, options.engine.program_options.command_force, Move_BuildString (&move)); // send the blunderous move to the engine |
315 | 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 |
305 | 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 |
316 | if (wcscmp (options.engine.program, L"Crafty") == 0) |
306 | if (wcscmp (options.engine.program, L"Crafty") == 0) |
317 | Player_SendBuffer_Add (player, 1000, L"disp\n"); |
307 | Player_SendBuffer_Add (player, 1000, L"disp\n"); |
318 | Debug_Log (L"===Discarding engine move, forcing a blunderous move (%s) instead===\n", Move_BuildString (&move)); // blunder |
308 | Debug_Log (L"===Discarding engine move, forcing a blunderous move (%s) instead===\n", Move_BuildString (&move)); // blunder |
319 | } |
309 | } |
320 | 310 | ||
321 | // mark the engine's selected and hovered squares |
311 | // mark the engine's selected and hovered squares |
322 | Board_SetSelectedAndHovered (&the_board, move.source[0], move.source[1], move.target[0], move.target[1]); |
312 | Board_SetSelectedAndHovered (&the_board, move.source[0], move.source[1], move.target[0], move.target[1]); |
323 | 313 | ||
324 | // was it NOT a hint ? |
314 | // was it NOT a hint ? |
325 | if (! |
315 | if (!is_hint_pending) |
326 | { |
316 | { |
- | 317 | the_scene.gui.central_text.disappear_time = current_time + 1.0f; // fade the "thinking" phrase out now (FIXME: ugly) |
|
- | 318 | the_scene.gui.want_spinwheel = false; // stop spinning wheel |
|
- | 319 | ||
327 | Board_AppendMove (&the_board, the_board.selected_position[0], the_board.selected_position[1], the_board.hovered_position[0], the_board.hovered_position[1], move.promotion_type, NULL); |
320 | Board_AppendMove (&the_board, the_board.selected_position[0], the_board.selected_position[1], the_board.hovered_position[0], the_board.hovered_position[1], move.promotion_type, NULL); |
328 | the_board.has_playerchanged = true; // do the movement and switch players |
321 | the_board.has_playerchanged = true; // do the movement and switch players |
329 | 322 | ||
330 | // forget the hovered and selected positions |
323 | // forget the hovered and selected positions |
331 | Board_SetSelectedAndHovered (&the_board, -1, -1, -1, -1); |
324 | Board_SetSelectedAndHovered (&the_board, -1, -1, -1, -1); |
332 | animation_endtime = current_time + ANIMATION_DURATION; // wait for animation time seconds |
325 | animation_endtime = current_time + ANIMATION_DURATION; // wait for animation time seconds |
333 | sound_playtime = current_time + ANIMATION_DURATION - 0.1f; // play sound near the end of animation |
326 | sound_playtime = current_time + ANIMATION_DURATION - 0.1f; // play sound near the end of animation |
334 | } |
327 | } |
335 | 328 | ||
336 | // else it was a hint |
329 | // else it was a hint |
337 | else |
330 | else |
- | 331 | { |
|
- | 332 | the_scene.gui.central_text.disappear_time = current_time + 0.1f; // fade the "thinking" phrase out now quickly (FIXME: ugly) |
|
- | 333 | the_scene.gui.want_spinwheel = false; // stop spinning wheel |
|
- | 334 | ||
338 | highlight_endtime = current_time + 2.0f; // just highlight this part for a little more than one second |
335 | highlight_endtime = current_time + 2.0f; // just highlight this part for a little more than one second |
- | 336 | is_hint_pending = false; // remember no hint is pending any longer |
|
- | 337 | ||
- | 338 | // we must now restore the board to its last state. Just set up the board again from its current Forsyth-Edwards notation |
|
- | 339 | Debug_Log (L"===Hint received, rebuilding board and telling engine to backup 1 move===\n"); |
|
- | 340 | Debug_Log (L"===setting up board using FEN string===\n"); |
|
- | 341 | ||
- | 342 | // instruct it about its allowed search depth BEFORE each table set (this ensures engine will be "ready" to handle the command) |
|
- | 343 | // then get the current game state in FEN format and feed it to the engine |
|
- | 344 | Player_SendBuffer_Add (player, 1000, options.engine.program_options.command_sd, options.engine.depth); |
|
- | 345 | 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 |
|
- | 346 | Player_SendBuffer_Add (player, 1000, options.engine.program_options.command_setboard, the_board.moves[the_board.move_count - 1].fen_string); |
|
- | 347 | 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 |
|
- | 348 | ||
- | 349 | if (wcscmp (options.engine.program, L"Crafty") == 0) |
|
- | 350 | Player_SendBuffer_Add (player, 1000, L"disp\n"); |
|
- | 351 | } |
|
339 | 352 | ||
340 | the_scene.gui.central_text.disappear_time = current_time + 1.0f; // fade the "thinking" phrase out now (FIXME: ugly) |
- | |
341 | the_scene.gui.want_spinwheel = false; // stop spinning wheel |
- | |
342 | do_update = true; // remember to update the 3D scene |
353 | do_update = true; // remember to update the 3D scene |
343 | } |
354 | } |
344 | 355 | ||
345 | // now clean the input buffer of all the lines we parsed |
356 | // now clean the input buffer of all the lines we parsed |
346 | line_pointer = wcsrchr (player->recvbuffer, L'\n'); // reach the last carriage return |
357 | line_pointer = wcsrchr (player->recvbuffer, L'\n'); // reach the last carriage return |
Line 374... | Line 385... | ||
374 | // instruct it about its allowed search depth BEFORE each table set (this ensures engine will be "ready" to handle the command) |
385 | // instruct it about its allowed search depth BEFORE each table set (this ensures engine will be "ready" to handle the command) |
375 | // then get the current game state in FEN format and feed it to the engine |
386 | // then get the current game state in FEN format and feed it to the engine |
376 | Player_SendBuffer_Add (player, 1000, options.engine.program_options.command_sd, options.engine.depth); |
387 | Player_SendBuffer_Add (player, 1000, options.engine.program_options.command_sd, options.engine.depth); |
377 | 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 |
388 | 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 |
378 | Player_SendBuffer_Add (player, 1000, options.engine.program_options.command_setboard, the_board.moves[the_board.move_count - 1].fen_string); |
389 | Player_SendBuffer_Add (player, 1000, options.engine.program_options.command_setboard, the_board.moves[the_board.move_count - 1].fen_string); |
379 | 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 |
390 | 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 |
380 | 391 | ||
381 | / |
392 | current_obstinacy = 0; // reset current obstinacy |
382 |
|
393 | is_hint_pending = false; // no hint was requested so far |
383 | 394 | ||
384 | if (wcscmp (options.engine.program, L"Crafty") == 0) |
395 | if (wcscmp (options.engine.program, L"Crafty") == 0) |
385 | Player_SendBuffer_Add (player, 1000, L"disp\n"); |
396 | Player_SendBuffer_Add (player, 1000, L"disp\n"); |
386 | } |
397 | } |
387 | 398 | ||
Line 434... | Line 445... | ||
434 | // does our opponent want a hint ? |
445 | // does our opponent want a hint ? |
435 | if (current_player->wants_hint) |
446 | if (current_player->wants_hint) |
436 | { |
447 | { |
437 | current_player->wants_hint = false; // don't ask twice |
448 | current_player->wants_hint = false; // don't ask twice |
438 | Debug_Log (L"===Hint requested, asking engine for it===\n"); |
449 | Debug_Log (L"===Hint requested, asking engine for it===\n"); |
439 | Player_SendBuffer_Add (player, 1000, options.engine.program_options. |
450 | Player_SendBuffer_Add (player, 1000, options.engine.program_options.command_go); // tell the computer to analyze this position |
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 |
451 | 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 |
- | 452 | is_hint_pending = true; // remember a hint is pending |
|
- | 453 | ||
- | 454 | // FIXME: move to scene.cpp |
|
- | 455 | 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), |
|
- | 456 | 999999.0f, true, LOCALIZE (L"Thinking")); // display the "thinking" phrase in the middle of the screen |
|
- | 457 | the_scene.gui.want_spinwheel = true; // start spinning wheel |
|
- | 458 | do_update = true; // remember to update the 3D scene |
|
441 | } |
459 | } |
442 | 460 | ||
443 | // does our opponent want to cancel a move ? |
461 | // does our opponent want to cancel a move ? |
444 | if (current_player->wants_cancel) |
462 | if (current_player->wants_cancel) |
445 | { |
463 | { |