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); } } } }
/* Displays a list of the available book moves, in a format Xboard understands. */ static void print_book_x(Board *board, MoveLst *move_list, int tot_score) { int i; int nmoves = 0; ASSERT(1, board != NULL); ASSERT(1, move_list != NULL); ASSERT(1, tot_score > 0); printf("0 0 0 0 ("); for (i = 0; i < move_list->nmoves; i++) { int score = move_list->score[i]; if (score != VAL_NONE) { double percent; char san_move[MAX_BUF]; percent = ((double)score / tot_score) * 100; if (percent < 1) continue; if (nmoves++ > 0) printf(", "); move_to_san(san_move, board, move_list->move[i]); printf("%s %.0f%%", san_move, percent); } } printf(")\n"); ASSERT(1, nmoves > 0); }
const std::string line_to_san(const Position &pos, Move line[], int startColumn, bool breakLines, int moveNumbers) { Position p = Position(pos); UndoInfo u; std::stringstream s, ns; std::string moveStr; int length, maxLength; length = 0; maxLength = 80 - startColumn; for(int i = 0; line[i] != MOVE_NONE; i++) { ns.str(""); if(moveNumbers && p.side_to_move() == WHITE) ns << moveNumbers + i/2 << ". "; else if(moveNumbers && i == 0) ns << moveNumbers + (i+1)/2 << "... "; moveStr = move_to_san(p, line[i]); length += moveStr.length() + 1; if(breakLines && length > maxLength) { s << "\n"; for(int j = 0; j < startColumn; j++) s << " "; length = moveStr.length() + 1; } s << ns.str() << moveStr << " "; if(line[i] == MOVE_NULL) p.do_null_move(u); else p.do_move(line[i], u); } return s.str(); }
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(); }
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 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(); }
/* Choose the best move (by searching or using the book), and make it. */ static void cpu_move(Chess *chess) { bool book_used = false; char san_move[MAX_BUF]; char str_move[MAX_BUF]; U32 move = NULLMOVE; int score = 0; S64 timer; Board *board; ASSERT(1, chess != NULL); board = &chess->board; timer = get_ms(); chess->sd.cmd_type = CMDT_CONTINUE; if (settings.book_type != BOOK_OFF) move = get_book_move(board, chess->show_pv, chess->book); if (move != NULLMOVE) { book_used = true; chess->in_book = true; } else { score = id_search(chess, NULLMOVE); if (chess->sd.cmd_type == CMDT_CANCEL) { chess->cpu_color = COLOR_NONE; return; } move = chess->sd.move; chess->in_book = false; } timer = get_ms() - timer; ASSERT(1, move != NULLMOVE); move_to_str(move, str_move); if (SIGN(board->color)*score < VAL_RESIGN) { if (board->color == WHITE) printf("0-1 {White resigns}\n"); else printf("1-0 {Black resigns}\n"); chess->game_over = true; return; } printf("move %s\n", str_move); if (chess->debug && chess->sd.nnodes > 0) { print_search_data(&chess->sd, (int)timer); printf("Score: %d\n", score); } move_to_san(san_move, board, move); update_game_log(board, san_move, score, book_used); update_game(chess, move); }
static void comp_move(int move) { board_t board[1]; char string[256]; ASSERT(move_is_ok(move)); ASSERT(State->state==THINK); ASSERT(!XB->analyse); if(option_get_bool(Option,"RepeatPV")) send_pv(); // to update time and nodes // send the move game_get_board(Game,board); if (move_is_castle(move,board) && option_get_bool(Option,"Chess960")) { if (!move_to_san(move,board,string,256)) my_fatal("comp_move(): move_to_san() failed\n"); // O-O/O-O-O } else { if (!move_to_can(move,board,string,256)) my_fatal("comp_move(): move_to_can() failed\n"); } gui_send(GUI,"move %s",string); // resign? if (option_get_bool(Option,"Resign") && Uci->root_move_nb > 1) { if (Uci->best_score <= -abs(option_get_int(Option,"ResignScore"))) { State->resign_nb++; my_log("POLYGLOT %d move%s with resign score\n",State->resign_nb,(State->resign_nb>1)?"s":""); if (State->resign_nb >= option_get_int(Option,"ResignMoves")) { my_log("POLYGLOT *** RESIGN ***\n"); gui_send(GUI,"resign"); } } else { if (State->resign_nb > 0) my_log("POLYGLOT resign reset (State->resign_nb=%d)\n",State->resign_nb); State->resign_nb = 0; } } // play the move move_step(move); no_mess(move); }
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; }
int move_from_san_debug(const char string[], const board_t * board) { list_t list[1]; int i, move; char move_string[256]; ASSERT(string!=NULL); ASSERT(board_is_ok(board)); gen_legal_moves(list,board); for (i = 0; i < list_size(list); i++) { move = list_move(list,i); if (!move_to_san(move,board,move_string,256)) ASSERT(false); if (my_string_equal(move_string,string)) return move; } return MoveNone; }
/* Displays a list of the available book moves. */ void print_book(Board *board, const AvlNode *book) { int i; int nmoves; int tot_score; MoveLst move_list; ASSERT(1, board != NULL); if (settings.book_type == BOOK_MEM && book == NULL) { printf("The opening book is empty or it doesn't exist\n"); return; } tot_score = get_book_move_list(board, &move_list, book); if (tot_score == 0) printf("There are no book moves for the current position\n"); if (tot_score <= 0) return; printf("Available book moves:\n"); nmoves = 0; for (i = 0; i < move_list.nmoves; i++) { U32 move = move_list.move[i]; int score = move_list.score[i]; if (score != VAL_NONE) { char san_move[MAX_BUF] = ""; move_to_san(san_move, board, move); printf(" %s: %d\n", san_move, score); nmoves++; } } printf("%d book moves were found\n", nmoves); ASSERT(1, nmoves > 0); }
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 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; }
static void comp_move(int move) { board_t board[1]; char string[256]; ASSERT(move_is_ok(move)); ASSERT(State->state==THINK); ASSERT(!XB->analyse); if(option_get_bool("RepeatPV")==true) send_pv(); // to update time and nodes // send the move game_get_board(Game,board); if (move_is_castle(move,board) && option_get_bool("Chess960")) { if (!move_to_san(move,board,string,sizeof(string))) my_fatal("comp_move(): move_to_san() failed\n"); // O-O/O-O-O } else { if (!move_to_can(move,board,string,sizeof(string))) my_fatal("comp_move(): move_to_can() failed\n"); } move_step(move); //game ended? if(game_status(Game)!= PLAYING){ //handle ics drawing stuff if(XB->ics){ switch (game_status(Game)){ case DRAW_MATERIAL: case DRAW_FIFTY: case DRAW_REPETITION: xboard_send(XBoard,"offer draw"); break; default: break; } } xboard_send(XBoard,"move %s",string); board_update(); no_mess(move); return; } // engine sended a move while in ponder mode? if(State->state==PONDER){ if(board->turn==White) xboard_send(XBoard,"0-1 {polyglot : engine moves while pondering}\n"); else xboard_send(XBoard,"1-0 {polyglot : engine moves while pondering}\n"); } // resign? if (option_get_bool("Resign") && Uci->root_move_nb > 1) { int best = Uci->best_score; if (option_get_bool("ScoreWhite") && colour_is_black(Uci->board->turn)) best = -best; if (best <= -abs(option_get_int("ResignScore"))) { State->resign_nb++; my_log("POLYGLOT %d move%s with resign score\n",State->resign_nb,(State->resign_nb>1)?"s":""); if (State->resign_nb >= option_get_int("ResignMoves")) { my_log("POLYGLOT *** RESIGN ***\n"); //send move and resign //xboard_send(XBoard,"move %s \nresign",string); //just resign xboard_send(XBoard,"resign",string); no_mess(move); return; } } else { if (State->resign_nb > 0) my_log("POLYGLOT resign reset (State->resign_nb=%d)\n",State->resign_nb); State->resign_nb = 0; } } no_mess(move); xboard_send(XBoard,"move %s",string); }
static int do_move(move_t *move, int ui_update) { char *move_s, *move_f, *move_san; board_t new_board; if (!move_is_valid(history->last->board, move)) { DBG_WARN("Move is illegal"); return 0; } move_set_attr(history->last->board, move); new_board = *history->last->board; move_s = move_to_fullalg(&new_board, move); move_list_play(&fullalg_list, move_s); move_san = move_to_san(&new_board, move); move_f = san_to_fan(&new_board, move_san); DBG_LOG("Processing move %s (%s)", move_s, move_san); move_list_play(&san_list, move_san); move_list_play(&fan_list, move_f); free(move_san); free(move_f); free(move_s); make_move(&new_board, move); if (move->state == MOVE_CHECK) new_board.state = BOARD_CHECK; else if (move->state == MOVE_CHECKMATE) new_board.state = BOARD_CHECKMATE; else new_board.state = BOARD_NORMAL; history_play(history, move, &new_board); if (ui_update) ui->update(history->view->board, move); if (new_board.state == MOVE_CHECKMATE) { history->result = malloc(sizeof(result_t)); if (new_board.turn == WHITE) { history->result->code = RESULT_BLACK_WINS; history->result->reason = strdup("Black mates"); } else { history->result->code = RESULT_WHITE_WINS; history->result->reason = strdup("White mates"); } if (ui_update) ui->show_result(history->result); } else if (new_board.state == MOVE_STALEMATE) { history->result = malloc(sizeof(result_t)); history->result->code = RESULT_DRAW; history->result->reason = strdup("Stalemate"); if (ui_update) ui->show_result(history->result); } return 1; }