static bool is_solution(int move, const board_t * board, const char bm[], const char am[]) { char move_string[256]; bool correct; ASSERT(move!=MoveNone); ASSERT(bm!=NULL); ASSERT(am!=NULL); if (!move_is_legal(move,board)) { board_disp(board); move_disp(move,board); printf("\n\n"); } ASSERT(move_is_legal(move,board)); if (!move_to_san(move,board,move_string,256)) ASSERT(false); correct = false; if (!my_string_empty(bm)) { correct = string_contain(bm,move_string); } else if (!my_string_empty(am)) { correct = !string_contain(am,move_string); } else { ASSERT(false); } return correct; }
static void send_pv() { char pv_string[StringSize]; board_t board[1]; int move; char move_string[StringSize]; ASSERT(State->state!=WAIT); if (Uci->best_depth == 0) return; // xboard search information if (XB->post) { if (State->state == THINK || State->state == ANALYSE) { line_to_san(Uci->best_pv,Uci->board,pv_string,StringSize); xboard_send(XBoard,"%d %+d %.0f %lld %s",Uci->best_depth,Uci->best_score,Uci->time*100.0,Uci->node_nb,pv_string); } else if (State->state == PONDER && option_get_bool("ShowPonder")) { game_get_board(Game,board); move = State->exp_move; if (move != MoveNone && move_is_legal(move,board)) { move_to_san(move,board,move_string,256); line_to_san(Uci->best_pv,Uci->board,pv_string,StringSize); xboard_send(XBoard,"%d %+d %.0f %lld (%s) %s",Uci->best_depth,Uci->best_score,Uci->time*100.0,Uci->node_nb,move_string,pv_string); } } } // kibitz if ((Uci->searching && option_get_bool("KibitzPV") && Uci->time >= option_get_double("KibitzDelay")) || (!Uci->searching && option_get_bool("KibitzMove"))) { if (State->state == THINK || State->state == ANALYSE) { line_to_san(Uci->best_pv,Uci->board,pv_string,StringSize); xboard_send(XBoard,"%s depth=%d time=%.2f node=%lld speed=%.0f score=%+.2f pv=\"%s\"",option_get_string("KibitzCommand"),Uci->best_depth,Uci->time,Uci->node_nb,Uci->speed,double(Uci->best_score)/100.0,pv_string); } else if (State->state == PONDER) { game_get_board(Game,board); move = State->exp_move; if (move != MoveNone && move_is_legal(move,board)) { move_to_san(move,board,move_string,256); line_to_san(Uci->best_pv,Uci->board,pv_string,StringSize); xboard_send(XBoard,"%s depth=%d time=%.2f node=%lld speed=%.0f score=%+.2f pv=\"(%s) %s\"",option_get_string("KibitzCommand"),Uci->best_depth,Uci->time,Uci->node_nb,Uci->speed,double(Uci->best_score)/100.0,move_string,pv_string); } } } }
static void send_pv() { char pv_string[StringSize]; board_t board[1]; int move; char move_string[256]; char tb_string[256]; ASSERT(State->state!=WAIT); if (Uci->best_depth == 0) return; // move_string[0]='\0'; // xboard search information if (XB->post && Uci->time >= option_get_double("PostDelay")) { if (State->state == THINK || State->state == ANALYSE) { line_to_san(Uci->best_pv,Uci->board,pv_string,sizeof(pv_string)); tb_to_string(tb_string,sizeof(tb_string)); if(Uci->depth==-1) //hack to clear the engine output window xboard_send(XBoard,"%d %+d %.0f " S64_FORMAT " ",0,Uci->best_score,Uci->time*100.0,Uci->node_nb); xboard_send(XBoard,"%d %+d %.0f " S64_FORMAT " %s %s",Uci->best_depth,Uci->best_score,Uci->time*100.0,Uci->node_nb,pv_string,tb_string); } else if (State->state == PONDER && option_get_bool("ShowPonder")) { game_get_board(Game,board); move = State->exp_move; if (move != MoveNone && move_is_legal(move,board)) { move_to_san(move,board,move_string,sizeof(move_string)); line_to_san(Uci->best_pv,Uci->board,pv_string,sizeof(pv_string)); tb_to_string(tb_string,sizeof(tb_string)); xboard_send(XBoard,"%d %+d %.0f " S64_FORMAT " (%s) %s %s",Uci->best_depth,Uci->best_score,Uci->time*100.0,Uci->node_nb,move_string,pv_string,tb_string); } } } // kibitz if ((Uci->searching && option_get_bool("KibitzPV") && Uci->time >= option_get_double("KibitzDelay")) || (!Uci->searching && option_get_bool("KibitzMove"))) { if (State->state == THINK || State->state == ANALYSE) { line_to_san(Uci->best_pv,Uci->board,pv_string,sizeof(pv_string)); xboard_send(XBoard,"%s depth=%d time=%.2f node=" S64_FORMAT " speed=%.0f score=%+.2f pv=\"%s\"",option_get_string("KibitzCommand"),Uci->best_depth,Uci->time,Uci->node_nb,Uci->speed,double(Uci->best_score)/100.0,pv_string); } else if (State->state == PONDER) { game_get_board(Game,board); move = State->exp_move; if (move != MoveNone && move_is_legal(move,board)) { move_to_san(move,board,move_string,sizeof(move_string)); line_to_san(Uci->best_pv,Uci->board,pv_string,sizeof(pv_string)); xboard_send(XBoard,"%s depth=%d time=%.2f node=" S64_FORMAT " speed=%.0f score=%+.2f pv=\"(%s) %s\"",option_get_string("KibitzCommand"),Uci->best_depth,Uci->time,Uci->node_nb,Uci->speed,double(Uci->best_score)/100.0,move_string,pv_string); } } } }
static bool ponder_move_is_ok(int move) { int status; board_t board[1]; ASSERT(move==MoveNone||move_is_ok(move)); // legal ponder move? if (move == MoveNone) return false; game_get_board(Game,board); if (!move_is_legal(move,board)) return false; // UCI-legal resulting position? game_add_move(Game,move); game_get_board(Game,board); status = game_status(Game); game_rem_move(Game); if (status != PLAYING) return false; // game ended if (option_get_bool("Book") && is_in_book(board)) { return false; } return true; }
static void move_step(int move) { board_t board[1]; char move_string[256]; ASSERT(move_is_ok(move)); // log game_get_board(Game,board); if (move != MoveNone && move_is_legal(move,board)) { move_to_san(move,board,move_string,256); my_log("POLYGLOT MOVE %s\n",move_string); } else { move_to_can(move,board,move_string,256); my_log("POLYGLOT ILLEGAL MOVE \"%s\"\n",move_string); board_disp(board); my_fatal("move_step(): illegal move \"%s\"\n",move_string); } // play the move game_add_move(Game,move); board_update(); }
ChessMove chess_move_generator_next(ChessMoveGenerator* generator) { ChessMove move = 0; while ((move = gen_next(generator)) && !move_is_legal(generator->position, move)) ; return move; }
ExtMove* generate<LEGAL>(const Position& pos, ExtMove* mlist){ ExtMove *end, *cur = mlist; Bitboard pinned = pos.pinned_pieces(); Square ksq = pos.king_square(pos.side_to_move()); end = pos.checkers() ? generate<EVASIONS>(pos, mlist) : generate<NON_EVASIONS>(pos, mlist); while (cur != end) { if(move_is_legal(pos, cur->move)){ //if (move_is_check(pos, cur->move)) //{ // std::cout<<"move is check "<< move_to_chinese(pos,cur->move).c_str()<<std::endl; //} cur++; } else{ cur->move = (--end)->move; } } //std::cout<< std::endl; //cur = mlist; //for(; cur != end; ++cur) //{ // std::cout<< move_to_chinese(pos,cur->move).c_str()<<std::endl; //} //std::cout<<pos.pretty(); return end; }
static void move_step(int move) { board_t board[1]; char move_string[256]; ASSERT(move_is_ok(move)); // log game_get_board(Game,board); if (XB->ics || (move != MoveNone && move_is_legal(move,board))) { move_to_san(move,board,move_string,sizeof(move_string)); my_log("POLYGLOT MOVE %s\n",move_string); } else { move_to_can(move,board,move_string,sizeof(move_string)); my_log("POLYGLOT ILLEGAL MOVE \"%s\"\n",move_string); board_disp(board); //since we have threads my_fatal is not enough,1 thread will wait for xboard to end the game //stuff illegal move in the comment as well,not everybody logs all the time. if(board->turn==White) xboard_send(XBoard,"0-1 {polyglot: %s illegal engine move white}\n",move_string); else xboard_send(XBoard,"1-0 {polyglot: %s illegal engine move black}\n",move_string); my_fatal("move_step(): illegal move \"%s\"\n",move_string); } // play the move game_add_move(Game,move); //board_update(); }
bool line_from_can (move_t line[], const board_t * board, const char string[], int size) { int pos; char new_string[StringSize], *p; int move; board_t new_board[1]; ASSERT(line!=NULL); ASSERT(board_is_ok(board)); ASSERT(string!=NULL); ASSERT(size>=LineSize); // init pos = 0; board_copy(new_board,board); // loop strcpy(new_string,string); // HACK for (p = strtok(new_string," "); p != NULL; p = strtok(NULL," ")) { move = move_from_can(p,new_board); ASSERT(move!=MoveNone); ASSERT(move_is_legal(move,new_board)); if (move == MoveNone || !move_is_legal(move,new_board)) break; // HACK: ignore illegal moves if (pos >= size) return false; line[pos++] = move; move_do(new_board,move); } if (pos >= size) return false; line[pos] = MoveNone; return true; }
void chess_generate_moves(const ChessPosition* position, ChessArray* moves) { ChessMoveGenerator generator; ChessMove move; chess_move_generator_init(&generator, position); while ((move = chess_move_generator_next(&generator))) { if (!move_is_legal(position, move)) continue; chess_array_push(moves, &move); } }
void add_root_move(position_t *pos, search_stack_t *sstack, move_t move, root_move_list_t *list) { undo_info_t u[1]; if(move_is_legal(pos, move)) { list->moves[list->num].move = move; list->moves[list->num].nodes = 0; list->moves[list->num].cumulative_nodes = 0; sstack[0].move = move; make_move(pos, move, u); // list->moves[list->num].depth_1_score = search(pos, sstack, 1, 0, 0); list->moves[list->num].score = WORSTSCORE; unmake_move(pos, move, u); list->num++; } }
bool line_to_san(const move_t line[], const board_t * board, char string[], int size) { board_t new_board[1]; int pos; int move; char move_string[256]; ASSERT(line_is_ok(line)); ASSERT(board_is_ok(board)); ASSERT(string!=NULL); ASSERT(size>=StringSize); // init string[0]='\0'; if (size < StringSize) return false; // return false; board_copy(new_board,board); pos = 0; // loop while ((move = *line++) != MoveNone) { if (pos != 0) { if (pos >= size) return false; string[pos++] = ' '; } if (!move_is_legal(move,new_board) || !move_to_san(move,new_board,&string[pos],size-pos)) { if (Strict || UseDebug) { move_to_can(move,new_board,move_string,sizeof(move_string)); my_log("POLYGLOT ILLEGAL MOVE IN LINE %s\n",move_string); board_disp(new_board); if (Strict) my_fatal("line_to_san(): illegal move\n"); } break; } pos += (int)strlen(&string[pos]); move_do(new_board,move); } if (pos >= size) return false; string[pos] = '\0'; return true; }
void game_add_move(game_t * game, int move) { ASSERT(game!=NULL); ASSERT(move_is_ok(move)); ASSERT(move_is_legal(move,game->board)); if (game->pos >= GameSize) my_fatal("game_add_move(): game overflow\n"); game->move[game->pos] = move; game->key[game->pos] = game->board->key; move_do(game->board,move); game->pos++; game->size = game->pos; // truncate game, HACK: before calling game_is_ok() in game_update() game_update(game); }
ExtMove* generate<EVASIONS>(const Position& pos, ExtMove* mlist){ Color us = pos.side_to_move(); Bitboard target = ~pos.pieces(us); ExtMove *end, *cur = mlist; end = us == WHITE ? generate_all<WHITE, EVASIONS>(pos, mlist, target) : generate_all<BLACK, EVASIONS>(pos, mlist, target); while (cur != end) { if(move_is_legal(pos, cur->move)){ cur++; } else{ cur->move = (--end)->move; } } return end; }
bool game_is_ok(const game_t * game) { board_t board[1]; int pos, move; if (game == NULL) return false; if (game->size < 0 || game->size > GameSize) return false; if (game->pos < 0 || game->pos > game->size) return false; // optional heavy DEBUG mode if (!UseSlowDebug) return true; if (!board_is_ok(game->start_board)) return false; board_copy(board,game->start_board); for (pos = 0; pos <= game->size; pos++) { if (pos == game->pos) { if (!board_equal(game->board,board)) return false; } if (pos >= game->size) break; if (game->key[pos] != board->key) return false; move = game->move[pos]; if (!move_is_legal(move,board)) ; move_do(board,move); } if (game->status != game_comp_status(game)) return false; return true; }
bool move_is_legal(const Position& pos, const Move m, Bitboard pinned) { assert(pos.is_ok()); assert(move_is_ok(m)); assert(pinned == pos.pinned_pieces(pos.side_to_move())); Color us = pos.side_to_move(); Color them = opposite_color(us); Square from = move_from(m); Square to = move_to(m); Piece pc = pos.piece_on(from); // Use a slower but simpler function for uncommon cases if (move_is_ep(m) || move_is_castle(m)) return move_is_legal(pos, m); // If the from square is not occupied by a piece belonging to the side to // move, the move is obviously not legal. if (color_of_piece(pc) != us) return false; // The destination square cannot be occupied by a friendly piece if (pos.color_of_piece_on(to) == us) return false; // Handle the special case of a pawn move if (type_of_piece(pc) == PAWN) { // Move direction must be compatible with pawn color int direction = to - from; if ((us == WHITE) != (direction > 0)) return false; // A pawn move is a promotion iff the destination square is // on the 8/1th rank. if (( (square_rank(to) == RANK_8 && us == WHITE) ||(square_rank(to) == RANK_1 && us != WHITE)) != bool(move_is_promotion(m))) return false; // Proceed according to the square delta between the origin and // destination squares. switch (direction) { case DELTA_NW: case DELTA_NE: case DELTA_SW: case DELTA_SE: // Capture. The destination square must be occupied by an enemy // piece (en passant captures was handled earlier). if (pos.color_of_piece_on(to) != them) return false; break; case DELTA_N: case DELTA_S: // Pawn push. The destination square must be empty. if (!pos.square_is_empty(to)) return false; break; case DELTA_NN: // Double white pawn push. The destination square must be on the fourth // rank, and both the destination square and the square between the // source and destination squares must be empty. if ( square_rank(to) != RANK_4 || !pos.square_is_empty(to) || !pos.square_is_empty(from + DELTA_N)) return false; break; case DELTA_SS: // Double black pawn push. The destination square must be on the fifth // rank, and both the destination square and the square between the // source and destination squares must be empty. if ( square_rank(to) != RANK_5 || !pos.square_is_empty(to) || !pos.square_is_empty(from + DELTA_S)) return false; break; default: return false; } // The move is pseudo-legal, check if it is also legal return pos.is_check() ? pos.pl_move_is_evasion(m, pinned) : pos.pl_move_is_legal(m, pinned); } // Luckly we can handle all the other pieces in one go return bit_is_set(pos.attacks_from(pc, from), to) && (pos.is_check() ? pos.pl_move_is_evasion(m, pinned) : pos.pl_move_is_legal(m, pinned)) && !move_is_promotion(m); }
void search(const board_t * board, int depth_max, double time_max) { char string[256]; ASSERT(board_is_ok(board)); ASSERT(depth_max>=1&&depth_max<DepthMax); ASSERT(time_max>=0.0); // engine Depth = 0; BestMove = MoveNone; BestValue = 0; line_clear(BestPV); NodeNb = 0; LeafNb = 0; Time = 0.0; Move = MoveNone; MovePos = 0; MoveNb = 0; // init uci_send_ucinewgame(Uci); uci_send_isready_sync(Uci); // position if (!board_to_fen(board,string,256)) ASSERT(false); engine_send(Engine,"position fen %s",string); // search engine_send_queue(Engine,"go"); engine_send_queue(Engine," movetime %.0f",time_max*1000.0); engine_send_queue(Engine," depth %d",depth_max); engine_send(Engine,""); // newline // wait for feed-back while (true) { engine_get(Engine,string,256); if (false) { } else if (match(string,"bestmove * ponder *")) { BestMove = move_from_can(Star[0],board); ASSERT(BestMove!=MoveNone&&move_is_legal(BestMove,board)); break; } else if (match(string,"bestmove *")) { BestMove = move_from_can(Star[0],board); ASSERT(BestMove!=MoveNone&&move_is_legal(BestMove,board)); break; } } printf("\n"); }
static int parse_bestmove(uci_t * uci, const char string[]) { parse_t parse[1]; char command[StringSize]; char option[StringSize]; char argument[StringSize]; board_t board[1]; ASSERT(uci_is_ok(uci)); ASSERT(string!=NULL); // init strcpy(command,"bestmove"); parse_open(parse,string); parse_add_keyword(parse,"ponder"); // bestmove if (!parse_get_string(parse,argument,StringSize)) { my_fatal("parse_bestmove(): missing argument\n"); } uci->best_move = move_from_can(argument,uci->board); if (uci->best_move == MoveNone) my_fatal("parse_bestmove(): not a move \"%s\"\n",argument); ASSERT(uci->best_move!=MoveNone); ASSERT(move_is_legal(uci->best_move,uci->board)); // loop while (parse_get_word(parse,option,StringSize)) { parse_get_string(parse,argument,StringSize); if (UseDebug) my_log("POLYGLOT COMMAND \"%s\" OPTION \"%s\" ARGUMENT \"%s\"\n",command,option,argument); if (false) { } else if (my_string_equal(option,"ponder")) { ASSERT(!my_string_empty(argument)); board_copy(board,uci->board); move_do(board,uci->best_move); uci->ponder_move = move_from_can(argument,board); // if (uci->ponder_move == MoveNone) my_fatal("parse_bestmove(): not a move \"%s\"\n",argument); ASSERT(uci->ponder_move!=MoveNone); ASSERT(move_is_legal(uci->ponder_move,board)); } else { my_log("POLYGLOT unknown option \"%s\" for command \"%s\"\n",option,command); } } parse_close(parse); return EVENT_MOVE; }
static void search_update() { int move; int move_nb; board_t board[1]; ASSERT(!Uci->searching); // launch a new search if needed if (State->state == THINK || State->state == PONDER || State->state == ANALYSE) { // opening book if (State->state == THINK && option_get_bool("Book")) { game_get_board(Game,Uci->board); move = book_move(Uci->board,option_get_bool("BookRandom")); if (move != MoveNone && move_is_legal(move,Uci->board)) { my_log("POLYGLOT *BOOK MOVE*\n"); search_clear(); // clears Uci->ponder_move Uci->best_move = move; board_copy(board,Uci->board); move_do(board,move); Uci->ponder_move = book_move(board,false); // expected move = best book move Uci->best_pv[0] = Uci->best_move; Uci->best_pv[1] = Uci->ponder_move; // can be MoveNone Uci->best_pv[2] = MoveNone; comp_move(Uci->best_move); return; } } // engine search my_log("POLYGLOT START SEARCH\n"); // options uci_send_option(Uci,"UCI_Chess960","%s",option_get_bool("Chess960")?"true":"false"); if (option_get_int("UCIVersion") >= 2) { uci_send_option(Uci,"UCI_Opponent","none none %s %s",(XB->computer)?"computer":"human",XB->name); uci_send_option(Uci,"UCI_AnalyseMode","%s",(XB->analyse)?"true":"false"); } uci_send_option(Uci,"Ponder","%s",ponder()?"true":"false"); // position move = (State->state == PONDER) ? State->exp_move : MoveNone; send_board(move); // updates Uci->board global variable // search if (State->state == THINK || State->state == PONDER) { engine_send_queue(Engine,"go"); if (XB->time_limit) { // fixed time per move engine_send_queue(Engine," movetime %.0f",XB->time_max*1000.0); } else { // time controls if (colour_is_white(Uci->board->turn)) { engine_send_queue(Engine," wtime %.0f btime %.0f",XB->my_time*1000.0,XB->opp_time*1000.0); } else { engine_send_queue(Engine," wtime %.0f btime %.0f",XB->opp_time*1000.0,XB->my_time*1000.0); } if (XB->inc != 0.0) engine_send_queue(Engine," winc %.0f binc %.0f",XB->inc*1000.0,XB->inc*1000.0); if (XB->mps != 0) { move_nb = XB->mps - (Uci->board->move_nb % XB->mps); ASSERT(move_nb>=1&&move_nb<=XB->mps); engine_send_queue(Engine," movestogo %d",move_nb); } } if (XB->depth_limit) engine_send_queue(Engine," depth %d",XB->depth_max); if (State->state == PONDER) engine_send_queue(Engine," ponder"); engine_send(Engine,""); // newline } else if (State->state == ANALYSE) { engine_send(Engine,"go infinite"); } else { ASSERT(false); } // init search info ASSERT(!Uci->searching); search_clear(); Uci->searching = true; Uci->pending_nb++; } }
bool move_to_san(int move, const board_t * board, char string[], int size) { int from, to, piece; char tmp_string[256]; ASSERT(move_is_ok(move)); ASSERT(board_is_ok(board)); ASSERT(string!=NULL); ASSERT(size>=8); ASSERT(move_is_legal(move,board)); if (size < 8) return false; // init from = move_from(move); to = move_to(move); string[0] = '\0'; // castle if (move_is_castle(move,board)) { if (to > from) { strcat(string,"O-O"); } else { strcat(string,"O-O-O"); } goto check; } // from piece = board->square[from]; if (piece_is_pawn(piece)) { // pawn if (move_is_capture(move,board)) { sprintf(tmp_string,"%c",file_to_char(square_file(from))); strcat(string,tmp_string); } } else { // piece sprintf(tmp_string,"%c",toupper(piece_to_char(piece))); strcat(string,tmp_string); // ambiguity switch (ambiguity(move,board)) { case AMBIGUITY_NONE: break; case AMBIGUITY_FILE: sprintf(tmp_string,"%c",file_to_char(square_file(from))); strcat(string,tmp_string); break; case AMBIGUITY_RANK: sprintf(tmp_string,"%c",rank_to_char(square_rank(from))); strcat(string,tmp_string); break; case AMBIGUITY_SQUARE: if (!square_to_string(from,tmp_string,256)) return false; strcat(string,tmp_string); break; default: ASSERT(false); break; } } // capture if (move_is_capture(move,board)) strcat(string,"x"); // to if (!square_to_string(to,tmp_string,256)) return false; strcat(string,tmp_string); // promote if (move_is_promote(move)) { sprintf(tmp_string,"=%c",toupper(piece_to_char(move_promote(move,board)))); strcat(string,tmp_string); } // check check: if (move_is_mate(move,board)) { strcat(string,"#"); } else if (move_is_check(move,board)) { strcat(string,"+"); } return true; }
static void xboard_step() { char string[StringSize]; int move; char move_string[256]; board_t board[1]; xboard_get(XBoard,string,StringSize); if (false) { } else if (match(string,"accepted *")) { // ignore } else if (match(string,"analyze")) { State->computer[White] = false; State->computer[Black] = false; XB->analyse = true; XB->new_hack = false; ASSERT(!XB->result); XB->result = false; mess(); } else if (match(string,"bk")) { if (option_get_bool("Book")) { game_get_board(Game,board); book_disp(board); } } else if (match(string,"black")) { if (colour_is_black(game_turn(Game))) { State->computer[White] = true; State->computer[Black] = false; XB->new_hack = true; XB->result = false; mess(); } } else if (match(string,"computer")) { XB->computer = true; } else if (match(string,"draw")) { // ignore } else if (match(string,"easy")) { XB->ponder = false; mess(); } else if (match(string,"edit")) { // refuse xboard_send(XBoard,"Error (unknown command): %s",string); } else if (match(string,"exit")) { State->computer[White] = false; State->computer[Black] = false; XB->analyse = false; mess(); } else if (match(string,"force")) { State->computer[White] = false; State->computer[Black] = false; mess(); } else if (match(string,"go")) { State->computer[game_turn(Game)] = true; State->computer[colour_opp(game_turn(Game))] = false; XB->new_hack = false; ASSERT(!XB->result); XB->result = false; mess(); } else if (match(string,"hard")) { XB->ponder = true; mess(); } else if (match(string,"hint")) { if (option_get_bool("Book")) { game_get_board(Game,board); move = book_move(board,false); if (move != MoveNone && move_is_legal(move,board)) { move_to_san(move,board,move_string,256); xboard_send(XBoard,"Hint: %s",move_string); } } } else if (match(string,"ics *")) { XB->ics = true; } else if (match(string,"level * *:* *")) { XB->mps = atoi(Star[0]); XB->base = double(atoi(Star[1])) * 60.0 + double(atoi(Star[2])); XB->inc = double(atoi(Star[3])); } else if (match(string,"level * * *")) { XB->mps = atoi(Star[0]); XB->base = double(atoi(Star[1])) * 60.0; XB->inc = double(atoi(Star[2])); } else if (match(string,"name *")) { my_string_set(&XB->name,Star[0]); } else if (match(string,"new")) { my_log("POLYGLOT NEW GAME\n"); option_set("Chess960","false"); game_clear(Game); if (XB->analyse) { State->computer[White] = false; State->computer[Black] = false; } else { State->computer[White] = false; State->computer[Black] = true; } XB->new_hack = true; XB->result = false; XB->depth_limit = false; XB->computer = false; my_string_set(&XB->name,"<empty>"); board_update(); mess(); uci_send_ucinewgame(Uci); } else if (match(string,"nopost")) { XB->post = false; } else if (match(string,"otim *")) { XB->opp_time = double(atoi(Star[0])) / 100.0; if (XB->opp_time < 0.0) XB->opp_time = 0.0; } else if (match(string,"pause")) { // refuse xboard_send(XBoard,"Error (unknown command): %s",string); } else if (match(string,"ping *")) { // HACK; TODO: answer only after an engine move if (DelayPong) { if (XB->ping >= 0) xboard_send(XBoard,"pong %d",XB->ping); // HACK: get rid of old ping XB->ping = atoi(Star[0]); uci_send_isready(Uci); } else { ASSERT(XB->ping==-1); xboard_send(XBoard,"pong %s",Star[0]); } } else if (match(string,"playother")) { State->computer[game_turn(Game)] = false; State->computer[colour_opp(game_turn(Game))] = true; XB->new_hack = false; ASSERT(!XB->result); XB->result = false; mess(); } else if (match(string,"post")) { XB->post = true; } else if (match(string,"protover *")) { XB->proto_ver = atoi(Star[0]); ASSERT(XB->proto_ver>=2); xboard_send(XBoard,"feature done=0"); xboard_send(XBoard,"feature analyze=1"); xboard_send(XBoard,"feature colors=0"); xboard_send(XBoard,"feature draw=1"); xboard_send(XBoard,"feature ics=1"); xboard_send(XBoard,"feature myname=\"%s\"",option_get_string("EngineName")); xboard_send(XBoard,"feature name=1"); xboard_send(XBoard,"feature pause=0"); xboard_send(XBoard,"feature ping=1"); xboard_send(XBoard,"feature playother=1"); xboard_send(XBoard,"feature reuse=1"); xboard_send(XBoard,"feature san=0"); xboard_send(XBoard,"feature setboard=1"); xboard_send(XBoard,"feature sigint=0"); xboard_send(XBoard,"feature sigterm=0"); xboard_send(XBoard,"feature time=1"); xboard_send(XBoard,"feature usermove=1"); if (uci_option_exist(Uci,"UCI_Chess960")) { xboard_send(XBoard,"feature variants=\"normal,fischerandom\""); } else { xboard_send(XBoard,"feature variants=\"normal\""); } if (Uci->ready) xboard_send(XBoard,"feature done=1"); // otherwise "feature done=1" will be sent when the engine is ready } else if (match(string,"quit")) { my_log("POLYGLOT *** \"quit\" from XBoard ***\n"); quit(); } else if (match(string,"random")) { // ignore } else if (match(string,"rating * *")) { // ignore } else if (match(string,"remove")) { if (game_pos(Game) >= 2) { game_goto(Game,game_pos(Game)-2); ASSERT(!XB->new_hack); XB->new_hack = false; // HACK? XB->result = false; board_update(); mess(); } } else if (match(string,"rejected *")) { // ignore } else if (match(string,"reset")) { // protover 3? // refuse xboard_send(XBoard,"Error (unknown command): %s",string); } else if (false || match(string,"result * {*}") || match(string,"result * {* }") || match(string,"result * { *}") || match(string,"result * { * }")) { my_log("POLYGLOT GAME END\n"); XB->result = true; mess(); // book learning if (option_get_bool("Book") && option_get_bool("BookLearn")) { if (false) { } else if (my_string_equal(Star[0],"1-0")) { learn(+1); } else if (my_string_equal(Star[0],"0-1")) { learn(-1); } else if (my_string_equal(Star[0],"1/2-1/2")) { learn(0); } } } else if (match(string,"resume")) { // refuse xboard_send(XBoard,"Error (unknown command): %s",string); } else if (match(string,"sd *")) { XB->depth_limit = true; XB->depth_max = atoi(Star[0]); } else if (match(string,"setboard *")) { my_log("POLYGLOT FEN %s\n",Star[0]); if (!game_init(Game,Star[0])) my_fatal("xboard_step(): bad FEN \"%s\"\n",Star[0]); State->computer[White] = false; State->computer[Black] = false; XB->new_hack = true; // HACK? XB->result = false; board_update(); mess(); } else if (match(string,"st *")) { XB->time_limit = true; XB->time_max = double(atoi(Star[0])); } else if (match(string,"time *")) { XB->my_time = double(atoi(Star[0])) / 100.0; if (XB->my_time < 0.0) XB->my_time = 0.0; } else if (match(string,"undo")) { if (game_pos(Game) >= 1) { game_goto(Game,game_pos(Game)-1); ASSERT(!XB->new_hack); XB->new_hack = false; // HACK? XB->result = false; board_update(); mess(); } } else if (match(string,"usermove *")) { game_get_board(Game,board); move = move_from_san(Star[0],board); if (move != MoveNone && move_is_legal(move,board)) { XB->new_hack = false; ASSERT(!XB->result); XB->result = false; move_step(move); no_mess(move); } else { xboard_send(XBoard,"Illegal move: %s",Star[0]); } } else if (match(string,"variant *")) { if (my_string_equal(Star[0],"fischerandom")) { option_set("Chess960","true"); } else { option_set("Chess960","false"); } } else if (match(string,"white")) { if (colour_is_white(game_turn(Game))) { State->computer[White] = false; State->computer[Black] = true; XB->new_hack = true; XB->result = false; mess(); } } else if (match(string,"xboard")) { // ignore } else if (match(string,".")) { // analyse info if (State->state == ANALYSE) { ASSERT(Uci->searching); ASSERT(Uci->pending_nb>=1); if (Uci->root_move != MoveNone && move_is_legal(Uci->root_move,Uci->board)) { move_to_san(Uci->root_move,Uci->board,move_string,256); xboard_send(XBoard,"stat01: %.0f %lld %d %d %d %s",Uci->time*100.0,Uci->node_nb,Uci->depth,Uci->root_move_nb-(Uci->root_move_pos+1),Uci->root_move_nb,move_string); } else { xboard_send(XBoard,"stat01: %.0f %lld %d %d %d",Uci->time*100.0,Uci->node_nb,Uci->depth,0,0); // HACK } } } else if (match(string,"?")) { // move now if (State->state == THINK) { ASSERT(Uci->searching); ASSERT(Uci->pending_nb>=1); // HACK: just send "stop" to the engine if (Uci->searching) { my_log("POLYGLOT STOP SEARCH\n"); engine_send(Engine,"stop"); } } } else { // unknown command, maybe a move? game_get_board(Game,board); move = move_from_san(string,board); if (move != MoveNone && move_is_legal(move,board)) { XB->new_hack = false; ASSERT(!XB->result); XB->result = false; move_step(move); no_mess(move); } else if (move != MoveNone) { xboard_send(XBoard,"Illegal move: %s",string); } else { xboard_send(XBoard,"Error (unknown command): %s",string); } } }
void E_scene_main_game::click_on_chessboard(int mouseX, int mouseY) { // if it's not the player's turn, don't manage click on chessboard if ((game_mode == PLAYER_VS_AI) && (current_color != player_color)) return; // promotion is a special state in which the player must answer // to the question of what is the piece he wants for the promotion if (promotion) return; // if the game is over, there is no reason to play anymore :) if (game_is_over) return; int sqX, sqY; if (pGlobalInfos->OnLeftMouseButtonDown()) { if (chessboard->clickOnChessBoard(mouseX,mouseY,&sqX,&sqY)); { // if a piece was already selected, this means the player want to move this piece if (SquareXSelected>-1 && SquareZSelected>-1) { FutureXSquare=sqX; FutureZSquare=sqY; // check if the player move is legal (ie: move is in possible_moves array) if (move_is_legal()) { // check if the move will be a promotion check_for_promotion(); // if so, wait for the player to answer to which piece // he wants for the promotion if (promotion) return; player_do_a_move(0); if (game_is_over) return; // ------- MODE PLAYER_VS_PLAYER ------- if (game_mode == PLAYER_VS_PLAYER) chessboard->changeSideToPlay(current_color); // ------- MODE PLAYER_VS_AI ------- if (game_mode == PLAYER_VS_AI) { thread_data[0]=&AI_comp_is_done; thread_data[1]=move_to_do; FAILE_AI_thread=SDL_CreateThread(AIComputeMove,thread_data); } return; } } // if no piece were previously selected SquareXSelected=-1; SquareZSelected=-1; int pos=24 + (sqY+1)*12 -(sqX+3); if (pos>=0 && pos<145) { bool color_selected=board_to_display[pos]%2; if (current_color!=WHITE) color_selected=!color_selected; if (color_selected && board_to_display[pos]!=npiece && board_to_display[pos]!=frame) { SquareXSelected=sqX; SquareZSelected=sqY; UpdatePossibleMoves(SquareXSelected,SquareZSelected); } } } } if (pGlobalInfos->display_possible_moves() && SquareXSelected>-1 && SquareZSelected>-1) chessboard->displayPossibleMoves(SquareXSelected,SquareZSelected,possible_moves); }
static void search_update() { int move; int move_nb; board_t board[1]; ASSERT(!Uci->searching); // launch a new search if needed if (State->state == THINK || State->state == PONDER || State->state == ANALYSE) { // [VdB] moved up as we need the move number game_get_board(Game,Uci->board); // opening book if (State->state == THINK && option_get_bool(Option,"Book") && Uci->board->move_nb<option_get_int(Option,"BookDepth") ) { move = book_move(Uci->board,option_get_bool(Option,"BookRandom")); if (move != MoveNone && move_is_legal(move,Uci->board)) { my_log("POLYGLOT *BOOK MOVE*\n"); search_clear(); // clears Uci->ponder_move Uci->best_move = move; board_copy(board,Uci->board); move_do(board,move); Uci->ponder_move = book_move(board,FALSE); // expected move = best book move Uci->best_pv[0] = Uci->best_move; Uci->best_pv[1] = Uci->ponder_move; // can be MoveNone Uci->best_pv[2] = MoveNone; comp_move(Uci->best_move); return; } } // engine search my_log("POLYGLOT START SEARCH\n"); // options uci_send_option(Uci,"UCI_3Check","%s", option_get_bool(Option,"3Check")?"true":"false"); uci_send_option(Uci,"UCI_Chess960","%s", option_get_bool(Option,"Chess960")?"true":"false"); uci_send_option(Uci,"UCI_Atomic","%s", option_get_bool(Option,"Atomic")?"true":"false"); uci_send_option(Uci,"UCI_Horde","%s", option_get_bool(Option,"Horde")?"true":"false"); if (option_get_int(Option,"UCIVersion") >= 2) { uci_send_option(Uci,"UCI_Opponent","none none %s %s",(XB->computer)?"computer":"human",XB->name); uci_send_option(Uci,"UCI_AnalyseMode","%s",(XB->analyse)?"true":"false"); } uci_send_option(Uci,"Ponder","%s",ponder()?"true":"false"); // position move = (State->state == PONDER) ? State->exp_move : MoveNone; send_board(move); // updates Uci->board global variable // search if (State->state == THINK || State->state == PONDER) { engine_send_queue(Engine,"go"); if (XB->time_limit) { // fixed time per move if(XB->node_rate > 0){ engine_send_queue(Engine, " nodes %.0f", XB->time_max*((double)XB->node_rate)); }else{ double computed_time; double st_fudge; st_fudge=(double) option_get_int(Option,"STFudge"); my_log("POLYGLOT Giving engine %.0fmsec extra time.\n",st_fudge); computed_time=XB->time_max*1000.0-st_fudge; if(computed_time< 1.0){ computed_time=1.0; } engine_send_queue(Engine, " movetime %.0f", computed_time); } } else { // time controls if(XB->node_rate > 0) { double time; move_nb = 40; if (XB->mps != 0){ move_nb = XB->mps - (Uci->board->move_nb % XB->mps); } time = XB->my_time / move_nb; if(XB->inc != 0){ time += XB->inc; } if(time > XB->my_time){ time = XB->my_time; } engine_send_queue(Engine, " nodes %.0f", time*XB->node_rate); } else { if (colour_is_white(Uci->board->turn)) { engine_send_queue(Engine, " wtime %.0f btime %.0f", XB->my_time*1000.0,XB->opp_time*1000.0); } else { engine_send_queue(Engine, " wtime %.0f btime %.0f", XB->opp_time*1000.0,XB->my_time*1000.0); } if (XB->inc != 0.0){ engine_send_queue(Engine, " winc %.0f binc %.0f", XB->inc*1000.0,XB->inc*1000.0); } if (XB->mps != 0) { move_nb = XB->mps - (Uci->board->move_nb % XB->mps); ASSERT(move_nb>=1&&move_nb<=XB->mps); engine_send_queue(Engine," movestogo %d",move_nb); } } } if (XB->depth_limit) engine_send_queue(Engine," depth %d",XB->depth_max); if (State->state == PONDER) engine_send_queue(Engine," ponder"); engine_send(Engine,""); // newline } else if (State->state == ANALYSE) { engine_send(Engine,"go infinite"); } else { ASSERT(FALSE); } // init search info ASSERT(!Uci->searching); search_clear(); Uci->searching = TRUE; Uci->pending_nb++; } }
void xboard2uci_gui_step(char string[]) { int move; char move_string[256]; board_t board[1]; if (FALSE) { } else if (match(string,"accepted *")) { // ignore } else if (match(string,"analyze")) { State->computer[White] = FALSE; State->computer[Black] = FALSE; XB->analyse = TRUE; XB->new_hack = FALSE; ASSERT(!XB->result); XB->result = FALSE; mess(); } else if (match(string,"bk")) { if (option_get_bool(Option,"Book")) { game_get_board(Game,board); book_disp(board); } } else if (match(string,"black")) { if (colour_is_black(game_turn(Game))) { State->computer[White] = TRUE; State->computer[Black] = FALSE; XB->new_hack = TRUE; XB->result = FALSE; mess(); } } else if (match(string,"computer")) { XB->computer = TRUE; } else if (match(string,"draw")) { if(option_find(Uci->option,"UCI_DrawOffers")){ my_log("POLYGLOT draw from XB received"); uci_send_option(Uci,"DrawOffer","%s","draw");} } else if (match(string,"easy")) { XB->ponder = FALSE; mess(); } else if (match(string,"edit")) { // refuse gui_send(GUI,"Error (unknown command): %s",string); } else if (match(string,"exit")) { State->computer[White] = FALSE; State->computer[Black] = FALSE; XB->analyse = FALSE; mess(); } else if (match(string,"force")) { State->computer[White] = FALSE; State->computer[Black] = FALSE; mess(); } else if (match(string,"go")) { State->computer[game_turn(Game)] = TRUE; State->computer[colour_opp(game_turn(Game))] = FALSE; XB->new_hack = FALSE; ASSERT(!XB->result); XB->result = FALSE; mess(); } else if (match(string,"hard")) { XB->ponder = TRUE; mess(); } else if (match(string,"hint")) { move=MoveNone; game_get_board(Game,board); if (option_get_bool(Option,"Book")) { move = book_move(board,FALSE); } if(move==MoveNone && State->hint_move!=MoveNone){ move=State->hint_move; } if (move != MoveNone && move_is_legal(move,board)) { move_to_san(move,board,move_string,256); gui_send(GUI,"Hint: %s",move_string); } } else if (match(string,"ics *")) { XB->ics = TRUE; } else if (match(string,"level * *:* *")) { XB->mps = atoi(Star[0]); XB->base = ((double)atoi(Star[1])) * 60.0 + ((double)atoi(Star[2])); XB->inc = ((double)atoi(Star[3])); } else if (match(string,"level * * *")) { XB->mps = atoi(Star[0]); XB->base = ((double)atoi(Star[1])) * 60.0; XB->inc = ((double)atoi(Star[2])); } else if (match(string,"name *")) { my_string_set(&XB->name,Star[0]); } else if (match(string,"new")) { uci_send_isready_sync(Uci); my_log("POLYGLOT NEW GAME\n"); option_set(Option,"3Check","false"); option_set(Option,"Chess960","false"); option_set(Option,"Atomic","false"); option_set(Option,"Horde","false"); game_clear(Game); if (XB->analyse) { State->computer[White] = FALSE; State->computer[Black] = FALSE; } else { State->computer[White] = FALSE; State->computer[Black] = TRUE; } XB->new_hack = TRUE; XB->result = FALSE; XB->depth_limit = FALSE; XB->node_rate=-1; XB->computer = FALSE; my_string_set(&XB->name,"<empty>"); board_update(); mess(); uci_send_ucinewgame(Uci); } else if (match(string,"nopost")) { XB->post = FALSE; } else if (match(string,"otim *")) { XB->opp_time = ((double)atoi(Star[0])) / 100.0; if (XB->opp_time < 0.0) XB->opp_time = 0.0; } else if (match(string,"pause")) { // refuse gui_send(GUI,"Error (unknown command): %s",string); } else if (match(string,"ping *")) { // HACK; TODO: answer only after an engine move if (DelayPong) { if (XB->ping >= 0) gui_send(GUI,"pong %d",XB->ping); // HACK: get rid of old ping XB->ping = atoi(Star[0]); uci_send_isready_sync(Uci); } else { ASSERT(XB->ping==-1); gui_send(GUI,"pong %s",Star[0]); } } else if (match(string,"nps *")) { // fake WB play-by-nodes mode XB->node_rate = atoi(Star[0]); } else if (match(string,"playother")) { State->computer[game_turn(Game)] = FALSE; State->computer[colour_opp(game_turn(Game))] = TRUE; XB->new_hack = FALSE; ASSERT(!XB->result); XB->result = FALSE; mess(); } else if (match(string,"post")) { XB->post = TRUE; } else if (match(string,"protover *")) { XB->proto_ver = atoi(Star[0]); ASSERT(XB->proto_ver>=2); send_xboard_options(); } else if (match(string,"quit")) { my_log("POLYGLOT *** \"quit\" from GUI ***\n"); quit(); } else if (match(string,"random")) { // ignore } else if (match(string,"rating * *")) { // ignore } else if (match(string,"remove")) { if (game_pos(Game) >= 2) { game_goto(Game,game_pos(Game)-2); ASSERT(!XB->new_hack); XB->new_hack = FALSE; // HACK? XB->result = FALSE; board_update(); mess(); } } else if (match(string,"rejected *")) { // ignore } else if (match(string,"reset")) { // protover 3? // refuse gui_send(GUI,"Error (unknown command): %s",string); } else if (FALSE || match(string,"result * {*}") || match(string,"result * {* }") || match(string,"result * { *}") || match(string,"result * { * }")) { my_log("POLYGLOT GAME END\n"); XB->result = TRUE; mess(); // book learning if (FALSE && option_get_bool(Option,"Book") && option_get_bool(Option,"BookLearn")) { if (FALSE) { } else if (my_string_equal(Star[0],"1-0")) { learn(+1); } else if (my_string_equal(Star[0],"0-1")) { learn(-1); } else if (my_string_equal(Star[0],"1/2-1/2")) { learn(0); } } } else if (match(string,"resume")) { // refuse gui_send(GUI,"Error (unknown command): %s",string); } else if (match(string,"option *=*") || match(string,"option * =*") || match(string,"option *= *") || match(string,"option * = *") ){ char *name=Star[0]; char *value=Star[1]; if(match(name, "Polyglot *")){ char *pg_name=Star[0]; polyglot_set_option(pg_name,value); }else{ option_t *opt=option_find(Uci->option,name); if(opt){ if(my_string_case_equal(opt->type,"check")){ value=my_string_equal(value,"1")?"true":"false"; } start_protected_command(); uci_send_option(Uci, name, "%s", value); end_protected_command(); }else{ gui_send(GUI,"Error (unknown option): %s",name); } } } else if (match(string,"option *")){ char *name=Star[0]; if(match(name, "Polyglot *")){ char *pg_name=Star[0]; polyglot_set_option(pg_name,"<empty>"); }else{ start_protected_command(); // value is ignored if(!uci_send_option(Uci, name, "%s", "<empty>")){ gui_send(GUI,"Error (unknown option): %s",name); }; end_protected_command(); } } else if (XB->has_feature_smp && match(string,"cores *")){ int cores=atoi(Star[0]); if(cores>=1){ // updating the number of cores my_log("POLYGLOT setting the number of cores to %d\n",cores); start_protected_command(); uci_set_threads(Uci,cores); end_protected_command(); } else{ // refuse gui_send(GUI,"Error (unknown command): %s",string); } } else if (match(string,"egtpath * *")){ char *type=Star[0]; char *path=Star[1]; if(my_string_empty(path)){ // refuse gui_send(GUI,"Error (unknown command): %s",string); }else{ if(my_string_case_equal(type,"nalimov") && XB->has_feature_egt_nalimov){ // updating NalimovPath my_log("POLYGLOT setting the Nalimov path to %s\n",path); start_protected_command(); uci_send_option(Uci,"NalimovPath","%s",path); end_protected_command(); }else if(my_string_case_equal(type,"gaviota") && XB->has_feature_egt_gaviota){ // updating GaviotaPath my_log("POLYGLOT setting the Gaviota path to %s\n",path); start_protected_command(); uci_send_option(Uci,"GaviotaTbPath","%s",path); end_protected_command(); }else{ // refuse gui_send(GUI,"Error (unsupported table base format): %s",string); } } } else if (XB->has_feature_memory && match(string,"memory *")){ int memory = atoi(Star[0]); int egt_cache; int real_memory; if(memory>=1){ // updating the available memory option_t *opt; my_log("POLYGLOT setting the amount of memory to %dMb\n",memory); if(XB->has_feature_egt_nalimov && (opt=option_find(Uci->option,"NalimovCache"))){ egt_cache=atoi(opt->value); }else if(XB->has_feature_egt_gaviota && (opt=option_find(Uci->option,"GaviotaTbCache"))){ egt_cache=atoi(opt->value); }else{ egt_cache=0; } my_log("POLYGLOT EGTB Cache is %dMb\n",egt_cache); real_memory=memory-egt_cache; if(real_memory>0){ start_protected_command(); uci_send_option(Uci,"Hash", "%d", real_memory); end_protected_command(); } }else{ // refuse gui_send(GUI,"Error (unknown command): %s",string); } } else if (match(string,"sd *")) { XB->depth_limit = TRUE; XB->depth_max = atoi(Star[0]); } else if (match(string,"setboard *")) { my_log("POLYGLOT FEN %s\n",Star[0]); if (!game_init(Game,Star[0])) my_fatal("xboard_step(): bad FEN \"%s\"\n",Star[0]); State->computer[White] = FALSE; State->computer[Black] = FALSE; XB->new_hack = TRUE; // HACK? XB->result = FALSE; board_update(); mess(); } else if (match(string,"st *")) { XB->time_limit = TRUE; XB->time_max = ((double)atoi(Star[0])); } else if (match(string,"time *")) { XB->my_time = ((double)atoi(Star[0])) / 100.0; if (XB->my_time < 0.0) XB->my_time = 0.0; } else if (match(string,"undo")) { if (game_pos(Game) >= 1) { game_goto(Game,game_pos(Game)-1); ASSERT(!XB->new_hack); XB->new_hack = FALSE; // HACK? XB->result = FALSE; board_update(); mess(); } } else if (match(string,"usermove *")) { game_get_board(Game,board); move = move_from_san(Star[0],board); if (move != MoveNone && move_is_legal(move,board)) { XB->new_hack = FALSE; ASSERT(!XB->result); XB->result = FALSE; move_step(move); no_mess(move); } else { gui_send(GUI,"Illegal move: %s",Star[0]); } } else if (match(string,"variant *")) { if (my_string_equal(Star[0],"3check")) { option_set(Option,"3Check","true"); } else { option_set(Option,"3Check","false"); } if (my_string_equal(Star[0],"fischerandom")) { option_set(Option,"Chess960","true"); } else { option_set(Option,"Chess960","false"); } if (my_string_equal(Star[0],"atomic")) { option_set(Option,"Atomic","true"); } else { option_set(Option,"Atomic","false"); } if (my_string_equal(Star[0],"horde")) { option_set(Option,"Horde","true"); game_init(Game,StartFenHorde); //gui_send(GUI,"setup %s",StartFenHorde); } else { option_set(Option,"Horde","false"); } } else if (match(string,"white")) { if (colour_is_white(game_turn(Game))) { State->computer[White] = FALSE; State->computer[Black] = TRUE; XB->new_hack = TRUE; XB->result = FALSE; mess(); } } else if (match(string,"xboard")) { // ignore } else if (match(string,".")) { // analyse info if (State->state == ANALYSE) { int depth=Uci->best_depth;//HACK: don't clear engine-output window... ASSERT(Uci->searching); ASSERT(Uci->pending_nb>=1); if (Uci->root_move != MoveNone && move_is_legal(Uci->root_move,Uci->board)) { move_to_san(Uci->root_move,Uci->board,move_string,256); gui_send(GUI,"stat01: %.0f "S64_FORMAT" %d %d %d %s",Uci->time*100.0,Uci->node_nb,/*Uci->*/depth,Uci->root_move_nb-(Uci->root_move_pos+1),Uci->root_move_nb,move_string); } else { gui_send(GUI,"stat01: %.0f "S64_FORMAT" %d %d %d",Uci->time*100.0,Uci->node_nb,/*Uci->*/depth,0,0); // HACK } } } else if (match(string,"?")) { // move now if (State->state == THINK) { ASSERT(Uci->searching); ASSERT(Uci->pending_nb>=1); // HACK: just send "stop" to the engine if (Uci->searching) { my_log("POLYGLOT STOP SEARCH\n"); engine_send(Engine,"stop"); } } } else { // unknown command, maybe a move? game_get_board(Game,board); move = move_from_san(string,board); if (move != MoveNone && move_is_legal(move,board)) { XB->new_hack = FALSE; ASSERT(!XB->result); XB->result = FALSE; move_step(move); no_mess(move); } else if (move != MoveNone) { gui_send(GUI,"Illegal move: %s",string); } else { gui_send(GUI,"Error (unknown command): %s",string); } } return; }