From: H.G. Muller Date: Wed, 18 Apr 2012 15:53:47 +0000 (+0200) Subject: Delete files no longer part of project X-Git-Url: http://winboard.nl/cgi-bin?p=polyglot.git;a=commitdiff_plain;h=70421cb18dd22c8ca8a7d8e21c174183431403d6 Delete files no longer part of project The .cpp files have long since been converted to .c files, and some C++-specific .h files were also still around. Only files that are also in the Debian package for 1.4.67b are left now. --- diff --git a/adapter.cpp b/adapter.cpp deleted file mode 100644 index e27c114..0000000 --- a/adapter.cpp +++ /dev/null @@ -1,1622 +0,0 @@ - -// adapter.cpp - -// includes - -#include -#include -#include -#include - -#ifndef _WIN32 -#include -#include // Mac OS X needs this one -#include -#endif - -#include "adapter.h" -#include "board.h" -#include "book.h" -#include "colour.h" -#include "engine.h" -#include "fen.h" -#include "game.h" -#include "gui.h" -#include "line.h" -#include "main.h" -#include "move.h" -#include "move_do.h" -#include "move_legal.h" -#include "option.h" -#include "parse.h" -#include "san.h" -#include "uci.h" -#include "util.h" -#include "posix.h" - - -// constants - -static const bool UseDebug = false; -static const bool DelayPong = false; - -static const int StringSize = 4096; - -// types - -struct state_t { - int state; - bool computer[ColourNb]; - int exp_move; - int resign_nb; - my_timer_t timer[1]; -}; - -struct xb_t { - bool has_feature_memory; - bool has_feature_smp; - bool has_feature_egt; - bool analyse; - bool computer; - const char * name; - bool ics; - bool new_hack; // "new" is a C++ keyword - bool ponder; - int ping; - bool post; - int proto_ver; - bool result; - - int mps; - double base; - double inc; - - bool time_limit; - double time_max; - - bool depth_limit; - int depth_max; - - double my_time; - double opp_time; -}; - -enum dummy_state_t { WAIT, THINK, PONDER, ANALYSE }; - -// variables - -static state_t State[1]; -static xb_t XB[1]; - -// prototypes - - -static void xboard_step (char string[]); -static void engine_step (char string[]); - -static void comp_move (int move); -static void move_step (int move); -static void board_update (); - -static void mess (); -static void no_mess (int move); - -static void search_update (); -static void search_clear (); -static void update_remaining_time(); -static void start_protected_command(); -static void end_protected_command(); - -static bool active (); -static bool ponder (); -static bool ponder_ok (int ponder_move); - -static void stop_search (); - -static void send_board (int extra_move); -static void send_pv (); - -static void send_xboard_options (); - -static void learn (int result); - -static void adapter_step (); - -// functions - -// adapter_loop() - -void adapter_loop() { - - // init - - game_clear(Game); - - // state - - State->state = WAIT; - - State->computer[White] = false; - State->computer[Black] = true; - - State->exp_move = MoveNone; - State->resign_nb = 0; - my_timer_reset(State->timer); - - // yes there are engines that do not have the "Hash" option.... - XB->has_feature_memory= uci_option_exist(Uci,"Hash"); - XB->has_feature_smp = uci_thread_option_exist(Uci); - // TODO: support for other types of table bases - XB->has_feature_egt = uci_option_exist(Uci,"NalimovPath"); - XB->analyse = false; - XB->computer = false; - XB->name = NULL; - my_string_set(&XB->name,""); - XB->ics = false; - XB->new_hack = true; - XB->ping = -1; - XB->ponder = false; - XB->post = false; - XB->proto_ver = 1; - XB->result = false; - - XB->mps = 0; - XB->base = 300.0; - XB->inc = 0.0; - - XB->time_limit = false; - XB->time_max = 5.0; - - XB->depth_limit = false; - XB->depth_max = 127; - - XB->my_time = 300.0; - XB->opp_time = 300.0; - while (true) adapter_step(); -} - -// adapter_step() - -#ifdef _WIN32 -static void adapter_step(){ // polling! - bool xin,ein; - char string[StringSize]; - if(option_get_bool("UCI")){ - xin=gui_get_non_blocking(GUI,string,StringSize); - if(xin) uci_gui_step(string); - ein=engine_get_non_blocking(Engine,string,StringSize); - if(ein) uci_engine_step(string); - }else{ - xin=gui_get_non_blocking(GUI,string,StringSize); - if(xin) xboard_step(string); - ein=engine_get_non_blocking(Engine,string,StringSize); - if(ein) engine_step(string); - } - if(xin==false && ein==false) Idle();//nobody wants me,lets have a beauty nap -} -#else -static void adapter_step() { - - fd_set set[1]; - int fd_max; - int val; - char string[StringSize]; - - // process buffered lines - - while (io_line_ready(GUI->io)){ - gui_get(GUI,string,StringSize); - if(option_get_bool("UCI")){ - uci_gui_step(string); - }else{ - xboard_step(string); // process available xboard lines - } - } - while (io_line_ready(Engine->io)){ - engine_get(Engine,string,StringSize); - if(option_get_bool("UCI")){ - uci_engine_step(string); // process available engine lines - }else{ - engine_step(string); - } - } - - // init - - FD_ZERO(set); - fd_max = -1; // HACK - - // add xboard input - - ASSERT(GUI->io->in_fd>=0); - - FD_SET(GUI->io->in_fd,set); - if (GUI->io->in_fd > fd_max) fd_max = GUI->io->in_fd; - - // add engine input - - ASSERT(Engine->io->in_fd>=0); - - FD_SET(Engine->io->in_fd,set); - if (Engine->io->in_fd > fd_max) fd_max = Engine->io->in_fd; - - // wait for something to read (no timeout) - - ASSERT(fd_max>=0); - - val = select(fd_max+1,set,NULL,NULL,NULL); - if (val == -1 && errno != EINTR) my_fatal("adapter_step(): select(): %s\n",strerror(errno)); - - if (val > 0) { - if (FD_ISSET(GUI->io->in_fd,set)) io_get_update(GUI->io); // read some xboard input - if (FD_ISSET(Engine->io->in_fd,set)) io_get_update(Engine->io); // read some engine input - } -} -#endif - -static void xboard_step(char string[]) { - - int move; - char move_string[256]; - board_t board[1]; - static bool firsttime=true; - - if(firsttime){ - if((match(string,"uci"))){ - my_log("POLYGLOT *** Switching to UCI mode ***\n"); - send_uci_options(); - option_set("UCI","true"); - return; - }else{ - //uci_send_isready(Uci); // In UCI mode this done by the GUI - //Grrr...Toga can fixes the number of threads after "isready" - //So we delay "isready" - } - firsttime=false; - } - 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")) { - if(uci_option_exist(Uci,"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")) { - - 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); - 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(Uci); - 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,""); - - 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(Uci); - } else { - ASSERT(XB->ping==-1); - gui_send(GUI,"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 *")) { - - 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 (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 - - gui_send(GUI,"Error (unknown command): %s",string); - - } else if (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{ - start_protected_command(); - engine_send(Engine,"setoption name %s value %s",name,value); - end_protected_command(); - } - } else if (match(string,"option *")){ - char *name=Star[0]; - start_protected_command(); - engine_send(Engine,"setoption name %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 (XB->has_feature_egt && match(string,"egtpath * *")){ - char *type=Star[0]; - char *path=Star[1]; - if(!my_string_case_equal(Star[0],"nalimov")){ - // refuse - gui_send(GUI,"Error (unsupported table base format): %s",string); - }else if(my_string_empty(path)){ - // refuse - gui_send(GUI,"Error (unknown command): %s",string); - }else{ - // 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 (XB->has_feature_memory && match(string,"memory *")){ - int memory = atoi(Star[0]); - int nalimov_cache; - int real_memory; - if(memory>=1){ - // updating the available memory - my_log("POLYGLOT setting the amount of memory to %dMb\n",memory); - if(uci_get_option(Uci,"NalimovCache")>=0){ - nalimov_cache=atoi(Uci->option[uci_get_option(Uci,"NalimovCache")].value); - }else{ - nalimov_cache=0; - } - my_log("POLYGLOT Nalimov Cache is %dMb\n",nalimov_cache); - real_memory=memory-nalimov_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],"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) { - 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; -} - -// engine_step() - -static void engine_step(char string[]) { - - int event; - event = uci_parse(Uci,string); - - // react to events - - if ((event & EVENT_READY) != 0) { - - // the engine is now ready - - if (!Uci->ready) { - Uci->ready = true; - // if (XB->proto_ver >= 2) xboard_send(XBoard,"feature done=1"); - } - - if (!DelayPong && XB->ping >= 0) { - gui_send(GUI,"pong %d",XB->ping); - XB->ping = -1; - } - } - - if ((event & EVENT_MOVE) != 0 && State->state == THINK) { - - // the engine is playing a move - - // MEGA HACK: estimate remaining time because XBoard won't send it! - - my_timer_stop(State->timer); - - XB->my_time -= my_timer_elapsed_real(State->timer); - XB->my_time += XB->inc; - if (XB->mps != 0 && (game_move_nb(Game) + 1) % XB->mps == 0) XB->my_time += XB->base; - - if (XB->my_time < 0.0) XB->my_time = 0.0; - - // play the engine move - - comp_move(Uci->best_move); - } - - if ((event & EVENT_PV) != 0) { - - // the engine has sent a new PV - - send_pv(); - } - if((event & (EVENT_DRAW|EVENT_RESIGN))!=0){ - my_log("POYGLOT draw offer/resign from engine\n"); - if(uci_option_exist(Uci,"UCI_DrawOffers")){ - if(event & EVENT_DRAW) - gui_send(GUI,"offer draw"); - else - gui_send(GUI,"resign"); - } - } -} - -// format_xboard_option_line - -void format_xboard_option_line(char * option_line, option_t *opt){ - int j; - char option_string[StringSize]; - strcpy(option_line,""); - strcat(option_line,"feature option=\""); - if(opt->mode&PG){ - strcat(option_line,"Polyglot "); - } - sprintf(option_string,"%s",opt->name); - strcat(option_line,option_string); - sprintf(option_string," -%s",opt->type); - strcat(option_line,option_string); - if(strcmp(opt->type,"button") && strcmp(opt->type,"combo")){ - if(strcmp(opt->type,"check")){ - sprintf(option_string," %s",opt->default_); - }else{ - sprintf(option_string," %d", - strcmp(opt->default_,"true")?0:1); - } - strcat(option_line,option_string); - } - if(!strcmp(opt->type,"spin")){ - sprintf(option_string," %s",opt->min); - strcat(option_line,option_string); - } - if(!strcmp(opt->type,"spin")){ - sprintf(option_string," %s",opt->max); - strcat(option_line,option_string); - } - for(j=0;jvar_nb;j++){ - if(!strcmp(opt->var[j],opt->default_)){ - sprintf(option_string," *%s",opt->var[j]); - }else{ - sprintf(option_string," %s",opt->var[j]); - } - strcat(option_line,option_string); - if(j!=opt->var_nb-1){ - strcat(option_line," ///"); - } - } - strcat(option_line,"\""); -} - -// send_xboard_options - -static void send_xboard_options(){ - int i; - char option_line[StringSize]=""; - option_t *p=Option; - const char * name; - XB->proto_ver = atoi(Star[0]); - ASSERT(XB->proto_ver>=2); - - gui_send(GUI,"feature done=0"); - - gui_send(GUI,"feature analyze=1"); - gui_send(GUI,"feature colors=0"); - gui_send(GUI,"feature draw=1"); - gui_send(GUI,"feature ics=1"); - gui_send(GUI,"feature myname=\"%s\"",option_get_string("EngineName")); - gui_send(GUI,"feature name=1"); - gui_send(GUI,"feature pause=0"); - gui_send(GUI,"feature ping=1"); - gui_send(GUI,"feature playother=1"); - gui_send(GUI,"feature reuse=1"); - gui_send(GUI,"feature san=0"); - gui_send(GUI,"feature setboard=1"); - gui_send(GUI,"feature sigint=0"); - gui_send(GUI,"feature sigterm=0"); - gui_send(GUI,"feature time=1"); - gui_send(GUI,"feature usermove=1"); - if (XB->has_feature_memory){ - gui_send(GUI,"feature memory=1"); - }else{ - gui_send(GUI,"feature memory=0"); - } - if (XB->has_feature_smp){ - gui_send(GUI,"feature smp=1"); - }else{ - gui_send(GUI,"feature smp=0"); - } - if (XB->has_feature_egt){ - // TODO: support for other types of table bases - gui_send(GUI,"feature egt=\"nalimov\""); - }else{ - gui_send(GUI,"feature egt=\"\""); - } - - if (uci_option_exist(Uci,"UCI_Chess960")) { - gui_send(GUI,"feature variants=\"normal,fischerandom\""); - } else { - gui_send(GUI,"feature variants=\"normal\""); - } - - for(i=0;ioption_nb;i++){ - if(!strcmp(Uci->option[i].name,PolyglotBookFile)) continue; - if(my_string_case_equal(Uci->option[i].name,"UCI_AnalyseMode")) continue; - if(my_string_case_equal(Uci->option[i].name,"Ponder")) continue; - if(my_string_case_equal(Uci->option[i].name,"Hash")) continue; - if(my_string_case_equal(Uci->option[i].name,"NalimovPath")) continue; - if((name=uci_thread_option(Uci))!=NULL && my_string_case_equal(Uci->option[i].name,name)) continue; - format_xboard_option_line(option_line,Uci->option+i); - - gui_send(GUI,"%s",option_line); - - } - while(p->name){ - if(p->mode &XBOARD){ - format_xboard_option_line(option_line,p); - gui_send(GUI,"%s",option_line); - } - p++; - } - gui_send(GUI,"feature done=1"); - -} - -// comp_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("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,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("Resign") && Uci->root_move_nb > 1) { - - if (Uci->best_score <= -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"); - 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); -} - -// move_step() - -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(); -} - -// board_update() - -static void board_update() { - - // handle game end - - ASSERT(!XB->result); - - switch (game_status(Game)) { - case PLAYING: - break; - case WHITE_MATES: - gui_send(GUI,"1-0 {White mates}"); - break; - case BLACK_MATES: - gui_send(GUI,"0-1 {Black mates}"); - break; - case STALEMATE: - gui_send(GUI,"1/2-1/2 {Stalemate}"); - break; - case DRAW_MATERIAL: - gui_send(GUI,"1/2-1/2 {Draw by insufficient material}"); - break; - case DRAW_FIFTY: - gui_send(GUI,"1/2-1/2 {Draw by fifty-move rule}"); - break; - case DRAW_REPETITION: - gui_send(GUI,"1/2-1/2 {Draw by repetition}"); - break; - default: - ASSERT(false); - break; - } -} - -// mess() - -static void mess() { - - // clear state variables - - State->resign_nb = 0; - State->exp_move = MoveNone; - my_timer_reset(State->timer); - - // abort a possible search - - stop_search(); - - // calculate the new state - - if (false) { - } else if (!active()) { - State->state = WAIT; - my_log("POLYGLOT WAIT\n"); - } else if (XB->analyse) { - State->state = ANALYSE; - my_log("POLYGLOT ANALYSE\n"); - } else if (State->computer[game_turn(Game)]) { - State->state = THINK; - my_log("POLYGLOT THINK\n"); - } else { - State->state = WAIT; - my_log("POLYGLOT WAIT\n"); - } - - search_update(); -} - -// no_mess() - -static void no_mess(int move) { - - ASSERT(move_is_ok(move)); - - // just received a move, calculate the new state - - if (false) { - - } else if (!active()) { - - stop_search(); // abort a possible search - - State->state = WAIT; - State->exp_move = MoveNone; - - my_log("POLYGLOT WAIT\n"); - - } else if (State->state == WAIT) { - - ASSERT(State->computer[game_turn(Game)]); - ASSERT(!State->computer[colour_opp(game_turn(Game))]); - ASSERT(!XB->analyse); - - my_log("POLYGLOT WAIT -> THINK\n"); - - State->state = THINK; - State->exp_move = MoveNone; - - } else if (State->state == THINK) { - - ASSERT(!State->computer[game_turn(Game)]); - ASSERT(State->computer[colour_opp(game_turn(Game))]); - ASSERT(!XB->analyse); - - if (ponder() && ponder_ok(Uci->ponder_move)) { - - my_log("POLYGLOT THINK -> PONDER\n"); - - State->state = PONDER; - State->exp_move = Uci->ponder_move; - - } else { - - my_log("POLYGLOT THINK -> WAIT\n"); - - State->state = WAIT; - State->exp_move = MoveNone; - } - - } else if (State->state == PONDER) { - - ASSERT(State->computer[game_turn(Game)]); - ASSERT(!State->computer[colour_opp(game_turn(Game))]); - ASSERT(!XB->analyse); - - if (move == State->exp_move && Uci->searching) { - - ASSERT(Uci->searching); - ASSERT(Uci->pending_nb>=1); - - my_timer_start(State->timer);//also resets - - my_log("POLYGLOT PONDER -> THINK (*** HIT ***)\n"); - engine_send(Engine,"ponderhit"); - - State->state = THINK; - State->exp_move = MoveNone; - - send_pv(); // update display - - return; // do not launch a new search - - } else { - - my_log("POLYGLOT PONDER -> THINK (miss)\n"); - - stop_search(); - - State->state = THINK; - State->exp_move = MoveNone; - } - - } else if (State->state == ANALYSE) { - - ASSERT(XB->analyse); - - my_log("POLYGLOT ANALYSE -> ANALYSE\n"); - - stop_search(); - - } else { - - ASSERT(false); - } - - search_update(); -} - -// start_protected_command() - -static void start_protected_command(){ - stop_search(); -} - -static void end_protected_command(){ - if(Uci->ready){ // not init faze - uci_send_isready_sync(Uci); // gobble up spurious "bestmove" - } - update_remaining_time(); - search_update(); // relaunch search if necessary -} - -// update_remaining_time() - -static void update_remaining_time(){ - double reduce; - if(State->timer->running){ - my_timer_stop(State->timer); - reduce = my_timer_elapsed_real(State->timer); - my_log("POLYGLOT reducing remaing time by %f seconds\n",reduce); - XB->my_time -= reduce; - if(XB->my_time<0.0){ - XB->my_time=0.0; - } - } -} - - -// search_update() - -static void search_update() { - - int move; - int move_nb; - board_t board[1]; - int nalimov_cache; - int real_memory; - - 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++; - } -} - -// search_clear() - -static void search_clear() { - - uci_clear(Uci); - - // TODO: MOVE ME - - my_timer_start(State->timer);//also resets -} - -// active() - -static bool active() { - - // position state - - if (game_status(Game) != PLAYING) return false; // game ended - - // xboard state - - if (XB->analyse) return true; // analysing - if (!State->computer[White] && !State->computer[Black]) return false; // force mode - if (XB->new_hack || XB->result) return false; // unstarted or ended game - - return true; // playing -} - -// ponder() - -static bool ponder() { - - return XB->ponder && (option_get_bool("CanPonder") || uci_option_exist(Uci,"Ponder")); -} -// ponder_ok() - -static bool ponder_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; -} - -// stop_search() - -static void stop_search() { - - if (Uci->searching) { - - ASSERT(Uci->searching); - ASSERT(Uci->pending_nb>=1); - - my_log("POLYGLOT STOP SEARCH\n"); - -/* - engine_send(Engine,"stop"); - Uci->searching = false; -*/ - - if (option_get_bool("SyncStop")) { - uci_send_stop_sync(Uci); - } else { - uci_send_stop(Uci); - } - } -} - -// send_board() - -static void send_board(int extra_move) { - - char fen[256]; - int start, end; - board_t board[1]; - int pos; - int move; - char string[256]; - - ASSERT(extra_move==MoveNone||move_is_ok(extra_move)); - - ASSERT(!Uci->searching); - - // init - - game_get_board(Game,Uci->board); - if (extra_move != MoveNone) move_do(Uci->board,extra_move); - - board_to_fen(Uci->board,fen,256); - my_log("POLYGLOT FEN %s\n",fen); - - ASSERT(board_can_play(Uci->board)); - - // more init - - start = 0; - end = game_pos(Game); - ASSERT(end>=start); - - // position - - game_get_board(Game,board,start); - board_to_fen(board,string,256); - - engine_send_queue(Engine,"position"); - - if (my_string_equal(string,StartFen)) { - engine_send_queue(Engine," startpos"); - } else { - engine_send_queue(Engine," fen %s",string); - } - - // move list - - if (end > start || extra_move != MoveNone) engine_send_queue(Engine," moves"); - - for (pos = start; pos < end; pos++) { // game moves - - move = game_move(Game,pos); - - move_to_can(move,board,string,256); - engine_send_queue(Engine," %s",string); - - move_do(board,move); - } - - if (extra_move != MoveNone) { // move to ponder on - move_to_can(extra_move,board,string,256); - engine_send_queue(Engine," %s",string); - } - - // end - - engine_send(Engine,""); // newline -} - -// send_pv() - -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); - - if(Uci->depth==-1) //hack to clear the engine output window - gui_send(GUI,"%d %+d %.0f "S64_FORMAT" ",0,Uci->best_score,Uci->time*100.0,Uci->node_nb); - - gui_send(GUI,"%d %+d %.0f "S64_FORMAT" %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); - gui_send(GUI,"%d %+d %.0f "S64_FORMAT" (%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); - gui_send(GUI,"%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,256); - line_to_san(Uci->best_pv,Uci->board,pv_string,StringSize); - gui_send(GUI,"%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); - } - } - } -} - -// learn() - -static void learn(int result) { - - int pos; - board_t board[1]; - int move; - - ASSERT(result>=-1&&result<=+1); - - ASSERT(XB->result); - ASSERT(State->computer[White]||State->computer[Black]); - - // init - - pos = 0; - - if (false) { - } else if (State->computer[White]) { - pos = 0; - } else if (State->computer[Black]) { - pos = 1; - result = -result; - } else { - my_fatal("learn(): unknown side\n"); - } - - if (false) { - } else if (result > 0) { - my_log("POLYGLOT *LEARN WIN*\n"); - } else if (result < 0) { - my_log("POLYGLOT *LEARN LOSS*\n"); - } else { - my_log("POLYGLOT *LEARN DRAW*\n"); - } - - // loop - - for (; pos < Game->size; pos += 2) { - - game_get_board(Game,board,pos); - move = game_move(Game,pos); - - book_learn_move(board,move,result); - } - - book_flush(); -} - -// end of adapter.cpp diff --git a/adapter.h b/adapter.h deleted file mode 100644 index 4f6e85b..0000000 --- a/adapter.h +++ /dev/null @@ -1,26 +0,0 @@ - -// adapter.h - -#ifndef ADAPTER_H -#define ADAPTER_H - -// includes - -#include "util.h" -#include "uci2uci.h" - -// types - - - - - -// functions - -extern void adapter_loop (); - - -#endif // !defined ADAPTER_H - -// end of adapter.h - diff --git a/attack.cpp b/attack.cpp deleted file mode 100644 index b1ce1f5..0000000 --- a/attack.cpp +++ /dev/null @@ -1,224 +0,0 @@ - -// attack.cpp - -// includes - -#include "board.h" -#include "colour.h" -#include "move.h" -#include "attack.h" -#include "piece.h" -#include "util.h" - -// macros - -#define DELTA_INC(delta) (DeltaInc[128+(delta)]) -#define DELTA_MASK(delta) (DeltaMask[128+(delta)]) - -// "constants" - -const sint8 KnightInc[8+1] = { - -33, -31, -18, -14, +14, +18, +31, +33, 0 -}; - -const sint8 BishopInc[4+1] = { - -17, -15, +15, +17, 0 -}; - -const sint8 RookInc[4+1] = { - -16, -1, +1, +16, 0 -}; - -const sint8 QueenInc[8+1] = { - -17, -16, -15, -1, +1, +15, +16, +17, 0 -}; - -const sint8 KingInc[8+1] = { - -17, -16, -15, -1, +1, +15, +16, +17, 0 -}; - -// variables - -static sint8 DeltaInc[256]; -static uint8 DeltaMask[256]; - -// prototypes - -static bool delta_is_ok (int delta); -static bool inc_is_ok (int inc); - -// functions - -// attack_init() - -void attack_init() { - - int delta; - int dir, inc, dist; - - for (delta = -128; delta < +128; delta++) { - DeltaInc[128+delta] = IncNone; - DeltaMask[128+delta] = 0; - } - - DeltaMask[128-17] |= BlackPawnFlag; - DeltaMask[128-15] |= BlackPawnFlag; - - DeltaMask[128+15] |= WhitePawnFlag; - DeltaMask[128+17] |= WhitePawnFlag; - - for (dir = 0; dir < 8; dir++) { - delta = KnightInc[dir]; - ASSERT(delta_is_ok(delta)); - DeltaMask[128+delta] |= KnightFlag; - } - - for (dir = 0; dir < 4; dir++) { - inc = BishopInc[dir]; - ASSERT(inc!=IncNone); - for (dist = 1; dist < 8; dist++) { - delta = inc*dist; - ASSERT(delta_is_ok(delta)); - ASSERT(DeltaInc[128+delta]==IncNone); - DeltaInc[128+delta] = inc; - DeltaMask[128+delta] |= BishopFlag; - } - } - - for (dir = 0; dir < 4; dir++) { - inc = RookInc[dir]; - ASSERT(inc!=IncNone); - for (dist = 1; dist < 8; dist++) { - delta = inc*dist; - ASSERT(delta_is_ok(delta)); - ASSERT(DeltaInc[128+delta]==IncNone); - DeltaInc[128+delta] = inc; - DeltaMask[128+delta] |= RookFlag; - } - } - - for (dir = 0; dir < 8; dir++) { - delta = KingInc[dir]; - ASSERT(delta_is_ok(delta)); - DeltaMask[128+delta] |= KingFlag; - } -} - -// delta_is_ok() - -static bool delta_is_ok(int delta) { - - if (delta < -119 || delta > +119) return false; - - return true; -} - -// inc_is_ok() - -static bool inc_is_ok(int inc) { - - int dir; - - for (dir = 0; dir < 8; dir++) { - if (KingInc[dir] == inc) return true; - } - - return false; -} - -// is_in_check() - -bool is_in_check(const board_t * board, int colour) { - - ASSERT(board_is_ok(board)); - ASSERT(colour_is_ok(colour)); - - return is_attacked(board,king_pos(board,colour),colour_opp(colour)); -} - -// is_attacked() - -bool is_attacked(const board_t * board, int to, int colour) { - - const uint8 * ptr; - int from, piece; - - ASSERT(board_is_ok(board)); - ASSERT(square_is_ok(to)); - ASSERT(colour_is_ok(colour)); - - for (ptr = board->list[colour]; (from=*ptr) != SquareNone; ptr++) { - - piece = board->square[from]; - ASSERT(colour_equal(piece,colour)); - - if (piece_attack(board,piece,from,to)) return true; - } - - return false; -} - -// piece_attack() - -bool piece_attack(const board_t * board, int piece, int from, int to) { - - int delta; - int inc, sq; - - ASSERT(board_is_ok(board)); - ASSERT(piece_is_ok(piece)); - ASSERT(square_is_ok(from)); - ASSERT(square_is_ok(to)); - - delta = to - from; - ASSERT(delta_is_ok(delta)); - - if ((piece & DELTA_MASK(delta)) == 0) return false; // no pseudo-attack - - if (!piece_is_slider(piece)) return true; - - inc = DELTA_INC(delta); - ASSERT(inc_is_ok(inc)); - - for (sq = from+inc; sq != to; sq += inc) { - ASSERT(square_is_ok(sq)); - if (board->square[sq] != Empty) return false; // blocker - } - - return true; -} - -// is_pinned() - -bool is_pinned(const board_t * board, int from, int to, int colour) { - - int king; - int inc; - int sq, piece; - - ASSERT(board!=NULL); - ASSERT(square_is_ok(from)); - ASSERT(square_is_ok(to)); - ASSERT(colour_is_ok(colour)); - - king = king_pos(board,colour); - - inc = DELTA_INC(king-from); - if (inc == IncNone) return false; // not a line - - sq = from; - do sq += inc; while (board->square[sq] == Empty); - - if (sq != king) return false; // blocker - - sq = from; - do sq -= inc; while ((piece=board->square[sq]) == Empty); - - return square_is_ok(sq) - && (piece & DELTA_MASK(king-sq)) != 0 - && piece_colour(piece) == colour_opp(colour) - && DELTA_INC(king-to) != inc; -} - -// end of attack.cpp - diff --git a/board.cpp b/board.cpp deleted file mode 100644 index 6e04900..0000000 --- a/board.cpp +++ /dev/null @@ -1,492 +0,0 @@ - -// board.cpp - -// includes - -#include - -#include "attack.h" -#include "board.h" -#include "colour.h" -#include "fen.h" -#include "hash.h" -#include "list.h" -#include "move.h" -#include "move_do.h" -#include "move_gen.h" -#include "move_legal.h" -#include "piece.h" -#include "util.h" - -// constants - -static const bool UseSlowDebug = false; - -// functions - -// board_is_ok() - -bool board_is_ok(const board_t * board) { - - int sq, piece; - int colour, pos; - int king, rook; - - if (board == NULL) return false; - - // optional heavy DEBUG mode - - if (!UseSlowDebug) return true; - - // squares - - for (sq = 0; sq < SquareNb; sq++) { - piece = board->square[sq]; - if (square_is_ok(sq)) { - pos = board->pos[sq]; - if (piece == Empty) { - if (pos != -1) return false; - } else { - if (pos < 0) return false; - if (board->list[piece_colour(piece)][pos] != sq) return false; - } - } else { - if (piece != Knight64) return false; - } - } - - // white piece list - - colour = White; - pos = 0; - - if (board->list_size[colour] <= 0 || board->list_size[colour] > 16) return false; - - sq = board->list[colour][pos]; - if (sq == SquareNone) return false; - if (board->pos[sq] != pos) return false; - piece = board->square[sq]; - if (!colour_equal(piece,colour) || !piece_is_king(piece)) return false; - - for (pos++; pos < board->list_size[colour]; pos++) { - sq = board->list[colour][pos]; - if (sq == SquareNone) return false; - if (board->pos[sq] != pos) return false; - if (!colour_equal(board->square[sq],colour)) return false; - } - - sq = board->list[colour][pos]; - if (sq != SquareNone) return false; - - // black piece list - - colour = Black; - pos = 0; - - if (board->list_size[colour] <= 0 || board->list_size[colour] > 16) return false; - - sq = board->list[colour][pos]; - if (sq == SquareNone) return false; - if (board->pos[sq] != pos) return false; - piece = board->square[sq]; - if (!colour_equal(piece,colour) || !piece_is_king(piece)) return false; - - for (pos++; pos < board->list_size[colour]; pos++) { - sq = board->list[colour][pos]; - if (sq == SquareNone) return false; - if (board->pos[sq] != pos) return false; - if (!colour_equal(board->square[sq],colour)) return false; - } - - sq = board->list[colour][pos]; - if (sq != SquareNone) return false; - - // TODO: material - - if (board->number[WhiteKing12] != 1) return false; - if (board->number[BlackKing12] != 1) return false; - - if (!colour_is_ok(board->turn)) return false; - - // castling status - - if (board->castle[White][SideH] != SquareNone) { - - king = board->list[White][0]; - if (king < A1 || king > H1) return false; - if (board->square[king] != WhiteKing256) return false; - - rook = board->castle[White][SideH]; - if (rook < A1 || rook > H1) return false; - if (board->square[rook] != WhiteRook256) return false; - - if (rook <= king) return false; - } - - if (board->castle[White][SideA] != SquareNone) { - - king = board->list[White][0]; - if (king < A1 || king > H1) return false; - if (board->square[king] != WhiteKing256) return false; - - rook = board->castle[White][SideA]; - if (rook < A1 || rook > H1) return false; - if (board->square[rook] != WhiteRook256) return false; - - if (rook >= king) return false; - } - - if (board->castle[Black][SideH] != SquareNone) { - - king = board->list[Black][0]; - if (king < A8 || king > H8) return false; - if (board->square[king] != BlackKing256) return false; - - rook = board->castle[Black][SideH]; - if (rook < A8 || rook > H8) return false; - if (board->square[rook] != BlackRook256) return false; - - if (rook <= king) return false; - } - - if (board->castle[Black][SideA] != SquareNone) { - - king = board->list[Black][0]; - if (king < A8 || king > H8) return false; - if (board->square[king] != BlackKing256) return false; - - rook = board->castle[Black][SideA]; - if (rook < A8 || rook > H8) return false; - if (board->square[rook] != BlackRook256) return false; - - if (rook >= king) return false; - } - - return true; -} - -// board_clear() - -void board_clear(board_t * board) { - - int file, rank, sq; - int colour, pos; - int piece; - - ASSERT(board!=NULL); - - // edge squares - - for (sq = 0; sq < SquareNb; sq++) { - board->square[sq] = Knight64; // HACK: uncoloured knight - board->pos[sq] = -1; - } - - // empty squares - - for (rank = 0; rank < 8; rank++) { - for (file = 0; file < 8; file++) { - sq = square_make(file,rank); - board->square[sq] = Empty; - } - } - - // piece lists - - for (colour = 0; colour < 3; colour++) { - for (pos = 0; pos < 32; pos++) { // HACK - board->list[colour][pos] = SquareNone; - } - board->list_size[colour] = 0; - } - - // material - - for (piece = 0; piece < 12; piece++) { - board->number[piece] = 0; - } - - // rest - - board->turn = ColourNone; - board->castle[White][SideH] = SquareNone; - board->castle[White][SideA] = SquareNone; - board->castle[Black][SideH] = SquareNone; - board->castle[Black][SideA] = SquareNone; - board->ep_square = SquareNone; - - board->ply_nb = 0; - board->move_nb = 0; - - board->key = 0; -} - -// board_start() - -void board_start(board_t * board) { - - ASSERT(board!=NULL); - - if (!board_from_fen(board,StartFen)) ASSERT(false); -} - -// board_copy() - -void board_copy(board_t * dst, const board_t * src) { - - ASSERT(dst!=NULL); - ASSERT(board_is_ok(src)); - - *dst = *src; -} - -// board_equal() - -bool board_equal(const board_t * board_1, const board_t * board_2) { - - int sq_64, sq; - - ASSERT(board_is_ok(board_1)); - ASSERT(board_is_ok(board_2)); - - // fast comparison - - if (board_1->key != board_2->key) return false; - - // slow comparison - - for (sq_64 = 0; sq_64 < 64; sq_64++) { - sq = square_from_64(sq_64); - if (board_1->square[sq] != board_2->square[sq]) return false; - } - - if (board_1->turn != board_2->turn) return false; - if (board_1->castle[White][SideH] != board_2->castle[White][SideH]) return false; - if (board_1->castle[White][SideA] != board_2->castle[White][SideA]) return false; - if (board_1->castle[Black][SideH] != board_2->castle[Black][SideH]) return false; - if (board_1->castle[Black][SideA] != board_2->castle[Black][SideA]) return false; - if (board_1->ep_square != board_2->ep_square) return false; - - return true; -} - -// board_init_list() - -void board_init_list(board_t * board) { - - int sq_64, sq, piece; - int colour, pos; - - ASSERT(board!=NULL); - - // init - - for (sq_64 = 0; sq_64 < 64; sq_64++) { - sq = square_from_64(sq_64); - board->pos[sq] = -1; - } - - for (piece = 0; piece < 12; piece++) board->number[piece] = 0; - - // white piece list - - colour = White; - pos = 0; - - for (sq_64 = 0; sq_64 < 64; sq_64++) { - sq = square_from_64(sq_64); - piece = board->square[sq]; - ASSERT(pos>=0&&pos<=16); - if (colour_equal(piece,colour) && piece_is_king(piece)) { - board->pos[sq] = pos; - board->list[colour][pos] = sq; - pos++; - board->number[piece_to_12(piece)]++; - } - } - ASSERT(pos==1); - - for (sq_64 = 0; sq_64 < 64; sq_64++) { - sq = square_from_64(sq_64); - piece = board->square[sq]; - ASSERT(pos>=0&&pos<=16); - if (colour_equal(piece,colour) && !piece_is_king(piece)) { - board->pos[sq] = pos; - board->list[colour][pos] = sq; - pos++; - board->number[piece_to_12(piece)]++; - } - } - - ASSERT(pos>=1&&pos<=16); - board->list[colour][pos] = SquareNone; - board->list_size[colour] = pos; - - // black piece list - - colour = Black; - pos = 0; - - for (sq_64 = 0; sq_64 < 64; sq_64++) { - sq = square_from_64(sq_64); - piece = board->square[sq]; - ASSERT(pos>=0&&pos<=16); - if (colour_equal(piece,colour) && piece_is_king(piece)) { - board->pos[sq] = pos; - board->list[colour][pos] = sq; - pos++; - board->number[piece_to_12(piece)]++; - } - } - ASSERT(pos==1); - - for (sq_64 = 0; sq_64 < 64; sq_64++) { - sq = square_from_64(sq_64); - piece = board->square[sq]; - ASSERT(pos>=1&&pos<=16); - if (colour_equal(piece,colour) && !piece_is_king(piece)) { - board->pos[sq] = pos; - board->list[colour][pos] = sq; - pos++; - board->number[piece_to_12(piece)]++; - } - } - - ASSERT(pos>=1&&pos<=16); - board->list[colour][pos] = SquareNone; - board->list_size[colour] = pos; - - // hash key - - board->key = hash_key(board); -} - -// board_flags() - -int board_flags(const board_t * board) { - - int flags; - - flags = 0; - - if (board->castle[White][SideH] != SquareNone) flags |= 1 << 0; - if (board->castle[White][SideA] != SquareNone) flags |= 1 << 1; - if (board->castle[Black][SideH] != SquareNone) flags |= 1 << 2; - if (board->castle[Black][SideA] != SquareNone) flags |= 1 << 3; - - return flags; -} - -// board_can_play() - -bool board_can_play(const board_t * board) { - - list_t list[1]; - int i, move; - - ASSERT(board_is_ok(board)); - - gen_moves(list,board); - - for (i = 0; i < list_size(list); i++) { - move = list_move(list,i); - if (pseudo_is_legal(move,board)) return true; - } - - return false; // no legal move -} - -// board_mobility() - -int board_mobility(const board_t * board) { - - list_t list[1]; - - ASSERT(board_is_ok(board)); - - gen_legal_moves(list,board); - - return list_size(list); -} - -// board_is_check() - -bool board_is_check(const board_t * board) { - - ASSERT(board_is_ok(board)); - - return is_in_check(board,board->turn); -} - -// board_is_mate() - -bool board_is_mate(const board_t * board) { - - ASSERT(board_is_ok(board)); - - if (!board_is_check(board)) return false; - if (board_can_play(board)) return false; - - return true; -} - -// board_is_stalemate() - -bool board_is_stalemate(const board_t * board) { - - ASSERT(board_is_ok(board)); - - if (board_is_check(board)) return false; - if (board_can_play(board)) return false; - - return true; -} - -// king_pos() - -int king_pos(const board_t * board, int colour) { - - ASSERT(board_is_ok(board)); - ASSERT(colour_is_ok(colour)); - - return board->list[colour][0]; -} - -// board_disp() - -void board_disp(const board_t * board) { - - int file, rank, sq; - int piece, c; - char fen[256]; - - ASSERT(board!=NULL); - - if (!board_to_fen(board,fen,256)) ASSERT(false); - my_log("POLYGLOT %s\n",fen); - my_log("POLYGLOT\n"); - - for (rank = 7; rank >= 0; rank--) { - - my_log("POLYGLOT "); - - for (file = 0; file < 8; file++) { - - sq = square_make(file,rank); - piece = board->square[sq]; - - c = (piece != Empty) ? piece_to_char(piece) : '-'; - my_log("%c ",c); - } - - my_log("\n"); - } - - my_log("POLYGLOT\n"); - - my_log("POLYGLOT %s to play\n",(colour_is_black(board->turn))?"black":"white"); - my_log("POLYGLOT\n"); -} - -// end of board.cpp - diff --git a/book.cpp b/book.cpp deleted file mode 100644 index 1dab50a..0000000 --- a/book.cpp +++ /dev/null @@ -1,384 +0,0 @@ - -// book.cpp - -// includes - -#include -#include -#include -#include - -#include "board.h" -#include "book.h" -#include "move.h" -#include "move_legal.h" -#include "san.h" -#include "util.h" -#include "option.h" - -// types - -struct entry_t { - uint64 key; - uint16 move; - uint16 count; - uint16 n; - uint16 sum; -}; - -// variables - -static FILE * BookFile; -static int BookSize; - -// prototypes - -static int find_pos (uint64 key); - -static void read_entry (entry_t * entry, int n); -static void write_entry (const entry_t * entry, int n); - -static uint64 read_integer (FILE * file, int size); -static void write_integer (FILE * file, int size, uint64 n); - -// functions - -// book_clear() - -void book_clear() { - - BookFile = NULL; - BookSize = 0; -} - -bool book_is_open(){ - return BookFile!=NULL; -} - -// book_open() - -void book_open(const char file_name[]) { - - ASSERT(file_name!=NULL); - if(option_get_bool("BookLearn")){ - BookFile = fopen(file_name,"rb+"); - }else{ - BookFile = fopen(file_name,"rb"); - } - -// if (BookFile == NULL) my_fatal("book_open(): can't open file \"%s\": %s\n",file_name,strerror(errno)); - if (BookFile == NULL) return; - - if (fseek(BookFile,0,SEEK_END) == -1) { - my_fatal("book_open(): fseek(): %s\n",strerror(errno)); - } - - BookSize = ftell(BookFile) / 16; -// if (BookSize == 0) my_fatal("book_open(): empty file\n"); - if (BookSize == 0) { - book_close(); - book_clear(); - }; -} - -// book_close() - -void book_close() { - - if(BookFile==NULL) return; - - if (fclose(BookFile) == EOF) { - my_fatal("book_close(): fclose(): %s\n",strerror(errno)); - } -} - -// is_in_book() - -bool is_in_book(const board_t * board) { - - int pos; - entry_t entry[1]; - - if(BookFile==NULL) return false; - - ASSERT(board!=NULL); - - for (pos = find_pos(board->key); pos < BookSize; pos++) { - read_entry(entry,pos); - if (entry->key == board->key) return true; - } - - return false; -} - -// book_move() - -int book_move(const board_t * board, bool random) { - - int best_move; - int best_score; - int pos; - entry_t entry[1]; - int move; - int score; - - if(BookFile==NULL) return MoveNone; - - ASSERT(board!=NULL); - ASSERT(random==true||random==false); - - - best_move = MoveNone; - best_score = 0; - for (pos = find_pos(board->key); pos < BookSize; pos++) { - - read_entry(entry,pos); - if (entry->key != board->key) break; - - move = entry->move; - score = entry->count; - - if (move != MoveNone && move_is_legal(move,board)) { - - // pick this move? - - ASSERT(score>0); - - if (random) { - best_score += score; - if (my_random_int(best_score) < score) best_move = move; - } else { - if (score > best_score) { - best_move = move; - best_score = score; - } - } - - } else { - - ASSERT(false); - } - } - - return best_move; -} - -// book_disp() - -void book_disp(const board_t * board) { - - int first_pos; - int sum; - int pos; - entry_t entry[1]; - int move; - int score; - char move_string[256]; - - ASSERT(board!=NULL); - - if(BookFile==NULL) return; - - first_pos = find_pos(board->key); - - // sum - - sum = 0; - - for (pos = first_pos; pos < BookSize; pos++) { - - read_entry(entry,pos); - if (entry->key != board->key) break; - - sum += entry->count; - } - - // disp - - for (pos = first_pos; pos < BookSize; pos++) { - - read_entry(entry,pos); - if (entry->key != board->key) break; - - move = entry->move; - score = entry->count; - - if (score > 0 && move != MoveNone && move_is_legal(move,board)) { - move_to_san(move,board,move_string,256); - printf(" %s (%.0f%%)\n",move_string,(double(score)/double(sum))*100.0); - } - } - - printf("\n"); -} - -// book_learn_move() - -void book_learn_move(const board_t * board, int move, int result) { - - int pos; - entry_t entry[1]; - - if(BookFile==NULL) return; - - ASSERT(board!=NULL); - ASSERT(move_is_ok(move)); - ASSERT(result>=-1&&result<=+1); - - ASSERT(move_is_legal(move,board)); - - for (pos = find_pos(board->key); pos < BookSize; pos++) { - - read_entry(entry,pos); - if (entry->key != board->key) break; - - if (entry->move == move) { - - entry->n++; - entry->sum += result+1; - - write_entry(entry,pos); - - break; - } - } -} - -// book_flush() - -void book_flush() { - - if(BookFile==NULL) return; - - if (fflush(BookFile) == EOF) { - my_fatal("book_flush(): fflush(): %s\n",strerror(errno)); - } -} - -// find_pos() - -static int find_pos(uint64 key) { - - int left, right, mid; - entry_t entry[1]; - - // binary search (finds the leftmost entry) - - left = 0; - right = BookSize-1; - - ASSERT(left<=right); - - while (left < right) { - - mid = (left + right) / 2; - ASSERT(mid>=left&&midkey) { - right = mid; - } else { - left = mid+1; - } - } - - ASSERT(left==right); - - read_entry(entry,left); - - return (entry->key == key) ? left : BookSize; -} - -// read_entry() - -static void read_entry(entry_t * entry, int n) { - - ASSERT(entry!=NULL); - ASSERT(n>=0&&nkey = read_integer(BookFile,8); - entry->move = read_integer(BookFile,2); - entry->count = read_integer(BookFile,2); - entry->n = read_integer(BookFile,2); - entry->sum = read_integer(BookFile,2); -} - -// write_entry() - -static void write_entry(const entry_t * entry, int n) { - - ASSERT(entry!=NULL); - ASSERT(n>=0&&nkey); - write_integer(BookFile,2,entry->move); - write_integer(BookFile,2,entry->count); - write_integer(BookFile,2,entry->n); - write_integer(BookFile,2,entry->sum); -} - -// read_integer() - -static uint64 read_integer(FILE * file, int size) { - - uint64 n; - int i; - int b; - - ASSERT(file!=NULL); - ASSERT(size>0&&size<=8); - - n = 0; - - for (i = 0; i < size; i++) { - - b = fgetc(file); - - if (b == EOF) { - if (feof(file)) { - my_fatal("read_integer(): fgetc(): EOF reached\n"); - } else { // error - my_fatal("read_integer(): fgetc(): %s\n",strerror(errno)); - } - } - - ASSERT(b>=0&&b<256); - n = (n << 8) | b; - } - - return n; -} - -// write_integer() - -static void write_integer(FILE * file, int size, uint64 n) { - - int i; - int b; - - ASSERT(file!=NULL); - ASSERT(size>0&&size<=8); - ASSERT(size==8||n>>(size*8)==0); - - for (i = size-1; i >= 0; i--) { - - b = (n >> (i*8)) & 0xFF; - ASSERT(b>=0&&b<256); - - if (fputc(b,file) == EOF) { - my_fatal("write_integer(): fputc(): %s\n",strerror(errno)); - } - } -} - -// end of book.cpp - diff --git a/book_make.cpp b/book_make.cpp deleted file mode 100644 index 1b8fe6c..0000000 --- a/book_make.cpp +++ /dev/null @@ -1,1082 +0,0 @@ -// book_make.cpp - -// includes - -#include -#include -#include -#include -#include - -#include "board.h" -#include "book_make.h" -#include "move.h" -#include "move_do.h" -#include "move_gen.h" -#include "move_legal.h" -#include "pgn.h" -#include "san.h" -#include "util.h" - -// constants - -static const int COUNT_MAX = 16384; -static const int StringSize = 4096; - -static const int NIL = -1; - -// defines - -#define opp_search(s) ((s)==BOOK?ALL:BOOK) - -// types - -struct entry_t { - uint64 key; - uint16 move; - uint16 count; -// Unfortunately the minggw32 cross compiler [4.2.1-sjlj (mingw32-2)] -// seems to have a bug with anon structs contained in unions when using -O2. -// See the ASSERT below in "read_entry_file"... -// To be fair this seems to be illegal in C++ -// although it is hard to understand why, and the compiler does not complain -// even with -Wall. -// union { -// struct { - uint16 n; - uint16 sum; -// }; -// struct { - uint8 height; - int line; -// }; - // }; - uint8 colour; -}; - -struct book_t { - int size; - int alloc; - uint32 mask; - entry_t * entry; - sint32 * hash; -}; - -enum search_t { - BOOK, - ALL -}; - -struct info_t { - int height; - int line; - int initial_color; - bool book_trans_only; - bool extended_search; - uint16 moves[1024]; - double probs[1024]; - uint64 keys[1024]; - FILE *output; -}; - - -// variables - -static int MaxPly; -static int MinGame; -static double MinScore; -static bool RemoveWhite, RemoveBlack; -static bool Uniform; -static bool Quiet=false; - -static book_t Book[1]; - -// prototypes - -static void book_clear (); -static void book_insert (const char file_name[]); -static void book_filter (); -static void book_sort (); -static void book_save (const char file_name[]); - -static int find_entry (const board_t * board, int move); -static void resize (); -static void halve_stats (uint64 key); - -static bool keep_entry (int pos); - -static int entry_score (const entry_t * entry); - -static int key_compare (const void * p1, const void * p2); - -static void write_integer (FILE * file, int size, uint64 n); -static uint64 read_integer(FILE * file, int size); - -static void read_entry_file(FILE *f, entry_t *entry); -static void write_entry_file(FILE * f, const entry_t * entry); - -// functions - -// book_make() - -void book_make(int argc, char * argv[]) { - - int i; - const char * pgn_file; - const char * bin_file; - - pgn_file = NULL; - my_string_set(&pgn_file,"book.pgn"); - - bin_file = NULL; - my_string_set(&bin_file,"book.bin"); - - MaxPly = 1024; - MinGame = 3; - MinScore = 0.0; - RemoveWhite = false; - RemoveBlack = false; - Uniform = false; - - for (i = 1; i < argc; i++) { - - if (false) { - - } else if (my_string_equal(argv[i],"make-book")) { - - // skip - - } else if (my_string_equal(argv[i],"-pgn")) { - - i++; - if (argv[i] == NULL) my_fatal("book_make(): missing argument\n"); - - my_string_set(&pgn_file,argv[i]); - - } else if (my_string_equal(argv[i],"-bin")) { - - i++; - if (argv[i] == NULL) my_fatal("book_make(): missing argument\n"); - - my_string_set(&bin_file,argv[i]); - - } else if (my_string_equal(argv[i],"-max-ply")) { - - i++; - if (argv[i] == NULL) my_fatal("book_make(): missing argument\n"); - - MaxPly = atoi(argv[i]); - ASSERT(MaxPly>=0); - - } else if (my_string_equal(argv[i],"-min-game")) { - - i++; - if (argv[i] == NULL) my_fatal("book_make(): missing argument\n"); - - MinGame = atoi(argv[i]); - ASSERT(MinGame>0); - - } else if (my_string_equal(argv[i],"-min-score")) { - - i++; - if (argv[i] == NULL) my_fatal("book_make(): missing argument\n"); - - MinScore = atof(argv[i]) / 100.0; - ASSERT(MinScore>=0.0&&MinScore<=1.0); - - } else if (my_string_equal(argv[i],"-only-white")) { - - RemoveWhite = false; - RemoveBlack = true; - - } else if (my_string_equal(argv[i],"-only-black")) { - - RemoveWhite = true; - RemoveBlack = false; - - } else if (my_string_equal(argv[i],"-uniform")) { - - Uniform = true; - - } else { - - my_fatal("book_make(): unknown option \"%s\"\n",argv[i]); - } - } - - book_clear(); - - printf("inserting games ...\n"); - book_insert(pgn_file); - - printf("filtering entries ...\n"); - book_filter(); - - printf("sorting entries ...\n"); - book_sort(); - - printf("saving entries ...\n"); - book_save(bin_file); - - printf("all done!\n"); -} - -// book_clear() - -static void book_clear() { - - int index; - - Book->alloc = 1; - Book->mask = (Book->alloc * 2) - 1; - - Book->entry = (entry_t *) my_malloc(Book->alloc*sizeof(entry_t)); - Book->size = 0; - - Book->hash = (sint32 *) my_malloc((Book->alloc*2)*sizeof(sint32)); - for (index = 0; index < Book->alloc*2; index++) { - Book->hash[index] = NIL; - } -} - -// book_insert() - -static void book_insert(const char file_name[]) { - - pgn_t pgn[1]; - board_t board[1]; - int ply; - int result; - char string[256]; - int move; - int pos; - - ASSERT(file_name!=NULL); - - // init - - pgn->game_nb=1; - // scan loop - - pgn_open(pgn,file_name); - - while (pgn_next_game(pgn)) { - - board_start(board); - ply = 0; - result = 0; - - if (false) { - } else if (my_string_equal(pgn->result,"1-0")) { - result = +1; - } else if (my_string_equal(pgn->result,"0-1")) { - result = -1; - } - - while (pgn_next_move(pgn,string,256)) { - - if (ply < MaxPly) { - - move = move_from_san(string,board); - - if (move == MoveNone || !move_is_legal(move,board)) { - my_fatal("book_insert(): illegal move \"%s\" at line %d, column %d,game %d\n",string,pgn->move_line,pgn->move_column,pgn->game_nb); - } - - pos = find_entry(board,move); - - Book->entry[pos].n++; - Book->entry[pos].sum += result+1; - - if (Book->entry[pos].n >= COUNT_MAX) { - halve_stats(board->key); - } - - move_do(board,move); - ply++; - result = -result; - } - } - pgn->game_nb++; - if (pgn->game_nb % 10000 == 0) printf("%d games ...\n",pgn->game_nb); - } - - pgn_close(pgn); - - printf("%d game%s.\n",pgn->game_nb,(pgn->game_nb>2)?"s":""); - printf("%d entries.\n",Book->size); - - return; -} - -// book_filter() - -static void book_filter() { - - int src, dst; - - // entry loop - - dst = 0; - - for (src = 0; src < Book->size; src++) { - if (keep_entry(src)) Book->entry[dst++] = Book->entry[src]; - } - - ASSERT(dst>=0&&dst<=Book->size); - Book->size = dst; - - printf("%d entries.\n",Book->size); -} - -// book_sort() - -static void book_sort() { - - // sort keys for binary search - - qsort(Book->entry,Book->size,sizeof(entry_t),&key_compare); -} - -// book_save() - -static void book_save(const char file_name[]) { - - FILE * file; - int pos; - - ASSERT(file_name!=NULL); - - file = fopen(file_name,"wb"); - if (file == NULL) my_fatal("book_save(): can't open file \"%s\" for writing: %s\n",file_name,strerror(errno)); - - // entry loop - - for (pos = 0; pos < Book->size; pos++) { - - ASSERT(keep_entry(pos)); - - write_integer(file,8,Book->entry[pos].key); - write_integer(file,2,Book->entry[pos].move); - write_integer(file,2,entry_score(&Book->entry[pos])); - write_integer(file,2,0); - write_integer(file,2,0); - } - - fclose(file); -} - -// find_entry() - -static int find_entry(const board_t * board, int move) { - - uint64 key; - int index; - int pos; - - ASSERT(board!=NULL); - ASSERT(move==MoveNone || move_is_ok(move)); - - ASSERT(move==MoveNone || move_is_legal(move,board)); - - // init - - key = board->key; - - // search - - for (index = key & (uint64) Book->mask; (pos=Book->hash[index]) != NIL; index = (index+1) & Book->mask) { - - ASSERT(pos>=0&&possize); - - if (Book->entry[pos].key == key && Book->entry[pos].move == move) { - return pos; // found - } - } - - // not found - - ASSERT(Book->size<=Book->alloc); - - if (Book->size == Book->alloc) { - - // allocate more memory - - resize(); - - for (index = key & (uint64) Book->mask; Book->hash[index] != NIL; index = (index+1) & Book->mask) - ; - } - - // create a new entry - - ASSERT(Book->sizealloc); - pos = Book->size++; - - Book->entry[pos].key = key; - Book->entry[pos].move = move; - Book->entry[pos].n = 0; - Book->entry[pos].sum = 0; - Book->entry[pos].colour = board->turn; - - // insert into the hash table - - ASSERT(index>=0&&indexalloc*2); - ASSERT(Book->hash[index]==NIL); - Book->hash[index] = pos; - - ASSERT(pos>=0&&possize); - - return pos; -} - -// rebuild_hash_table - -static void rebuild_hash_table(){ - int index,pos; - for (index = 0; index < Book->alloc*2; index++) { - Book->hash[index] = NIL; - } - for (pos = 0; pos < Book->size; pos++) { - for (index = Book->entry[pos].key & (uint64) Book->mask; Book->hash[index] != NIL; index = (index+1) & Book->mask) - ; - ASSERT(index>=0&&indexalloc*2); - Book->hash[index] = pos; - } -} - -static void resize() { - - int size; - - ASSERT(Book->size==Book->alloc); - - Book->alloc *= 2; - Book->mask = (Book->alloc * 2) - 1; - - size = 0; - size += Book->alloc * sizeof(entry_t); - size += (Book->alloc*2) * sizeof(sint32); - - if (size >= 1048576) if(!Quiet){printf("allocating %gMB ...\n",double(size)/1048576.0);} - - // resize arrays - - Book->entry = (entry_t *) my_realloc(Book->entry,Book->alloc*sizeof(entry_t)); - Book->hash = (sint32 *) my_realloc(Book->hash,(Book->alloc*2)*sizeof(sint32)); - - // rebuild hash table - - rebuild_hash_table(); -} - - -// halve_stats() - -static void halve_stats(uint64 key) { - - int index; - int pos; - - // search - - for (index = key & (uint64) Book->mask; (pos=Book->hash[index]) != NIL; index = (index+1) & Book->mask) { - - ASSERT(pos>=0&&possize); - - if (Book->entry[pos].key == key) { - Book->entry[pos].n = (Book->entry[pos].n + 1) / 2; - Book->entry[pos].sum = (Book->entry[pos].sum + 1) / 2; - } - } -} - -// keep_entry() - -static bool keep_entry(int pos) { - - const entry_t * entry; - int colour; - double score; - - ASSERT(pos>=0&&possize); - - entry = &Book->entry[pos]; - - // if (entry->n == 0) return false; - if (entry->n < MinGame) return false; - - if (entry->sum == 0) return false; - - score = (double(entry->sum) / double(entry->n)) / 2.0; - ASSERT(score>=0.0&&score<=1.0); - - if (score < MinScore) return false; - - colour = entry->colour; - - if ((RemoveWhite && colour_is_white(colour)) - || (RemoveBlack && colour_is_black(colour))) { - return false; - } - - if (entry_score(entry) == 0) return false; // REMOVE ME? - - return true; -} - -// entry_score() - -static int entry_score(const entry_t * entry) { - - int score; - - ASSERT(entry!=NULL); - - // score = entry->n; // popularity - score = entry->sum; // "expectancy" - - if (Uniform) score = 1; - - ASSERT(score>=0); - - return score; -} - -// key_compare() - -static int key_compare(const void * p1, const void * p2) { - - const entry_t * entry_1, * entry_2; - - ASSERT(p1!=NULL); - ASSERT(p2!=NULL); - - entry_1 = (const entry_t *) p1; - entry_2 = (const entry_t *) p2; - - if (entry_1->key > entry_2->key) { - return +1; - } else if (entry_1->key < entry_2->key) { - return -1; - } else { - return entry_score(entry_2) - entry_score(entry_1); // highest score first - } -} - -// write_integer() - -static void write_integer(FILE * file, int size, uint64 n) { - - int i; - int b; - - ASSERT(file!=NULL); - ASSERT(size>0&&size<=8); - ASSERT(size==8||n>>(size*8)==0); - - for (i = size-1; i >= 0; i--) { - b = (n >> (i*8)) & 0xFF; - ASSERT(b>=0&&b<256); - fputc(b,file); - } -} - -// read_integer() - -static uint64 read_integer(FILE * file, int size) { - uint64 n; - int i; - int b; - ASSERT(file!=NULL); - ASSERT(size>0&&size<=8); - n = 0; - for (i = 0; i < size; i++) { - b = fgetc(file); - if (b == EOF) { - if (feof(file)) { - my_fatal("read_integer(): fgetc(): EOF reached\n"); - } else { // error - my_fatal("read_integer(): fgetc(): %s\n",strerror(errno)); - } - } - ASSERT(b>=0&&b<256); - n = (n << 8) | b; - } - return n; -} - -// read_entry_file - -static void read_entry_file(FILE *f, entry_t *entry){ - uint64 n; - ASSERT(entry!=NULL); - n = entry->key = read_integer(f,8); - entry->move = read_integer(f,2); - entry->count = read_integer(f,2); - entry->n = read_integer(f,2); - entry->sum = read_integer(f,2); - ASSERT(n==entry->key); // test for mingw compiler bug with anon structs -} - -// write_entry_file - -static void write_entry_file(FILE * f, const entry_t * entry) { - ASSERT(entry!=NULL); - write_integer(f,8,entry->key); - write_integer(f,2,entry->move); - write_integer(f,2,entry->count); - write_integer(f,2,entry->n); - write_integer(f,2,entry->sum); -} - -static void print_list(const board_t *board, list_t *list){ - int i; - uint16 move; - char move_string[256]; - for (i = 0; i < list_size(list); i++) { - move = list_move(list,i); - move_to_san(move,board,move_string,256); - printf("%s",move_string); - } - printf("\n"); -} - -// book_load() -// loads a polyglot book - -static void book_load(const char filename[]){ - FILE* f; - entry_t entry[1]; - int size; - int i; - int pos; - int index; - ASSERT(filename!=NULL); - if(!(f=fopen(filename,"rb"))){ - my_fatal("book_load() : can't open file \"%s\" for reading: %s\n",filename,strerror(errno)); - } - fseek(f,0L,SEEK_END); // superportable way to get size of book! - size=ftell(f)/16; - fseek(f,0,SEEK_SET); - for(i=0L;isize<=Book->alloc); - if (Book->size == Book->alloc) { - // allocate more memoryx - resize(); - } - // insert into the book - pos = Book->size++; - Book->entry[pos].key = entry->key; - ASSERT(entry->move!=MoveNone); - Book->entry[pos].move = entry->move; - Book->entry[pos].count = entry->count; - Book->entry[pos].n = entry->n; - Book->entry[pos].sum = entry->sum; - Book->entry[pos].colour = ColourNone; - // find free hash table spot - for (index = entry->key & (uint64) Book->mask; - Book->hash[index] != NIL; - index = (index+1) & Book->mask); - // insert into the hash table - ASSERT(index>=0&&indexalloc*2); - ASSERT(Book->hash[index]==NIL); - Book->hash[index] = pos; - ASSERT(pos>=0&&possize); - } - fclose(f); -} - -// gen_book_moves() -// similar signature as gen_legal_moves -static int gen_book_moves(list_t * list, const board_t * board){ - int first_pos, pos, index; - entry_t entry[1]; - list_clear(list); - bool found; - found=FALSE; - for (index = board->key & (uint64) Book->mask; (first_pos=Book->hash[index]) != NIL; index = (index+1) & Book->mask) { - ASSERT(first_pos>=0&&first_possize); - if (Book->entry[first_pos].key == board->key) { - found=TRUE; - break; // found - } - } - if(!found) return -1; - if(Book->entry[first_pos].move==MoveNone) return -1; - for (pos = first_pos; pos < Book->size; pos++) { - *entry=Book->entry[pos]; - if (entry->key != board->key) break; - if (entry->count > 0 && - entry->move != MoveNone && - move_is_legal(entry->move,board)) { - list_add(list,entry->move,entry->count); - } - } - return first_pos; -} - -// gen_opp_book_moves() -// moves to which opponent has a reply in book -// similar signature as gen_legal_moves -static void gen_opp_book_moves(list_t * list, const board_t * board){ - int move; - list_t new_list[1], legal_moves[1]; - board_t new_board[1]; - int i; - list_clear(list); - gen_legal_moves(legal_moves,board); - for (i = 0; i < list_size(legal_moves); i++) { - move = list_move(legal_moves,i); - // scratch_board - memcpy(new_board, board, sizeof(board_t)); - move_do(new_board,move); - gen_book_moves(new_list,new_board); // wasteful in time but tested! - if(list_size(new_list)!=0){ - list_add(list,move); - } - } -} - -static void print_moves(info_t *info){ - board_t board[1]; - char move_string[256]; - int i; - int color=White; - if(!info->output){ - return; - } - board_start(board); - for(i=0;iheight;i++){ - if(color==White){ - fprintf(info->output,"%d. ",i/2+1); - color=Black; - }else{ - color=White; - } - move_to_san(info->moves[i],board,move_string,256); - fprintf(info->output,"%s", move_string); - if(color==colour_opp(info->initial_color)){ - fprintf(info->output,"{%.0f%%} ",100*info->probs[i]); - }else{ - fprintf(info->output," "); - } - move_do(board,info->moves[i]); - } -} - -static int search_book(board_t *board, info_t *info, search_t search){ - list_t list[1]; - board_t new_board[1]; - uint16 move; - int count; - int ret; - int i; - int offset; - int pos; - int size; - int prob_sum; - double probs[256]; - for(i=0;i<256;i++){ - probs[i]=0.0; // kill compiler warnings - } - for(i=0;iheight;i++){ - if(board->key==info->keys[i]){ - if(info->output){ - fprintf(info->output,"%d: ",info->line); - print_moves(info); - fprintf(info->output,"{cycle: ply=%d}\n",i); - } - info->line++; - return 1; // end of line because of cycle - } - } - if(!info->book_trans_only || (info->book_trans_only && search==BOOK)){ - info->keys[info->height]=board->key; - size=Book->size; // hack - pos=find_entry(board,MoveNone); - if(size==Book->size){ - if(info->output){ - fprintf(info->output,"%d: ",info->line); - print_moves(info); - fprintf(info->output,"{trans: line=%d, ply=%d}\n", - Book->entry[pos].line, - Book->entry[pos].height); - } - info->line++; - return 1; // end of line because of transposition - }else{ - Book->entry[pos].height=info->height; - Book->entry[pos].line=info->line; - } - } - count=0; - if(search==BOOK){ - offset=gen_book_moves(list,board); - if(info->extended_search){ - gen_legal_moves(list,board); - } -// ASSERT(offset!=-1); - if(offset!=-1){ // only false in starting position for black book - Book->entry[offset].colour=board->turn; - prob_sum=0; - if(!info->extended_search){ - for(i=0;imoves[info->height++]=move; - if(search==BOOK){ - info->probs[info->height-1]=probs[i]; - } - ret=search_book(new_board, info, opp_search(search)); - if(ret==0 && search==BOOK){ - if(info->output){ - fprintf(info->output,"%d: ",info->line); - print_moves(info); - fprintf(info->output,"\n"); - } - info->line++; - ret=1; // end of line book move counts for 1 - } - info->height--; - ASSERT(info->height>=0); - count+=ret; - } - return count; -} - -void init_info(info_t *info){ - info->line=1; - info->height=0; - info->output=NULL; - info->initial_color=White; - info->book_trans_only=FALSE; -} - -// book_clean() -// remove MoveNone entries from book and rebuild hash table -void book_clean(){ - int read_ptr,write_ptr; - write_ptr=0; - for(read_ptr=0;read_ptrsize;read_ptr++){ - if(Book->entry[read_ptr].move!=MoveNone){ - Book->entry[write_ptr++]=Book->entry[read_ptr]; - } - } - Book->size=write_ptr; - rebuild_hash_table(); -} - -// book_dump() - -void book_dump(int argc, char * argv[]) { - const char * bin_file=NULL; - const char * txt_file=NULL; - char string[StringSize]; - int color=ColourNone; - board_t board[1]; - info_t info[1]; - int i; - FILE *f; - my_string_set(&bin_file,"book.bin"); - for (i = 1; i < argc; i++) { - if (false) { - } else if (my_string_equal(argv[i],"dump-book")) { - // skip - } else if (my_string_equal(argv[i],"-bin")) { - i++; - if (i==argc) my_fatal("book_dump(): missing argument\n"); - my_string_set(&bin_file,argv[i]); - } else if (my_string_equal(argv[i],"-out")) { - i++; - if (i==argc) my_fatal("book_dump(): missing argument\n"); - my_string_set(&txt_file,argv[i]); - } else if (my_string_equal(argv[i],"-color") || my_string_equal(argv[i],"-colour")) { - i++; - if (i == argc) my_fatal("book_dump(): missing argument\n"); - if(my_string_equal(argv[i],"white")){ - color=White; - }else if (my_string_equal(argv[i],"black")){ - color=Black; - }else{ - my_fatal("book_dump(): unknown color \"%s\"\n",argv[i]); - } - } else { - my_fatal("book_dump(): unknown option \"%s\"\n",argv[i]); - } - } - if(color==ColourNone){ - my_fatal("book_dump(): you must specify a color\n"); - } - if(txt_file==NULL){ - snprintf(string,StringSize,"book_%s.txt",color?"white":"black"); - my_string_set(&txt_file,string); - } - - book_clear(); - if(!Quiet){printf("loading book ...\n");} - book_load(bin_file); - board_start(board); - init_info(info); - info->initial_color=color; - if(!(f=fopen(txt_file,"w"))){ - my_fatal("book_dump(): can't open file \"%s\" for writing: %s", - txt_file,strerror(errno)); - } - info->output=f; - fprintf(info->output,"Dump of \"%s\" for %s.\n", - bin_file,color==White?"white":"black"); - if(color==White){ - if(!Quiet){printf("generating lines for white...\n");} - search_book(board,info, BOOK); - }else{ - if(!Quiet){printf("generating lines for black...\n");} - search_book(board,info, ALL); - } -} - -// book_info() - -void book_info(int argc,char* argv[]){ - const char *bin_file=NULL; - board_t board[1]; - info_t info[1]; - uint64 last_key; - int pos; - int white_pos,black_pos,total_pos,white_pos_extended, - black_pos_extended,white_pos_extended_diff,black_pos_extended_diff; - int s; - bool extended_search=FALSE; - int i; - Quiet=TRUE; - my_string_set(&bin_file,"book.bin"); - - for (i = 1; i < argc; i++) { - if (false) { - } else if (my_string_equal(argv[i],"info-book")) { - // skip - } else if (my_string_equal(argv[i],"-bin")) { - i++; - if (i==argc) my_fatal("book_info(): missing argument\n"); - my_string_set(&bin_file,argv[i]); - } else if (my_string_equal(argv[i],"-exact")) { - extended_search=TRUE; - } else { - my_fatal("book_info(): unknown option \"%s\"\n",argv[i]); - } - } - book_clear(); - if(!Quiet){printf("loading book ...\n");} - book_load(bin_file); - s=Book->size; - - board_start(board); - init_info(info); - info->book_trans_only=FALSE; - info->initial_color=White; - info->extended_search=FALSE; - search_book(board,info, BOOK); - printf("Lines for white : %8d\n",info->line-1); - - - info->line=1; - info->height=0; - info->initial_color=Black; - book_clean(); - ASSERT(Book->size==s); - board_start(board); - search_book(board,info, ALL); - printf("Lines for black : %8d\n",info->line-1); - - book_clean(); - ASSERT(Book->size==s); - white_pos=0; - black_pos=0; - total_pos=0; - last_key=0; - for(pos=0;possize;pos++){ - if(Book->entry[pos].key==last_key){ - ASSERT(Book->entry[pos].colour==ColourNone); - continue; - } - last_key=Book->entry[pos].key; - total_pos++; - if(Book->entry[pos].colour==White){ - white_pos++; - }else if(Book->entry[pos].colour==Black){ - black_pos++; - } - } - printf("Positions on lines for white : %8d\n",white_pos); - printf("Positions on lines for black : %8d\n",black_pos); - - - if(extended_search){ - init_info(info); - info->book_trans_only=TRUE; - info->initial_color=White; - info->extended_search=TRUE; - book_clean(); - board_start(board); - search_book(board,info, BOOK); - - init_info(info); - info->book_trans_only=TRUE; - info->initial_color=Black; - info->extended_search=TRUE; - book_clean(); - board_start(board); - search_book(board,info, ALL); - book_clean(); - ASSERT(Book->size==s); - white_pos_extended=0; - black_pos_extended=0; - last_key=0; - for(pos=0;possize;pos++){ - if(Book->entry[pos].key==last_key){ - ASSERT(Book->entry[pos].colour==ColourNone); - continue; - } - last_key=Book->entry[pos].key; - if(Book->entry[pos].colour==White){ - white_pos_extended++; - }else if(Book->entry[pos].colour==Black){ - black_pos_extended++; - } - } - white_pos_extended_diff=white_pos_extended-white_pos; - black_pos_extended_diff=black_pos_extended-black_pos; - printf("Unreachable white positions(?) : %8d\n", - white_pos_extended_diff); - printf("Unreachable black positions(?) : %8d\n", - black_pos_extended_diff); - - } - if(extended_search){ - printf("Isolated positions : %8d\n", - total_pos-white_pos_extended-black_pos_extended); - }else{ - printf("Isolated positions : %8d\n", - total_pos-white_pos-black_pos); - } -} - - - -// end of book_make.cpp - diff --git a/book_merge.cpp b/book_merge.cpp deleted file mode 100644 index 6d9c847..0000000 --- a/book_merge.cpp +++ /dev/null @@ -1,304 +0,0 @@ - -// book_merge.cpp - -// includes - -#include -#include -#include -#include - -#include "book_merge.h" -#include "util.h" - -// types - -struct book_t { - FILE * file; - int size; -}; - -struct entry_t { - uint64 key; - uint16 move; - uint16 count; - uint16 n; - uint16 sum; -}; - -// variables - -static book_t In1[1]; -static book_t In2[1]; -static book_t Out[1]; - -// prototypes - -static void book_clear (book_t * book); - -static void book_open (book_t * book, const char file_name[], const char mode[]); -static void book_close (book_t * book); - -static bool read_entry (book_t * book, entry_t * entry, int n); -static void write_entry (book_t * book, const entry_t * entry); - -static uint64 read_integer (FILE * file, int size); -static void write_integer (FILE * file, int size, uint64 n); - -// functions - -// book_merge() - -void book_merge(int argc, char * argv[]) { - - int i; - const char * in_file_1; - const char * in_file_2; - const char * out_file; - int i1, i2; - bool b1, b2; - entry_t e1[1], e2[1]; - int skip; - - in_file_1 = NULL; - my_string_clear(&in_file_1); - - in_file_2 = NULL; - my_string_clear(&in_file_2); - - out_file = NULL; - my_string_set(&out_file,"out.bin"); - - for (i = 1; i < argc; i++) { - - if (false) { - - } else if (my_string_equal(argv[i],"merge-book")) { - - // skip - - } else if (my_string_equal(argv[i],"-in1")) { - - i++; - if (argv[i] == NULL) my_fatal("book_merge(): missing argument\n"); - - my_string_set(&in_file_1,argv[i]); - - } else if (my_string_equal(argv[i],"-in2")) { - - i++; - if (argv[i] == NULL) my_fatal("book_merge(): missing argument\n"); - - my_string_set(&in_file_2,argv[i]); - - } else if (my_string_equal(argv[i],"-out")) { - - i++; - if (argv[i] == NULL) my_fatal("book_merge(): missing argument\n"); - - my_string_set(&out_file,argv[i]); - - } else { - - my_fatal("book_merge(): unknown option \"%s\"\n",argv[i]); - } - } - - book_clear(In1); - book_clear(In2); - book_clear(Out); - - book_open(In1,in_file_1,"rb"); - book_open(In2,in_file_2,"rb"); - book_open(Out,out_file,"wb"); - - skip = 0; - - i1 = 0; - i2 = 0; - - while (true) { - - b1 = read_entry(In1,e1,i1); - b2 = read_entry(In2,e2,i2); - - if (false) { - - } else if (!b1 && !b2) { - - break; - - } else if (b1 && !b2) { - - write_entry(Out,e1); - i1++; - - } else if (b2 && !b1) { - - write_entry(Out,e2); - i2++; - - } else { - - ASSERT(b1); - ASSERT(b2); - - if (false) { - } else if (e1->key < e2->key) { - write_entry(Out,e1); - i1++; - } else if (e1->key > e2->key) { - write_entry(Out,e2); - i2++; - } else { - ASSERT(e1->key==e2->key); - skip++; - i2++; - } - } - } - - book_close(In1); - book_close(In2); - book_close(Out); - - if (skip != 0) { - printf("skipped %d entr%s.\n",skip,(skip>1)?"ies":"y"); - } - - printf("done!\n"); -} - -// book_clear() - -static void book_clear(book_t * book) { - - ASSERT(book!=NULL); - - book->file = NULL; - book->size = 0; -} - -// book_open() - -static void book_open(book_t * book, const char file_name[], const char mode[]) { - - ASSERT(book!=NULL); - ASSERT(file_name!=NULL); - ASSERT(mode!=NULL); - - book->file = fopen(file_name,mode); - if (book->file == NULL) my_fatal("book_open(): can't open file \"%s\": %s\n",file_name,strerror(errno)); - - if (fseek(book->file,0,SEEK_END) == -1) { - my_fatal("book_open(): fseek(): %s\n",strerror(errno)); - } - - book->size = ftell(book->file) / 16; -} - -// book_close() - -static void book_close(book_t * book) { - - ASSERT(book!=NULL); - - if (fclose(book->file) == EOF) { - my_fatal("book_close(): fclose(): %s\n",strerror(errno)); - } -} - -// read_entry() - -static bool read_entry(book_t * book, entry_t * entry, int n) { - - ASSERT(book!=NULL); - ASSERT(entry!=NULL); - - if (n < 0 || n >= book->size) return false; - - ASSERT(n>=0&&nsize); - - if (fseek(book->file,n*16,SEEK_SET) == -1) { - my_fatal("read_entry(): fseek(): %s\n",strerror(errno)); - } - - entry->key = read_integer(book->file,8); - entry->move = read_integer(book->file,2); - entry->count = read_integer(book->file,2); - entry->n = read_integer(book->file,2); - entry->sum = read_integer(book->file,2); - - return true; -} - -// write_entry() - -static void write_entry(book_t * book, const entry_t * entry) { - - ASSERT(book!=NULL); - ASSERT(entry!=NULL); - - write_integer(book->file,8,entry->key); - write_integer(book->file,2,entry->move); - write_integer(book->file,2,entry->count); - write_integer(book->file,2,entry->n); - write_integer(book->file,2,entry->sum); -} - -// read_integer() - -static uint64 read_integer(FILE * file, int size) { - - uint64 n; - int i; - int b; - - ASSERT(file!=NULL); - ASSERT(size>0&&size<=8); - - n = 0; - - for (i = 0; i < size; i++) { - - b = fgetc(file); - - if (b == EOF) { - if (feof(file)) { - my_fatal("read_integer(): fgetc(): EOF reached\n"); - } else { // error - my_fatal("read_integer(): fgetc(): %s\n",strerror(errno)); - } - } - - ASSERT(b>=0&&b<256); - n = (n << 8) | b; - } - - return n; -} - -// write_integer() - -static void write_integer(FILE * file, int size, uint64 n) { - - int i; - int b; - - ASSERT(file!=NULL); - ASSERT(size>0&&size<=8); - ASSERT(size==8||n>>(size*8)==0); - - for (i = size-1; i >= 0; i--) { - - b = (n >> (i*8)) & 0xFF; - ASSERT(b>=0&&b<256); - - if (fputc(b,file) == EOF) { - my_fatal("write_integer(): fputc(): %s\n",strerror(errno)); - } - } -} - -// end of book_merge.cpp - diff --git a/colour.cpp b/colour.cpp deleted file mode 100644 index 42b12b2..0000000 --- a/colour.cpp +++ /dev/null @@ -1,55 +0,0 @@ - -// colour.cpp - -// includes - -#include "colour.h" -#include "util.h" - -// functions - -// colour_is_ok() - -bool colour_is_ok(int colour) { - - return colour == Black || colour == White; -} - -// colour_is_white() - -bool colour_is_white(int colour) { - - ASSERT(colour_is_ok(colour)); - - return colour == White; -} - -// colour_is_black() - -bool colour_is_black(int colour) { - - ASSERT(colour_is_ok(colour)); - - return colour == Black; -} - -// colour_equal() - -bool colour_equal(int colour_1, int colour_2) { - - ASSERT(colour_is_ok(colour_2)); - - return (colour_1 & colour_2) != 0; -} - -// colour_opp() - -int colour_opp(int colour) { - - ASSERT(colour_is_ok(colour)); - - return colour ^ (BlackFlag^WhiteFlag); -} - -// end of colour.cpp - diff --git a/engine.cpp b/engine.cpp deleted file mode 100644 index f86f0fb..0000000 --- a/engine.cpp +++ /dev/null @@ -1,442 +0,0 @@ -#ifndef _WIN32 - -// engine.cpp - -// includes - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "engine.h" -#include "io.h" -#include "option.h" -#include "util.h" - - -// constants - -static const unsigned int StringSize = 4096; - -// variables - -engine_t Engine[1]; - -// prototypes - -static void my_close (int fd); -static void my_dup2 (int old_fd, int new_fd); - -// functions - -// engine_is_ok() - -bool engine_is_ok(const engine_t * engine) { - - if (engine == NULL) return false; - - if (!io_is_ok(engine->io)) return false; - - return true; -} - -// engine_open() - -void engine_open(engine_t * engine) { - - const char * dir, * command; - char string[StringSize]; - int argc; - char * ptr; - char * argv[256]; - int from_engine[2], to_engine[2]; - pid_t pid; - - ASSERT(engine!=NULL); - - // init - - dir = option_get_string("EngineDir"); - my_log("POLYGLOT Dir \"%s\"\n",dir); - - command = option_get_string("EngineCommand"); - my_log("POLYGLOT Command \"%s\"\n",command); - - // parse the command line and create the argument list - - if (strlen(command) >= StringSize) my_fatal("engine_open(): buffer overflow\n"); - strcpy(string,command); - - argc = 0; - - for (ptr = strtok(string," "); ptr != NULL; ptr = strtok(NULL," ")) { - argv[argc++] = ptr; - } - - argv[argc] = NULL; - - // create the pipes - - if (pipe(from_engine) == -1) { - my_fatal("engine_open(): pipe(): %s\n",strerror(errno)); - } - - if (pipe(to_engine) == -1) { - my_fatal("engine_open(): pipe(): %s\n",strerror(errno)); - } - - // create the child process - - pid = fork(); - - if (pid == -1) { - - my_fatal("engine_open(): fork(): %s\n",strerror(errno)); - - } else if (pid == 0) { - - // child = engine - - // close unused pipe descriptors to avoid deadlocks - - my_close(from_engine[0]); - my_close(to_engine[1]); - - // attach the pipe to standard input - - my_dup2(to_engine[0],STDIN_FILENO); - my_close(to_engine[0]); - - // attach the pipe to standard output - - my_dup2(from_engine[1],STDOUT_FILENO); - my_close(from_engine[1]); - - // attach standard error to standard output - - my_dup2(STDOUT_FILENO,STDERR_FILENO); - - // set a low priority - - if (option_get_bool("UseNice")) { - my_log("POLYGLOT Adjust Engine Piority"); - nice(option_get_int("NiceValue")); - } - - // change the current directory - - if (dir[0] != '\0' && chdir(dir) == -1) { - my_fatal("engine_open(): chdir(): %s\n",strerror(errno)); - } - - // launch the new executable file - - execvp(argv[0],&argv[0]); - - // execvp() only returns when an error has occured - - my_fatal("engine_open(): execvp(): %s\n",strerror(errno)); - - } else { // pid > 0 - - ASSERT(pid>0); - - // parent = PolyGlot - - // close unused pipe descriptors to avoid deadlocks - - my_close(from_engine[1]); - my_close(to_engine[0]); - - // fill in the engine struct - - engine->io->in_fd = from_engine[0]; - engine->io->out_fd = to_engine[1]; - engine->io->name = "Engine"; - engine->pid=pid; - engine->state|=ENGINE_ACTIVE; // can we test if this really true? - - io_init(engine->io); - } -} - -// engine_active - -bool engine_active(engine_t *engine){ - return (engine->state & ENGINE_ACTIVE)!=0; -} - -// engine_eof - -bool engine_eof(engine_t *engine){ - return (engine->state & ENGINE_EOF)!=0; -} - -// engine_set_nice_value() - -void engine_set_nice_value(engine_t * engine, int value){ - setpriority(PRIO_PROCESS,engine->pid,value); -} - - -// engine_close() - -void engine_close(engine_t * engine) { - - ASSERT(engine_is_ok(engine)); - - char string[StringSize]; - io_close(engine->io); - // TODO: timeout - while (!engine_eof(engine)) { - engine_get(engine,string,StringSize); - } - -} - -// engine_get_non_blocking() - -bool engine_get_non_blocking(engine_t * engine, char string[], int size){ - if(io_line_ready(engine->io)){ - engine_get(engine,string,StringSize); - return true; - }else{ - string[0]='\0'; - return false; - } -} - -// engine_get() - -void engine_get(engine_t * engine, char string[], int size) { - - ASSERT(engine_is_ok(engine)); - ASSERT(string!=NULL); - ASSERT(size>=256); - - while (!io_line_ready(engine->io)) { - io_get_update(engine->io); - } - - if (!io_get_line(engine->io,string,size)) { // EOF - engine->state|=ENGINE_EOF; - } -} - -// engine_send() - -void engine_send(engine_t * engine, const char format[], ...) { - - va_list arg_list; - char string[StringSize]; - - ASSERT(engine_is_ok(engine)); - ASSERT(format!=NULL); - - // format - - va_start(arg_list,format); - vsprintf(string,format,arg_list); - va_end(arg_list); - - // send - - io_send(engine->io,"%s",string); -} - -// engine_send_queue() - -void engine_send_queue(engine_t * engine, const char format[], ...) { - - va_list arg_list; - char string[StringSize]; - - ASSERT(engine_is_ok(engine)); - ASSERT(format!=NULL); - - // format - - va_start(arg_list,format); - vsprintf(string,format,arg_list); - va_end(arg_list); - - // send - - io_send_queue(engine->io,"%s",string); -} - -// my_close() - -static void my_close(int fd) { - - ASSERT(fd>=0); - - if (close(fd) == -1) my_fatal("my_close(): close(): %s\n",strerror(errno)); -} - -// my_dup2() - -static void my_dup2(int old_fd, int new_fd) { - - ASSERT(old_fd>=0); - ASSERT(new_fd>=0); - - if (dup2(old_fd,new_fd) == -1) my_fatal("my_dup2(): dup2(): %s\n",strerror(errno)); -} - -// end of posix part -#else - -// WIN32 part - -// includes - -#include -#include -#include -#include - - - -#include "engine.h" -#include "option.h" -#include "pipe.h" -#include "posix.h" - -// constants - -static const int StringSize = 4096; - -// variables - -static int nQueuePtr = 0; -static char szQueueString[StringSize]; -engine_t Engine[1]; - -// functions - -void set_affinity(engine_t *engine, int affin){ - if(affin==-1) return; - - typedef void (WINAPI *SPAM)(HANDLE, int); - SPAM pSPAM; - pSPAM = (SPAM) GetProcAddress( - GetModuleHandle(TEXT("kernel32.dll")), - "SetProcessAffinityMask"); - if(NULL != pSPAM){ - // [HGM] avoid crash on Win95 by first checking if API call exists - my_log("POLYGLOT Setting process affinity to %d\n",affin); - pSPAM((engine->io).hProcess,affin); - }else{ - my_log("POLYGLOT API call \"SetProcessAffinityMask\" not available\n"); - } -} - -DWORD GetWin32Priority(int nice) -{ -/* -REALTIME_PRIORITY_CLASS 0x00000100 -HIGH_PRIORITY_CLASS 0x00000080 -ABOVE_NORMAL_PRIORITY_CLASS 0x00008000 -NORMAL_PRIORITY_CLASS 0x00000020 -BELOW_NORMAL_PRIORITY_CLASS 0x00004000 -IDLE_PRIORITY_CLASS 0x00000040 -*/ - if (nice < -15) return 0x00000080; - if (nice < 0) return 0x00008000; - if (nice == 0) return 0x00000020; - if (nice < 15) return 0x00004000; - return 0x00000040; -} - -void engine_set_nice_value(engine_t *engine, int value){ - SetPriorityClass((engine->io).hProcess, - GetWin32Priority(value)); -} - -void engine_send_queue(engine_t * engine,const char *szFormat, ...) { - nQueuePtr += vsprintf(szQueueString + nQueuePtr, szFormat, (va_list) (&szFormat + 1)); -} - -void engine_send(engine_t * engine, const char *szFormat, ...) { - vsprintf(szQueueString + nQueuePtr, szFormat, (va_list) (&szFormat + 1)); - (engine->io).LineOutput(szQueueString); - my_log("Adapter->Engine: %s\n",szQueueString); - nQueuePtr = 0; -} - -void engine_close(engine_t * engine){ - char string[StringSize]; - (engine->io).Close(); - // TODO: Timeout - while (!engine_eof(engine)) { - engine_get(Engine,string,StringSize); - } - (engine->io).Kill(); -} - -void engine_open(engine_t * engine){ - int affinity; - char *my_dir; - engine->state=0; - if( (my_dir = _getcwd( NULL, 0 )) == NULL ) - my_fatal("Can't build path: %s\n",strerror(errno)); - SetCurrentDirectory(option_get_string("EngineDir")); - (engine->io).Open(option_get_string("EngineCommand")); - if((engine->io).Active()){ - engine->state|=ENGINE_ACTIVE; - //play with affinity (bad idea) - affinity=option_get_int("Affinity"); - if(affinity!=-1) set_affinity(engine,affinity); //AAA - //lets go back - SetCurrentDirectory(my_dir); - // set a low priority - if (option_get_bool("UseNice")){ - my_log("POLYGLOT Adjust Engine Piority\n"); - engine_set_nice_value(engine, option_get_int("NiceValue")); - } - } - -} - -bool engine_active(engine_t *engine){ - return (engine->state & ENGINE_ACTIVE)!=0; -} - -bool engine_eof(engine_t *engine){ - return (engine->state & ENGINE_EOF)!=0; -} - -bool engine_get_non_blocking(engine_t * engine, char *szLineStr, int size){ - if(engine_eof(engine)){ return false;} - if ((engine->io).GetBuffer(szLineStr)) { - my_log("Engine->Adapter: %s\n",szLineStr); - return true; - } else { - szLineStr[0]='\0'; - if(engine->io.EOF_()){ - engine->state|=ENGINE_EOF; - my_log("POLYGLOT *** EOF from Engine ***\n"); - } - return false; - } -} - -void engine_get(engine_t * engine, char *szLineStr, int size){ - (engine->io).LineInput(szLineStr); - if(engine->io.EOF_()){ - engine->state|=ENGINE_EOF; - my_log("POLYGLOT *** EOF from Engine ***\n"); - }else{ - my_log("Engine->Adapter: %s\n",szLineStr); - } -} - - -#endif diff --git a/epd.cpp b/epd.cpp deleted file mode 100644 index fab728a..0000000 --- a/epd.cpp +++ /dev/null @@ -1,444 +0,0 @@ - -// epd.cpp - -// includes - -#include -#include -#include -#include - -#include "board.h" -#include "engine.h" -#include "epd.h" -#include "fen.h" -#include "line.h" -#include "main.h" -#include "move.h" -#include "move_legal.h" -#include "option.h" -#include "parse.h" -#include "san.h" -#include "uci.h" -#include "util.h" - -// constants - -static const bool UseDebug = false; -static const bool UseTrace = false; - -static const int StringSize = 4096; - -// variables - -static int MinDepth; -static int MaxDepth; - -static double MaxTime; -static double MinTime; - -static int DepthDelta; - -static int FirstMove; -static int FirstDepth; -static int FirstSelDepth; -static int FirstScore; -static double FirstTime; -static uint64 FirstNodeNb; -static move_t FirstPV[LineSize]; - -static int LastMove; -static int LastDepth; -static int LastSelDepth; -static int LastScore; -static double LastTime; -static uint64 LastNodeNb; -static move_t LastPV[LineSize]; - -static my_timer_t Timer[1]; - -// prototypes - -static void epd_test_file (const char file_name[]); - -static bool is_solution (int move, const board_t * board, const char bm[], const char am[]); -static bool string_contain (const char string[], const char substring[]); - -static bool engine_step (); - -// functions - -// epd_test() - -void epd_test(int argc, char * argv[]) { - - int i; - const char * epd_file; - - epd_file = NULL; - my_string_set(&epd_file,"wac.epd"); - - MinDepth = 8; - MaxDepth = 63; - - MinTime = 1.0; - MaxTime = 5.0; - - DepthDelta = 3; - - for (i = 1; i < argc; i++) { - - if (false) { - - } else if (my_string_equal(argv[i],"epd-test")) { - - // skip - - } else if (my_string_equal(argv[i],"-epd")) { - - i++; - if (argv[i] == NULL) my_fatal("epd_test(): missing argument\n"); - - my_string_set(&epd_file,argv[i]); - - } else if (my_string_equal(argv[i],"-min-depth")) { - - i++; - if (argv[i] == NULL) my_fatal("epd_test(): missing argument\n"); - - MinDepth = atoi(argv[i]); - - } else if (my_string_equal(argv[i],"-max-depth")) { - - i++; - if (argv[i] == NULL) my_fatal("epd_test(): missing argument\n"); - - MaxDepth = atoi(argv[i]); - - } else if (my_string_equal(argv[i],"-min-time")) { - - i++; - if (argv[i] == NULL) my_fatal("epd_test(): missing argument\n"); - - MinTime = atof(argv[i]); - - } else if (my_string_equal(argv[i],"-max-time")) { - - i++; - if (argv[i] == NULL) my_fatal("epd_test(): missing argument\n"); - - MaxTime = atof(argv[i]); - - } else if (my_string_equal(argv[i],"-depth-delta")) { - - i++; - if (argv[i] == NULL) my_fatal("epd_test(): missing argument\n"); - - DepthDelta = atoi(argv[i]); - - } else { - - my_fatal("epd_test(): unknown option \"%s\"\n",argv[i]); - } - } - - if(MinTime>MaxTime){ - MaxTime=MinTime; - } - - epd_test_file(epd_file); -} - -// epd_test_file() - -static void epd_test_file(const char file_name[]) { - - FILE * file; - int hit, tot; - char epd[StringSize]; - char am[StringSize], bm[StringSize], id[StringSize]; - board_t board[1]; - char string[StringSize]; - int move; - char pv_string[StringSize]; - bool correct; - double depth_tot, time_tot, node_tot; - int line=0; - - ASSERT(file_name!=NULL); - - // init - - file = fopen(file_name,"r"); - if (file == NULL) my_fatal("epd_test_file(): can't open file \"%s\": %s\n",file_name,strerror(errno)); - - hit = 0; - tot = 0; - - depth_tot = 0.0; - time_tot = 0.0; - node_tot = 0.0; - - printf("\nEngineName=%s\n",option_get_string("EngineName")); - - printf("\n[Search parameters: MaxDepth=%d MaxTime=%.1f DepthDelta=%d MinDepth=%d MinTime=%.1f]\n\n",MaxDepth,MaxTime,DepthDelta,MinDepth,MinTime); - - // loop - - while (my_file_read_line(file,epd,StringSize)) { - line++; - if(my_string_whitespace(epd)) continue; - if (UseTrace) printf("%s\n",epd); - - if (!epd_get_op(epd,"am",am,StringSize)) strcpy(am,""); - if (!epd_get_op(epd,"bm",bm,StringSize)) strcpy(bm,""); - if (!epd_get_op(epd,"id",id,StringSize)) strcpy(id,""); - - if (my_string_empty(am) && my_string_empty(bm)) { - my_fatal("epd_test(): no am or bm field at line %d\n",line); - } - - // init - - uci_send_ucinewgame(Uci); - uci_send_isready_sync(Uci); - - ASSERT(!Uci->searching); - - // position - if (!board_from_fen(board,epd)) ASSERT(false); - if (!board_to_fen(board,string,StringSize)) ASSERT(false); - - engine_send(Engine,"position fen %s",string); - - // search - - my_timer_start(Timer); // also resets - - // which ones of the next two alternatives is best? - engine_send(Engine,"go movetime %.0f depth %d",MaxTime*1000.0,MaxDepth); - //engine_send(Engine,"go infinite"); - - // engine data - - board_copy(Uci->board,board); - - uci_clear(Uci); - Uci->searching = true; - Uci->pending_nb++; - - FirstMove = MoveNone; - FirstDepth = 0; - FirstSelDepth = 0; - FirstScore = 0; - FirstTime = 0.0; - FirstNodeNb = 0; - line_clear(FirstPV); - - LastMove = MoveNone; - LastDepth = 0; - LastSelDepth = 0; - LastScore = 0; - LastTime = 0.0; - LastNodeNb = 0; - line_clear(LastPV); - - // parse engine output - - while (!engine_eof(Engine) && engine_step()) { - bool stop=false; - - // stop search? -// printf("Uci->time=%.2f time=%.2f\n",Uci->time,my_timer_elapsed_real(Timer)); - if (Uci->depth > MaxDepth){ - my_log("POLYGLOT Maximum depth %d reached\n",MaxDepth); - stop=true; - }else if(my_timer_elapsed_real(Timer) >= MaxTime){ - my_log("POLYGLOT Maximum search time %.2fs reached\n",MaxTime); - stop=true; - }else if(Uci->depth - FirstDepth >= DepthDelta){ - if(Uci->depth > MinDepth){ - if(Uci->time >= MinTime){ - if(is_solution(FirstMove,board,bm,am)){ - my_log("POLYGLOT Solution found\n",MaxTime); - stop=true; - } - } - } - } - if(stop){ - my_log("POLYGLOT Stopping engine\n"); - engine_send(Engine,"stop"); - break; - } - } - - move = FirstMove; - correct = is_solution(move,board,bm,am); - - if (correct) hit++; - tot++; - - if (correct) { - depth_tot += double(FirstDepth); - time_tot += FirstTime; - node_tot += double(sint64(FirstNodeNb)); - } - - printf("%2d: %-15s %s %4d",tot,id,correct?"OK":"--",hit); - - if (!line_to_san(LastPV,Uci->board,pv_string,StringSize)) ASSERT(false); - printf(" score=%+6.2f pv [D=%2d, T=%7.2fs, N=%6dk] =%s\n",double(LastScore)/100.0,FirstDepth,FirstTime,(int)FirstNodeNb/1000,pv_string); - } - - printf("\nscore=%d/%d",hit,tot); - - if (hit != 0) { - - depth_tot /= double(hit); - time_tot /= double(hit); - node_tot /= double(hit); - - printf(" [averages on correct positions: depth=%.1f time=%.2f nodes=%.0f]",depth_tot,time_tot,node_tot); - } - - printf("\n"); - - fclose(file); - quit(); -} - -// is_solution() - -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; -} - -// epd_get_op() - -bool epd_get_op(const char record[], const char opcode[], char string[], int size) { - - char op[256]; - int len; - const char *p_start, *p_end; - - ASSERT(record!=NULL); - ASSERT(opcode!=NULL); - ASSERT(string!=NULL); - ASSERT(size>0); - - // find the opcode - - sprintf(op," %s ",opcode); - - p_start = strstr(record,op); - if (p_start == NULL){ - sprintf(op,";%s ",opcode); - p_start = strstr(record,op); - if (p_start == NULL){ - return false; - } - } - - // skip the opcode - - p_start += strlen(op); - - // find the end - p_end = strchr(p_start,';'); - if (p_end == NULL) return false; - - // calculate the length - - len = p_end - p_start; - if (size < len+1) my_fatal("epd_get_op(): size < len+1\n"); - - strncpy(string,p_start,len); - string[len] = '\0'; - - return true; -} - -// string_contain() - -static bool string_contain(const char string[], const char substring[]) { - - char new_string[StringSize], *p; - - strcpy(new_string,string); // HACK - - for (p = strtok(new_string," "); p != NULL; p = strtok(NULL," ")) { - if (my_string_equal(p,substring)) return true; - } - - return false; -} - -// engine_step() - -static bool engine_step() { - - char string[StringSize]; - int event; - - engine_get(Engine,string,StringSize); - event = uci_parse(Uci,string); - - if ((event & EVENT_MOVE) != 0) { - - return false; - } - - if ((event & EVENT_PV) != 0) { - - LastMove = Uci->best_pv[0]; - LastDepth = Uci->best_depth; - LastSelDepth = Uci->best_sel_depth; - LastScore = Uci->best_score; - LastTime = Uci->time; - LastNodeNb = Uci->node_nb; - line_copy(LastPV,Uci->best_pv); - - if (LastMove != FirstMove) { - FirstMove = LastMove; - FirstDepth = LastDepth; - FirstSelDepth = LastSelDepth; - FirstScore = LastScore; - FirstTime = LastTime; - FirstNodeNb = LastNodeNb; - line_copy(FirstPV,LastPV); - } - } - - return true; -} - -// end of epd.cpp - diff --git a/fen.cpp b/fen.cpp deleted file mode 100644 index 9f6f428..0000000 --- a/fen.cpp +++ /dev/null @@ -1,392 +0,0 @@ - -// fen.cpp - -// includes - -#include -#include -#include - -#include "board.h" -#include "colour.h" -#include "fen.h" -#include "option.h" -#include "piece.h" -#include "square.h" -#include "util.h" - -// "constants" - -// const char * StartFen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w HAha - 0 1"; -const char * StartFen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"; - -// variables - -static const bool Strict = false; - -// macros - -#define skip_white_space() \ - c=string[pos];\ - if (c != ' ' && c!='\t') my_fatal("board_from_fen(): bad FEN (pos=%d)\n",pos); \ - while(c==' ' || c=='\t') c=string[++pos]; - - -// functions - -// board_from_fen() - -bool board_from_fen(board_t * board, const char string[]) { - - int pos; - int file, rank, sq; - int c; - int i, len; - int piece; - int king_pos[ColourNb]; - - ASSERT(board!=NULL); - ASSERT(string!=NULL); - - board_clear(board); - - king_pos[White] = SquareNone; - king_pos[Black] = SquareNone; - - pos = 0; - c = string[pos]; - - // piece placement - - for (rank = 7; rank >= 0; rank--) { - - for (file = 0; file < 8;) { - - sq = square_make(file,rank); - - if (c >= '1' && c <= '8') { // empty square(s) - - len = c - '0'; - if (file + len > 8) my_fatal("board_from_fen(): bad FEN (pos=%d)\n",pos); - - for (i = 0; i < len; i++) { - board->square[sq++] = Empty; - file++; - } - - } else { // piece - - piece = piece_from_char(c); - if (piece == PieceNone256) my_fatal("board_from_fen(): bad FEN (pos=%d)\n",pos); - - if (piece_is_king(piece)) king_pos[piece_colour(piece)] = sq; - - board->square[sq++] = piece; - file++; - } - - c = string[++pos]; - } - - if (rank > 0) { - if (c != '/') my_fatal("board_from_fen(): bad FEN (pos=%d)\n",pos); - c = string[++pos]; - } - } - - // active colour - - skip_white_space(); - - switch (c) { - case 'w': - board->turn = White; - break; - case 'b': - board->turn = Black; - break; - default: - my_fatal("board_from_fen(): bad FEN (pos=%d)\n",pos); - break; - } - - c = string[++pos]; - - // castling - - skip_white_space(); - - board->castle[White][SideH] = SquareNone; - board->castle[White][SideA] = SquareNone; - board->castle[Black][SideH] = SquareNone; - board->castle[Black][SideA] = SquareNone; - - if (c == '-') { // no castling rights - - c = string[++pos]; - - } else { - - // TODO: filter out illegal rights - - do { - - if (false) { - - } else if (c == 'K') { - - for (sq = H1; sq > king_pos[White]; sq--) { - if (board->square[sq] == WhiteRook256) { - board->castle[White][SideH] = sq; - break; - } - } - - } else if (c == 'Q') { - - for (sq = A1; sq < king_pos[White]; sq++) { - if (board->square[sq] == WhiteRook256) { - board->castle[White][SideA] = sq; - break; - } - } - - } else if (c == 'k') { - - for (sq = H8; sq > king_pos[Black]; sq--) { - if (board->square[sq] == BlackRook256) { - board->castle[Black][SideH] = sq; - break; - } - } - - } else if (c == 'q') { - - for (sq = A8; sq < king_pos[Black]; sq++) { - if (board->square[sq] == BlackRook256) { - board->castle[Black][SideA] = sq; - break; - } - } - - } else if (c >= 'A' && c <= 'H') { - - // white castling right - - sq = square_make(file_from_char(tolower(c)),Rank1); - - if (sq > king_pos[White]) { // h side - board->castle[White][SideH] = sq; - } else { // a side - board->castle[White][SideA] = sq; - } - - } else if (c >= 'a' && c <= 'h') { - - // black castling right - - sq = square_make(file_from_char(tolower(c)),Rank8); - - if (sq > king_pos[Black]) { // h side - board->castle[Black][SideH] = sq; - } else { // a side - board->castle[Black][SideA] = sq; - } - - } else { - - my_fatal("board_from_fen(): bad FEN (pos=%d)\n",pos); - } - - c = string[++pos]; - - } while (c != ' '); - } - - // en-passant - - skip_white_space(); - - if (c == '-') { // no en-passant - - sq = SquareNone; - c = string[++pos]; - - } else { - - if (c < 'a' || c > 'h') my_fatal("board_from_fen(): bad FEN (pos=%d)\n",pos); - file = file_from_char(c); - c = string[++pos]; - - if (c < '1' || c > '8') my_fatal("board_from_fen(): bad FEN (pos=%d)\n",pos); - rank = rank_from_char(c); - c = string[++pos]; - - sq = square_make(file,rank); - } - - board->ep_square = sq; - - // halfmove clock - - board->ply_nb = 0; - board->move_nb = 0; // HACK, in case of broken syntax - - if (c != ' ') { - if (!Strict) goto update; - my_fatal("board_from_fen(): bad FEN (pos=%d)\n",pos); - } - c = string[++pos]; - - if (!isdigit(c)) { - if (!Strict) goto update; - my_fatal("board_from_fen(): bad FEN (pos=%d)\n",pos); - } - - board->ply_nb = atoi(&string[pos]); - do c = string[++pos]; while (isdigit(c)); - - // fullmove number - - board->move_nb = 0; - - if (c != ' ') { - if (!Strict) goto update; - my_fatal("board_from_fen(): bad FEN (pos=%d)\n",pos); - } - c = string[++pos]; - - if (!isdigit(c)) { - if (!Strict) goto update; - my_fatal("board_from_fen(): bad FEN (pos=%d)\n",pos); - } - - board->move_nb = atoi(&string[pos]) - 1; - do c = string[++pos]; while (isdigit(c)); - - // board update - -update: - board_init_list(board); - - return true; -} - -// board_to_fen() - -bool board_to_fen(const board_t * board, char string[], int size) { - - int pos; - int file, rank; - int sq, piece; - int c; - int len; - int old_pos; - - ASSERT(board_is_ok(board)); - ASSERT(string!=NULL); - ASSERT(size>=92); - - // init - - if (size < 92) return false; - - pos = 0; - - // piece placement - - for (rank = 7; rank >= 0; rank--) { - - for (file = 0; file < 8;) { - - sq = square_make(file,rank); - piece = board->square[sq]; - ASSERT(piece==Empty||piece_is_ok(piece)); - - if (piece == Empty) { - - len = 0; - for (; file < 8 && board->square[square_make(file,rank)] == Empty; file++) { - len++; - } - - ASSERT(len>=1&&len<=8); - c = '0' + len; - - } else { - - c = piece_to_char(piece); - file++; - } - - string[pos++] = c; - } - - string[pos++] = '/'; - } - - string[pos-1] = ' '; // HACK: remove the last '/' - - // active colour - - string[pos++] = (colour_is_white(board->turn)) ? 'w' : 'b'; - string[pos++] = ' '; - - // castling - - old_pos = pos; - - if (option_get_bool("Chess960")) { - - // FEN-960 - - if (board->castle[White][SideH] != SquareNone) { - string[pos++] = toupper(file_to_char(square_file(board->castle[White][SideH]))); - } - - if (board->castle[White][SideA] != SquareNone) { - string[pos++] = toupper(file_to_char(square_file(board->castle[White][SideA]))); - } - - if (board->castle[Black][SideH] != SquareNone) { - string[pos++] = tolower(file_to_char(square_file(board->castle[Black][SideH]))); - } - - if (board->castle[Black][SideA] != SquareNone) { - string[pos++] = tolower(file_to_char(square_file(board->castle[Black][SideA]))); - } - - } else { - - // FEN - - if (board->castle[White][SideH] != SquareNone) string[pos++] = 'K'; - if (board->castle[White][SideA] != SquareNone) string[pos++] = 'Q'; - if (board->castle[Black][SideH] != SquareNone) string[pos++] = 'k'; - if (board->castle[Black][SideA] != SquareNone) string[pos++] = 'q'; - } - - if (pos == old_pos) string[pos++] = '-'; - - string[pos++] = ' '; - - // en-passant - - if (board->ep_square == SquareNone) { - string[pos++] = '-'; - } else { - if (!square_to_string(board->ep_square,&string[pos],3)) return false; - pos += 2; - } - - string[pos++] = ' '; - - // halfmove clock and fullmove number - - sprintf(&string[pos],"%d %d",board->ply_nb,board->move_nb+1); - - return true; -} - -// end of fen.cpp - diff --git a/game.cpp b/game.cpp deleted file mode 100644 index 703fa2d..0000000 --- a/game.cpp +++ /dev/null @@ -1,355 +0,0 @@ - -// game.cpp - -// includes - -#include "attack.h" -#include "board.h" -#include "fen.h" -#include "game.h" -#include "list.h" -#include "move.h" -#include "move_do.h" -#include "move_legal.h" -#include "piece.h" -#include "square.h" -#include "util.h" - -// constants - -static const bool UseSlowDebug = false; - -// variables - -game_t Game[1]; - -// prototypes - -static void game_update (game_t * game); -static int game_comp_status (const game_t * game); - -// functions - -// game_is_ok() - -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)); //huh?? - if (!move_is_legal(move,board)) return false; - - move_do(board,move); - } - - if (game->status != game_comp_status(game)) return false; - - return true; -} - -// game_clear() - -void game_clear(game_t * game) { - - ASSERT(game!=NULL); - - game_init(game,StartFen); -} - -// game_init() - -bool game_init(game_t * game, const char fen[]) { - - ASSERT(game!=NULL); - ASSERT(fen!=NULL); - - if (!board_from_fen(game->start_board,fen)) return false; - - game->size = 0; - - board_copy(game->board,game->start_board); - game->pos = 0; - - game_update(game); - - return true; -} - -// game_status() - -int game_status(const game_t * game) { - - ASSERT(game!=NULL); - - return game->status; -} - -// game_size() - -int game_size(const game_t * game) { - - ASSERT(game!=NULL); - - return game->size; -} - -// game_pos() - -int game_pos(const game_t * game) { - - ASSERT(game!=NULL); - - return game->pos; -} - -// game_move() - -int game_move(const game_t * game, int pos) { - - ASSERT(game!=NULL); - ASSERT(pos>=0&&pospos); - - return game->move[pos]; -} - -// game_get_board() - -void game_get_board(const game_t * game, board_t * board, int pos) { - - int start; - int i; - - ASSERT(game!=NULL); - ASSERT(board!=NULL); - ASSERT(pos==-1||(pos>=0&&pos<=game->size)); // HACK - - if (pos < 0) pos = game->pos; - - if (pos >= game->pos) { // forward from current position - start = game->pos; - board_copy(board,game->board); - } else { // backward => replay the whole game - start = 0; - board_copy(board,game->start_board); - } - - for (i = start; i < pos; i++) move_do(board,game->move[i]); -} - -// game_turn() - -int game_turn(const game_t * game) { - - ASSERT(game!=NULL); - - return game->board->turn; -} - -// game_move_nb() - -int game_move_nb(const game_t * game) { - - ASSERT(game!=NULL); - - return game->board->move_nb; -} - -// game_add_move() - -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); -} - -// game_rem_move() - -void game_rem_move(game_t * game) { - - ASSERT(game!=NULL); - - game_goto(game,game->pos-1); - - game->size = game->pos; // truncate game -} - -// game_goto() - -void game_goto(game_t * game, int pos) { - - int i; - - ASSERT(game!=NULL); - ASSERT(pos>=0&&pos<=game->size); - - if (pos < game->pos) { // going backward => replay the whole game - board_copy(game->board,game->start_board); - game->pos = 0; - } - - for (i = game->pos; i < pos; i++) move_do(game->board,game->move[i]); - ASSERT(i==pos); - - game->pos = pos; - - game_update(game); -} - -// game_disp() - -void game_disp(const game_t * game) { - - board_t board[1]; - int i, move; - - ASSERT(game_is_ok(game)); - - board_copy(board,game->start_board); - - board_disp(board); - - for (i = 0; i < game->pos; i++) { - - move = game->move[i]; - move_disp(move,board); - - move_do(board,move); - } - - my_log("POLYGLOT\n"); - - board_disp(board); -} - -// game_update() - -static void game_update(game_t * game) { - - ASSERT(game!=NULL); - - game->status = game_comp_status(game); - - ASSERT(game_is_ok(game)); -} - -// game_comp_status() - -static int game_comp_status(const game_t * game) { - - int i, n; - int wb, bb; - const board_t * board; - uint64 key; - int start; - - ASSERT(game!=NULL); - - // init - - board = game->board; - - // mate and stalemate - - if (!board_can_play(board)) { - if (false) { - } else if (is_in_check(board,Black)) { // HACK - return WHITE_MATES; - } else if (is_in_check(board,White)) { // HACK - return BLACK_MATES; - } else { - return STALEMATE; - } - } - - // insufficient material - - if (board->number[WhitePawn12] == 0 - && board->number[BlackPawn12] == 0 - && board->number[WhiteQueen12] == 0 - && board->number[BlackQueen12] == 0 - && board->number[WhiteRook12] == 0 - && board->number[BlackRook12] == 0) { - - if (board->number[WhiteBishop12] - + board->number[BlackBishop12] - + board->number[WhiteKnight12] - + board->number[BlackKnight12] <= 1) { // KK, KBK and KNK - - return DRAW_MATERIAL; - - } else if (board->number[WhiteBishop12] == 1 - && board->number[BlackBishop12] == 1 - && board->number[WhiteKnight12] == 0 - && board->number[BlackKnight12] == 0) { - - wb = board->list[White][1]; // HACK - bb = board->list[Black][1]; // HACK - - if (square_colour(wb) == square_colour(bb)) { // KBKB - return DRAW_MATERIAL; - } - } - } - - // 50-move rule - - if (board->ply_nb >= 100) return DRAW_FIFTY; - - // position repetition - - key = board->key; - n = 0; - - start = game->pos - board->ply_nb; - if (start < 0) start = 0; - - for (i = game->pos-4; i >= start; i -= 2) { - if (game->key[i] == key) { - if (++n == 2) return DRAW_REPETITION; - } - } - - return PLAYING; -} - -// end of game.cpp - diff --git a/gui.cpp b/gui.cpp deleted file mode 100644 index 71d0cc0..0000000 --- a/gui.cpp +++ /dev/null @@ -1,130 +0,0 @@ -// gui.cpp - -// includes - -#include -#include - -#include "gui.h" -#include "main.h" - -// constants - -static const int StringSize = 4096; - -// variables - -gui_t GUI[1]; - -// functions - -// sig_quit() - -static void sig_quit(int dummy){ - my_log("POLYGLOT *** SIGINT Received ***\n"); - quit(); -} - - -// gui_init() - -void gui_init(gui_t *gui){ - -// the following is nice if the "GUI" is a console! - signal(SIGINT,sig_quit); -#ifdef _WIN32 - signal(SIGTERM,SIG_IGN); -#ifdef SIGPIPE - signal(SIGPIPE,SIG_IGN); -#endif -#endif - -#ifdef _WIN32 - (gui->io).Open(); -#else - - gui->io->in_fd = STDIN_FILENO; - gui->io->out_fd = STDOUT_FILENO; - gui->io->name = "GUI"; - - io_init(gui->io); -#endif -} - - -// gui_get_non_blocking() - -bool gui_get_non_blocking(gui_t * gui, char string[], int size) { - - ASSERT(gui!=NULL); - ASSERT(string!=NULL); - ASSERT(size>=256); -#ifndef _WIN32 - if(io_line_ready(gui->io)){ - gui_get(GUI,string,StringSize); - return true; - }else{ - string[0]='\0'; - return false; - } -#else - if((gui->io).EOF_()){ - my_log("POLYGLOT *** EOF from GUI ***\n"); - quit(); - return true; // we never get here - }else if ((gui->io).GetBuffer(string)) { - my_log("GUI->Adapter: %s\n", string); - return true; - } else { - string[0]='\0'; - return false; - } -#endif -} - -// gui_get() - -void gui_get(gui_t * gui, char string[], int size) { - bool data_available; -#ifdef _WIN32 - if((gui->io).EOF_()){ - my_log("POLYGLOT *** EOF from GUI ***\n"); - quit(); - } - (gui->io).LineInput(string); - my_log("GUI->Adapter: %s\n", string); -#else - if (!io_get_line(gui->io,string,size)) { // EOF - my_log("POLYGLOT *** EOF from GUI ***\n"); - quit(); - } -#endif -} - - -// gui_send() - -void gui_send(gui_t * gui, const char format[], ...) { - - va_list arg_list; - char string[StringSize]; - - ASSERT(gui!=NULL); - ASSERT(format!=NULL); - - // format - - va_start(arg_list,format); - vsprintf(string,format,arg_list); - va_end(arg_list); - - // send - -#ifndef _WIN32 - io_send(gui->io,"%s",string); -#else - gui->io.LineOutput(string); - my_log("Adapter->GUI: %s\n",string); -#endif -} - diff --git a/hash.cpp b/hash.cpp deleted file mode 100644 index 490a5a3..0000000 --- a/hash.cpp +++ /dev/null @@ -1,128 +0,0 @@ - -// hash.cpp - -// includes - -#include "board.h" -#include "hash.h" -#include "piece.h" -#include "random.h" -#include "square.h" -#include "util.h" - -// variables - -static uint64 Castle64[16]; - -// prototypes - -static uint64 hash_castle_key_debug (int flags); - -// functions - -// hash_init() - -void hash_init() { - - int i; - - for (i = 0; i < 16; i++) Castle64[i] = hash_castle_key_debug(i); -} - -// hash_key() - -uint64 hash_key(const board_t * board) { - - uint64 key; - int colour; - const uint8 * ptr; - int sq, piece; - - ASSERT(board_is_ok(board)); - - // init - - key = 0; - - // pieces - - for (colour = 1; colour <= 2; colour++) { // HACK - for (ptr = board->list[colour]; (sq=*ptr) != SquareNone; ptr++) { - piece = board->square[sq]; - key ^= hash_piece_key(piece,sq); - } - } - - // castle flags - - key ^= hash_castle_key(board_flags(board)); - - // en-passant square - - sq = board->ep_square; - if (sq != SquareNone) key ^= hash_ep_key(sq); - - // turn - - key ^= hash_turn_key(board->turn); - - return key; -} - -// hash_piece_key() - -uint64 hash_piece_key(int piece, int square) { - - ASSERT(piece_is_ok(piece)); - ASSERT(square_is_ok(square)); - - return random_64(RandomPiece+piece_to_12(piece)*64+square_to_64(square)); -} - -// hash_castle_key() - -uint64 hash_castle_key(int flags) { - - ASSERT((flags&~0xF)==0); - - return Castle64[flags]; -} - -// hash_castle_key_debug() - -static uint64 hash_castle_key_debug(int flags) { - - uint64 key; - int i; - - ASSERT((flags&~0xF)==0); - - key = 0; - - for (i = 0; i < 4; i++) { - if ((flags & (1< -#include -#include -#include -#include - -#include -#include - -#include "io.h" -#include "util.h" - -// constants - -static const bool UseDebug = false; -static const bool UseCR = false; - -static const int StringSize = 4096; - -static const char LF = '\n'; -static const char CR = '\r'; - -// prototypes - -static int my_read (int fd, char string[], int size); -static void my_write (int fd, const char string[], int size); - -// functions - -// io_is_ok() - -bool io_is_ok(const io_t * io) { - - if (io == NULL) return false; - - if (io->name == NULL) return false; - - if (io->in_eof != true && io->in_eof != false) return false; - - if (io->in_size < 0 || io->in_size > BufferSize) return false; - if (io->out_size < 0 || io->out_size > BufferSize) return false; - - return true; -} - -// io_init() - -void io_init(io_t * io) { - - ASSERT(io!=NULL); - - io->in_eof = false; - - io->in_size = 0; - io->out_size = 0; - - ASSERT(io_is_ok(io)); -} - -// io_close() - -void io_close(io_t * io) { - - ASSERT(io_is_ok(io)); - - ASSERT(io->out_fd>=0); - - my_log("Adapter>Engine: EOF\n",io->name); - - if (close(io->out_fd) == -1) { - my_fatal("io_close(): close(): %s\n",strerror(errno)); - } - - io->out_fd = -1; -} - -// io_get_update() - -void io_get_update(io_t * io) { - - int pos, size; - int n; - - ASSERT(io_is_ok(io)); - - ASSERT(io->in_fd>=0); - ASSERT(!io->in_eof); - - // init - - pos = io->in_size; - - size = BufferSize - pos; - if (size <= 0) my_fatal("io_get_update(): buffer overflow\n"); - - // read as many data as possible - n = my_read(io->in_fd,&io->in_buffer[pos],size); - if (UseDebug) my_log("POLYGLOT read %d byte%s from %s\n",n,(n>1)?"s":"",io->name); - - if (n > 0) { // at least one character was read - - // update buffer size - - ASSERT(n>=1&&n<=size); - - io->in_size += n; - ASSERT(io->in_size>=0&&io->in_size<=BufferSize); - - } else { // EOF - - ASSERT(n==0); - - io->in_eof = true; - } -} - -// io_line_ready() - -bool io_line_ready(const io_t * io) { - - ASSERT(io_is_ok(io)); - - if (io->in_eof) return true; - - if (memchr(io->in_buffer,LF,io->in_size) != NULL) return true; // buffer contains LF - - return false; -} - -// io_get_line() - -bool io_get_line(io_t * io, char string[], int size) { - - int src, dst; - int c; - - ASSERT(io_is_ok(io)); - ASSERT(string!=NULL); - ASSERT(size>=256); - - src = 0; - dst = 0; - - while (true) { - - // test for end of buffer - - if (src >= io->in_size) { - if (io->in_eof) { - my_log("%s->Adapter: EOF\n",io->name); - return false; - } else { - my_fatal("io_get_line(): no EOL in buffer\n"); - } - } - - // test for end of string - - if (dst >= size) my_fatal("io_get_line(): buffer overflow\n"); - - // copy the next character - - c = io->in_buffer[src++]; - - if (c == LF) { // LF => line complete - string[dst] = '\0'; - break; - } else if (c != CR) { // skip CRs - string[dst++] = c; - } - } - - // shift the buffer - - ASSERT(src>0); - - io->in_size -= src; - ASSERT(io->in_size>=0); - - if (io->in_size > 0) memmove(&io->in_buffer[0],&io->in_buffer[src],io->in_size); - - // return - - my_log("%s->Adapter: %s\n",io->name,string); - - return true; -} - -// io_send() - -void io_send(io_t * io, const char format[], ...) { - - va_list arg_list; - char string[StringSize]; - int len; - - ASSERT(io_is_ok(io)); - ASSERT(format!=NULL); - - ASSERT(io->out_fd>=0); - - // format - - va_start(arg_list,format); - vsprintf(string,format,arg_list); - va_end(arg_list); - - // append string to buffer - - len = strlen(string); - if (io->out_size + len > BufferSize-2) my_fatal("io_send(): buffer overflow\n"); - - memcpy(&io->out_buffer[io->out_size],string,len); - io->out_size += len; - - ASSERT(io->out_size>=0&&io->out_size<=BufferSize-2); - - // log - - io->out_buffer[io->out_size] = '\0'; - my_log("Adapter->%s: %s\n",io->name,io->out_buffer); -// my_log("> %f %s %s\n",now_real(),io->name,io->out_buffer); - // append EOL to buffer - - if (UseCR) io->out_buffer[io->out_size++] = CR; - io->out_buffer[io->out_size++] = LF; - - ASSERT(io->out_size>=0&&io->out_size<=BufferSize); - - // flush buffer - - if (UseDebug) my_log("POLYGLOT writing %d byte%s to %s\n",io->out_size,(io->out_size>1)?"s":"",io->name); - my_write(io->out_fd,io->out_buffer,io->out_size); - - io->out_size = 0; -} - -// io_send_queue() - -void io_send_queue(io_t * io, const char format[], ...) { - - va_list arg_list; - char string[StringSize]; - int len; - - ASSERT(io_is_ok(io)); - ASSERT(format!=NULL); - - ASSERT(io->out_fd>=0); - - // format - - va_start(arg_list,format); - vsprintf(string,format,arg_list); - va_end(arg_list); - - // append string to buffer - - len = strlen(string); - if (io->out_size + len > BufferSize-2) my_fatal("io_send_queue(): buffer overflow\n"); - - memcpy(&io->out_buffer[io->out_size],string,len); - io->out_size += len; - - ASSERT(io->out_size>=0&&io->out_size<=BufferSize-2); -} - -// my_read() - -static int my_read(int fd, char string[], int size) { - - int n; - - ASSERT(fd>=0); - ASSERT(string!=NULL); - ASSERT(size>0); - - do { - n = read(fd,string,size); - } while (n == -1 && errno == EINTR); - - if (n == -1) my_fatal("my_read(): read(): %s\n",strerror(errno)); - - ASSERT(n>=0); - - return n; -} - -// my_write() - -static void my_write(int fd, const char string[], int size) { - - int n; - - ASSERT(fd>=0); - ASSERT(string!=NULL); - ASSERT(size>0); - - do { - - n = write(fd,string,size); - - // if (n == -1 && errno != EINTR && errno != EPIPE) my_fatal("my_write(): write(): %s\n",strerror(errno)); - - if (n == -1) { - if (false) { - } else if (errno == EINTR) { - n = 0; // nothing has been written - } else if (errno == EPIPE) { - n = size; // pretend everything has been written - } else { - my_fatal("my_write(): write(): %s\n",strerror(errno)); - } - } - - ASSERT(n>=0); - - string += n; - size -= n; - - } while (size > 0); - - ASSERT(size==0); -} - -// end of io.cpp - -#endif diff --git a/line.cpp b/line.cpp deleted file mode 100644 index db62926..0000000 --- a/line.cpp +++ /dev/null @@ -1,205 +0,0 @@ - -// line.cpp - -// includes - -#include - -#include "board.h" -#include "line.h" -#include "move.h" -#include "move_do.h" -#include "move_legal.h" -#include "san.h" -#include "util.h" - -// constants - -static const bool Strict = false; // false -static const bool UseDebug = false; // false - -static const int StringSize = 1024; - -// functions - -// line_is_ok() - -bool line_is_ok(const move_t line[]) { - - int move; - - if (line == NULL) return false; - - while ((move = *line++) != MoveNone) { - if (!move_is_ok(move)) return false; - } - - return true; -} - -// line_clear() - -void line_clear(move_t line[]) { - - ASSERT(line!=NULL); - - *line = MoveNone; -} - -// line_copy() - -void line_copy(move_t dst[], const move_t src[]) { - - ASSERT(dst!=NULL); - ASSERT(src!=NULL); - - ASSERT(dst!=src); - - while ((*dst++ = *src++) != MoveNone) - ; -} - -// line_from_can() - -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; -} - -// line_to_can() - -bool line_to_can(const move_t line[], const board_t * board, char string[], int size) { - - board_t new_board[1]; - int pos; - int move; - - ASSERT(line_is_ok(line)); - ASSERT(board_is_ok(board)); - ASSERT(string!=NULL); - ASSERT(size>=StringSize); - - // init - - if (size < StringSize) 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_to_can(move,new_board,&string[pos],size-pos)) return false; - pos += strlen(&string[pos]); - - move_do(new_board,move); - } - - if (pos >= size) return false; - string[pos] = '\0'; - - return true; -} - -// line_to_san() - -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 - - if (size < StringSize) 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,256); - 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 += strlen(&string[pos]); - - move_do(new_board,move); - } - - if (pos >= size) return false; - string[pos] = '\0'; - - return true; -} - -// end of line.cpp - diff --git a/list.cpp b/list.cpp deleted file mode 100644 index 040d7ea..0000000 --- a/list.cpp +++ /dev/null @@ -1,269 +0,0 @@ - -// list.cpp - -// includes - -#include "board.h" -#include "list.h" -#include "move.h" -#include "util.h" - -// functions - -// list_is_ok() - -bool list_is_ok(const list_t * list) { - - if (list == NULL) return false; - - if (list->size >= ListSize) return false; - - return true; -} - -// list_clear() - -void list_clear(list_t * list) { - - ASSERT(list!=NULL); - - list->size = 0; -} - -// list_add() - -void list_add(list_t * list, int move, int value) { - - ASSERT(list_is_ok(list)); - ASSERT(move_is_ok(move)); - ASSERT(value>=-32767&&value<=+32767); - - ASSERT(list->sizemove[list->size] = move; - list->value[list->size] = value; - list->size++; -} - -// list_remove() - -void list_remove(list_t * list, int index) { - - int i; - - ASSERT(list_is_ok(list)); - ASSERT(index>=0&&indexsize); - - for (i = index; i < list->size-1; i++) { - list->move[i] = list->move[i+1]; - list->value[i] = list->value[i+1]; - } - - list->size--; -} - -// list_is_empty() - -bool list_is_empty(const list_t * list) { - - ASSERT(list_is_ok(list)); - - return list->size == 0; -} - -// list_size() - -int list_size(const list_t * list) { - - ASSERT(list_is_ok(list)); - - return list->size; -} - -// list_move() - -int list_move(const list_t * list, int index) { - - ASSERT(list_is_ok(list)); - ASSERT(index>=0&&indexsize); - - return list->move[index]; -} - -// list_value() - -int list_value(const list_t * list, int index) { - - ASSERT(list_is_ok(list)); - ASSERT(index>=0&&indexsize); - - return list->value[index]; -} - -// list_copy() - -void list_copy(list_t * dst, const list_t * src) { - - int i; - - ASSERT(dst!=NULL); - ASSERT(list_is_ok(src)); - - dst->size = src->size; - - for (i = 0; i < src->size; i++) { - dst->move[i] = src->move[i]; - dst->value[i] = src->value[i]; - } -} - -// list_move_to_front() - -void list_move_to_front(list_t * list, int index) { - - int i; - int move, value; - - ASSERT(list_is_ok(list)); - ASSERT(index>=0&&indexsize); - - if (index != 0) { - - move = list->move[index]; - value = list->value[index]; - - for (i = index; i > 0; i--) { - list->move[i] = list->move[i-1]; - list->value[i] = list->value[i-1]; - } - - list->move[0] = move; - list->value[0] = value; - } -} - -// list_note() - -void list_note(list_t * list) { - - int i, move; - - ASSERT(list_is_ok(list)); - - for (i = 0; i < list->size; i++) { - move = list->move[i]; - ASSERT(move_is_ok(move)); - list->value[i] = -move_order(move); - } -} - -// list_sort() - -void list_sort(list_t * list) { - - int i, j; - int best_index, best_move, best_value; - - ASSERT(list_is_ok(list)); - - for (i = 0; i < list->size-1; i++) { - - best_index = i; - best_value = list->value[i]; - - for (j = i+1; j < list->size; j++) { - if (list->value[j] > best_value) { - best_index = j; - best_value = list->value[j]; - } - } - - if (best_index != i) { - - best_move = list->move[best_index]; - ASSERT(best_value==list->value[best_index]); - - for (j = best_index; j > i; j--) { - list->move[j] = list->move[j-1]; - list->value[j] = list->value[j-1]; - } - - list->move[i] = best_move; - list->value[i] = best_value; - } - } - - if (DEBUG) { - for (i = 0; i < list->size-1; i++) { - ASSERT(list->value[i]>=list->value[i+1]); - } - } -} - -// list_contain() - -bool list_contain(const list_t * list, int move) { - - int i; - - ASSERT(list_is_ok(list)); - ASSERT(move_is_ok(move)); - - for (i = 0; i < list->size; i++) { - if (list->move[i] == move) return true; - } - - return false; -} - -// list_equal() - -bool list_equal(list_t * list_1, list_t * list_2) { - - list_t copy_1[1], copy_2[1]; - int i; - - ASSERT(list_is_ok(list_1)); - ASSERT(list_is_ok(list_2)); - - if (list_1->size != list_2->size) return false; - - list_copy(copy_1,list_1); - list_note(copy_1); - list_sort(copy_1); - - list_copy(copy_2,list_2); - list_note(copy_2); - list_sort(copy_2); - - for (i = 0; i < copy_1->size; i++) { - if (copy_1->move[i] != copy_2->move[i]) return false; - } - - return true; -} - -// list_disp() - -void list_disp(const list_t * list, const board_t * board) { - - int i, move, value; - char string[256]; - - ASSERT(list_is_ok(list)); - ASSERT(board_is_ok(board)); - - for (i = 0; i < list->size; i++) { - - move = list->move[i]; - value = list->value[i]; - - if (!move_to_can(move,board,string,256)) ASSERT(false); - my_log("POLYGLOT %-5s %04X %+4d\n",string,move,value); - } - - my_log("POLYGLOT\n"); -} - -// end of list.cpp - diff --git a/main.cpp b/main.cpp deleted file mode 100644 index 9dd5e04..0000000 --- a/main.cpp +++ /dev/null @@ -1,375 +0,0 @@ - -// main.cpp - -// includes - -#include -#include -#include -#include - -#include "attack.h" -#include "board.h" -#include "book.h" -#include "book_make.h" -#include "book_merge.h" -#include "engine.h" -#include "epd.h" -#include "fen.h" -#include "gui.h" -#include "hash.h" -#include "list.h" -#include "main.h" -#include "mainloop.h" -#include "move.h" -#include "move_gen.h" -#include "option.h" -#include "piece.h" -#include "search.h" -#include "square.h" -#include "uci.h" -#include "util.h" -#include "xboard2uci.h" -#include "uci2uci.h" - -// constants - - -static const char * const Version = "1.4b27"; -static const char * const HelpMessage = "\ -SYNTAX\n\ -* polyglot [configfile]\n\ -* polyglot -ec enginecommand\n\ -* polyglot make-book [-pgn inputfile] [-bin outputfile] [-max-ply ply] [-min-game games] [-min-score score] [-only-white] [-only-black] [-uniform]\n\ -* polyglot merge-book -in1 inputfile1 -in2 inputfile2 [-out outputfile]\n\ -* polyglot info-book [-bin inputfile] [-exact]\n\ -* polyglot dumb-book [-bin inputfile] -color color [-out outputfile]\n\ -* polyglot [configfile] epd-test [-epd inputfile] [-min-depth depth] [-max-depth depth] [-min-time time] [-max-time time] [-depth-delta delta]\n\ -* polyglot perft [-fen fen] [-max-depth depth]\ -"; - -static const int SearchDepth = 63; -static const double SearchTime = 3600.0; -static const int StringSize = 4096; - -// variables - -static bool Init; - -// prototypes - -static void parse_option (); -static void init_book (); -static bool parse_line (char line[], char * * name_ptr, char * * value_ptr); -static void stop_search (); - -// functions - -// main() - -int main(int argc, char * argv[]) { - -// board_t board[1]; - - if(argc>=2 && ((my_string_case_equal(argv[1],"help")) || (my_string_case_equal(argv[1],"-help")) || (my_string_case_equal(argv[1],"--help")) || (my_string_case_equal(argv[1],"-h")) || my_string_case_equal(argv[1],"/?"))){ - printf("%s\n",HelpMessage); - return EXIT_SUCCESS; - } - // init - - Init = false; - - util_init(); - printf("PolyGlot %s by Fabien Letouzey\n",Version); - - option_init(); - - square_init(); - piece_init(); - attack_init(); - - hash_init(); - - my_random_init(); - - // build book - - if (argc >= 2 && my_string_equal(argv[1],"make-book")) { - book_make(argc,argv); - return EXIT_SUCCESS; - } - - if (argc >= 2 && my_string_equal(argv[1],"merge-book")) { - book_merge(argc,argv); - return EXIT_SUCCESS; - } - - if (argc >= 2 && my_string_equal(argv[1],"merge-book")) { - book_merge(argc,argv); - return EXIT_SUCCESS; - } - - if (argc >= 2 && my_string_equal(argv[1],"dump-book")) { - book_dump(argc,argv); - return EXIT_SUCCESS; - } - - if (argc >= 2 && my_string_equal(argv[1],"info-book")) { - book_info(argc,argv); - return EXIT_SUCCESS; - } - - if (argc >= 2 && my_string_equal(argv[1],"perft")) { - do_perft(argc,argv); - return EXIT_SUCCESS; - } - - if (argc >= 3 && my_string_equal(argv[1],"-ec")) { - option_set("EngineCommand",argv[2]); - engine_open(Engine); - if(!engine_active(Engine)){ - my_fatal("Could not start \"%s\"\n",option_get("EngineCommand")); - } - Init=true; - gui_init(GUI); - uci_open(Uci,Engine); - if (my_string_equal(option_get_string("EngineName"),"")) { - option_set("EngineName",Uci->name); - } - mainloop(); - return EXIT_SUCCESS; - } - - // read options - - if (argc == 2) option_set("OptionFile",argv[1]); // HACK for compatibility - - parse_option(); // HACK: also launches the engine - - // EPD test - - if (argc >= 2 && my_string_equal(argv[1],"epd-test")){ - epd_test(argc,argv); - return EXIT_SUCCESS; - }else if(argc >= 3 && my_string_equal(argv[2],"epd-test")){ - epd_test(argc-1,argv+1); - return EXIT_SUCCESS; - } - - if (argc >= 3) my_fatal("Too many arguments\n"); - - - init_book(); - gui_init(GUI); - mainloop(); - return EXIT_SUCCESS; -} - -// polyglot_set_option - -void polyglot_set_option(char *name, char *value){ // this must be cleaned up! - option_set(name,value); - if(option_get_bool("Book")&&(my_string_case_equal(name,"BookFile")||my_string_case_equal(name,"Book"))){ - my_log("POLYGLOT *** SETTING BOOK ***\n"); - my_log("POLYGLOT BOOK \"%s\"\n",option_get_string("BookFile")); - book_close(); - book_clear(); - book_open(option_get_string("BookFile")); - if(!book_is_open()){ - my_log("POLYGLOT Unable to open book \"%s\"\n",option_get_string("BookFile")); - } - }else if(option_get_bool("Log")&&(my_string_case_equal(name,"LogFile") ||my_string_case_equal(name,"Log"))){ - my_log("POLYGLOT *** SETTING LOGFILE ***\n"); - my_log("POLYGLOT LOGFILE \"%s\"\n",option_get_string("LogFile")); - my_log_close(); - my_log_open(option_get_string("LogFile")); - }else if(option_get_bool("UseNice") &&(my_string_case_equal(name,"NiceValue")||my_string_case_equal(name,"UseNice"))){ - my_log("POLYGLOT Adjust Engine Piority\n"); - engine_set_nice_value(Engine,atoi(option_get_string("NiceValue"))); - }else if(my_string_case_equal(name,"Book") && !option_get_bool("Book")){ - book_close(); - book_clear(); - }else if(my_string_case_equal(name,"UseNice") && !option_get_bool("UseNice")){ - my_log("POLYGLOT Adjust Engine Piority\n"); - engine_set_nice_value(Engine,0); - }else if(my_string_case_equal(name,"Log") && !option_get_bool("Log")){ - my_log("POLYGLOT QUIT LOGGING\n"); - my_log_close(); - } -} - - -// init_book() - -static void init_book(){ - book_clear(); - if (option_get_bool("Book")){ - my_log("POLYGLOT *** SETTING BOOK ***\n"); - my_log("POLYGLOT BOOK \"%s\"\n",option_get_string("BookFile")); - book_open(option_get_string("BookFile")); - if(!book_is_open()){ - my_log("POLYGLOT Unable to open book \"%s\"\n", - option_get_string("BookFile")); - } - } -} - -// parse_option() - -static void parse_option() { - - const char * file_name; - FILE * file; - char line[256]; - char * name, * value; - file_name = option_get_string("OptionFile"); - - file = fopen(file_name,"r"); - if (file == NULL) { - my_fatal("Can't open file \"%s\": %s\n",file_name,strerror(errno)); - } - - // PolyGlot options (assumed first) - - while (true) { - - if (!my_file_read_line(file,line,256)) { - my_fatal("parse_option(): missing [Engine] section\n"); - } - - if (my_string_case_equal(line,"[engine]")) break; - - if (parse_line(line,&name,&value)) { - option_set(name,value); - option_set_default(name,value); - } - } - - if (option_get_bool("Log")) { - my_log_open(option_get_string("LogFile")); - } - - my_log("POLYGLOT *** START ***\n"); - my_log("POLYGLOT INI file \"%s\"\n",file_name); - engine_open(Engine); - if(!engine_active(Engine)){ - my_fatal("Could not start \"%s\"\n",option_get("EngineCommand")); - } - - if (option_get_bool("UCI")) { - my_log("POLYGLOT *** Switching to UCI mode ***\n"); - } - uci_open(Uci,Engine); - Init = true; - while (my_file_read_line(file,line,256)) { - if (line[0] == '[') my_fatal("parse_option(): unknown section %s\n",line); - if (parse_line(line,&name,&value)) { - uci_send_option(Uci,name,"%s",value); - //to get a decent display in winboard_x we need to now if an engine really is doing multipv analysis - // "multipv 1" in the pv is meaningless,f.i. toga sends that all the time - //therefore check if MultiPV is set to a decent value in the polyglot ini file - if(my_string_case_equal(name,"MultiPV") && atoi(value)>1) Uci->multipv_mode=true; - } - } - if (my_string_equal(option_get_string("EngineName"),"")) { - option_set("EngineName",Uci->name); - } - - fclose(file); -} - -// parse_line() - -static bool parse_line(char line[], char * * name_ptr, char * * value_ptr) { - - char * ptr; - char * name, * value; - - ASSERT(line!=NULL); - ASSERT(name_ptr!=NULL); - ASSERT(value_ptr!=NULL); - - // remove comments - - ptr = strchr(line,';'); - if (ptr != NULL) *ptr = '\0'; - - ptr = strchr(line,'#'); - if (ptr != NULL) *ptr = '\0'; - - // split at '=' - - ptr = strchr(line,'='); - if (ptr == NULL) return false; - - name = line; - value = ptr+1; - - // cleanup name - - while (*name == ' ') name++; // remove leading spaces - - while (ptr > name && ptr[-1] == ' ') ptr--; // remove trailing spaces - *ptr = '\0'; - - if (*name == '\0') return false; - - // cleanup value - - ptr = &value[strlen(value)]; // pointer to string terminator - - while (*value == ' ') value++; // remove leading spaces - - while (ptr > value && ptr[-1] == ' ') ptr--; // remove trailing spaces - *ptr = '\0'; - - if (*value == '\0') return false; - - // end - - *name_ptr = name; - *value_ptr = value; - - return true; -} - -// quit() - -void quit() { - - my_log("POLYGLOT *** QUIT ***\n"); - - if (Init) { - - stop_search(); - engine_send(Engine,"quit"); - my_log("POLYGLOT Closing engine\n"); - engine_close(Engine); - - } - my_log("POLYGLOT Calling exit\n"); - exit(EXIT_SUCCESS); -} - -// stop_search() - -static void stop_search() { - - if (Init && Uci->searching) { - - ASSERT(Uci->searching); - ASSERT(Uci->pending_nb>=1); - - my_log("POLYGLOT STOP SEARCH\n"); - - if (option_get_bool("SyncStop")) { - uci_send_stop_sync(Uci); - } else { - uci_send_stop(Uci); - } - } -} - - -// end of main.cpp - diff --git a/mainloop.cpp b/mainloop.cpp deleted file mode 100644 index 0bb378c..0000000 --- a/mainloop.cpp +++ /dev/null @@ -1,149 +0,0 @@ -// mainloop.cpp - -// constants - -static const int StringSize = 4096; - -// includes - -#include -#include -#include -#include - -#ifndef _WIN32 -#include -#include // Mac OS X needs this one -#include -#endif - -#include "main.h" -#include "engine.h" -#include "gui.h" -#include "option.h" -#include "xboard2uci.h" -#include "uci2uci.h" - -// prototypes - -static void mainloop_init (); -static void mainloop_wait_for_event (); -static void mainloop_engine_step(char * string); -static void mainloop_gui_step(char * string); - -// functions - -// mainloop_init() - -static void mainloop_init(){ - if(!option_get_bool("UCI")){ - xboard2uci_init(); // the default - } -} - -// mainloop_engine_step() - -static void mainloop_engine_step(char * string){ - if(option_get_bool("UCI")){ - uci2uci_engine_step(string); - }else{ - xboard2uci_engine_step(string); - } -} - -// mainloop_gui_step() - -static void mainloop_gui_step(char * string){ - if(option_get_bool("UCI")){ - uci2uci_gui_step(string); - }else if(my_string_equal(string,"uci")){ // mode auto detection - my_log("POLYGLOT *** Switching to UCI mode ***\n"); - option_set("UCI","true"); - uci2uci_gui_step(string); - }else{ - xboard2uci_gui_step(string); - } -} - -// mainloop() - -void mainloop() { - char string[StringSize]; - mainloop_init(); - while (!engine_eof(Engine)) { - // process buffered lines - while(TRUE){ - if(gui_get_non_blocking(GUI,string,StringSize)){ - mainloop_gui_step(string); - }else if(!engine_eof(Engine) && - engine_get_non_blocking(Engine,string,StringSize) ){ - mainloop_engine_step(string); - }else{ - break; - } - } - mainloop_wait_for_event(); - } - my_log("POLYGLOT *** Mainloop has ended ***\n"); - // This should be handled better. - engine_close(Engine); - my_log("POLYGLOT Calling exit\n"); - exit(EXIT_SUCCESS); - -} - - - - -// mainloop_wait_for_event() - -static void mainloop_wait_for_event(){ -#ifdef _WIN32 - HANDLE hHandles[2]; - char string[StringSize]; - hHandles[0]=(GUI->io).hEvent; - hHandles[1]=(Engine->io).hEvent; - WaitForMultipleObjects(2, // count - hHandles, // - FALSE, // return if one object is signaled - INFINITE // no timeout - ); -#else - fd_set set[1]; - int fd_max; - int val; - char string[StringSize]; - // init - - FD_ZERO(set); - fd_max = -1; // HACK - - // add gui input - - ASSERT(GUI->io->in_fd>=0); - - FD_SET(GUI->io->in_fd,set); - if (GUI->io->in_fd > fd_max) fd_max = GUI->io->in_fd; - - // add engine input - - ASSERT(Engine->io->in_fd>=0); - - FD_SET(Engine->io->in_fd,set); - if (Engine->io->in_fd > fd_max) fd_max = Engine->io->in_fd; - - // wait for something to read (no timeout) - - ASSERT(fd_max>=0); - val = select(fd_max+1,set,NULL,NULL,NULL); - if (val == -1 && errno != EINTR) my_fatal("adapter_step(): select(): %s\n",strerror(errno)); - - if (val > 0) { - if (FD_ISSET(GUI->io->in_fd,set)) io_get_update(GUI->io); // read some xboard input - if (FD_ISSET(Engine->io->in_fd,set)) io_get_update(Engine->io); // read some engine input - } -#endif -} - - - diff --git a/move.cpp b/move.cpp deleted file mode 100644 index 248ebdf..0000000 --- a/move.cpp +++ /dev/null @@ -1,380 +0,0 @@ - -// move.cpp - -// includes - -#include -#include - -#include "attack.h" -#include "colour.h" -#include "list.h" -#include "move.h" -#include "move_do.h" -#include "move_gen.h" -#include "move_legal.h" -#include "option.h" -#include "piece.h" -#include "square.h" -#include "util.h" - -// "constants" - -static const uint8 PromotePiece[5] = { PieceNone64, Knight64, Bishop64, Rook64, Queen64 }; - -// functions - -// move_is_ok() - -bool move_is_ok(int move) { - - if (move < 0 || move >= 65536) return false; - - if (move == MoveNone) return false; - - return true; -} - -// move_make() - -int move_make(int from, int to) { - - ASSERT(square_is_ok(from)); - ASSERT(square_is_ok(to)); - - return (square_to_64(from) << 6) | square_to_64(to); -} - -// move_make_flags() - -int move_make_flags(int from, int to, int flags) { - - ASSERT(square_is_ok(from)); - ASSERT(square_is_ok(to)); - ASSERT((flags&~0xF000)==0); - - ASSERT(to!=from); - - return (square_to_64(from) << 6) | square_to_64(to) | flags; -} - -// move_from() - -int move_from(int move) { - - int from_64; - - ASSERT(move_is_ok(move)); - - from_64 = (move >> 6) & 077; - - return square_from_64(from_64); -} - -// move_to() - -int move_to(int move) { - - int to_64; - - ASSERT(move_is_ok(move)); - - to_64 = move & 077; - - return square_from_64(to_64); -} - -// move_promote_hack() - -int move_promote_hack(int move) { - - int code; - - ASSERT(move_is_ok(move)); - - ASSERT(move_is_promote(move)); - - code = move >> 12; - ASSERT(code>=1&&code<=4); - - return PromotePiece[code]; -} - -// move_is_capture() - -bool move_is_capture(int move, const board_t * board) { - - ASSERT(move_is_ok(move)); - ASSERT(board_is_ok(board)); - - if (move_is_en_passant(move,board)) return true; - if (board->square[move_to(move)] != Empty) return true; - - return false; -} - -// move_is_promote() - -bool move_is_promote(int move) { - - ASSERT(move_is_ok(move)); - - return (move & MoveFlags) != 0; -} - -// move_is_en_passant() - -bool move_is_en_passant(int move, const board_t * board) { - - ASSERT(move_is_ok(move)); - ASSERT(board_is_ok(board)); - - return piece_is_pawn(move_piece(move,board)) - && move_to(move) == board->ep_square; -} - -// move_is_castle() - -bool move_is_castle(int move, const board_t * board) { - - ASSERT(move_is_ok(move)); - ASSERT(board_is_ok(board)); - - return colour_equal(board->square[move_to(move)],board->turn); -} - -// move_piece() - -int move_piece(int move, const board_t * board) { - - ASSERT(move_is_ok(move)); - ASSERT(board_is_ok(board)); - - return board->square[move_from(move)]; -} - -// move_capture() - -int move_capture(int move, const board_t * board) { - - ASSERT(move_is_ok(move)); - ASSERT(board_is_ok(board)); - - if (move_is_en_passant(move,board)) { - return piece_pawn_opp(move_piece(move,board)); - } - - return board->square[move_to(move)]; -} - -// move_promote() - -int move_promote(int move, const board_t * board) { - - int code; - - ASSERT(move_is_ok(move)); - ASSERT(board_is_ok(board)); - - if (move_is_promote(move)) { - code = move >> 12; - ASSERT(code>=1&&code<=4); - return PromotePiece[code] | board->turn; - } - - return Empty; -} - -// move_is_check() - -bool move_is_check(int move, const board_t * board) { - - board_t new_board[1]; - - ASSERT(move_is_ok(move)); - ASSERT(board_is_ok(board)); - - board_copy(new_board,board); - move_do(new_board,move); - ASSERT(!is_in_check(new_board,colour_opp(new_board->turn))); - - return board_is_check(new_board); -} - -// move_is_mate() - -bool move_is_mate(int move, const board_t * board) { - - board_t new_board[1]; - - ASSERT(move_is_ok(move)); - ASSERT(board_is_ok(board)); - - board_copy(new_board,board); - move_do(new_board,move); - ASSERT(!is_in_check(new_board,colour_opp(new_board->turn))); - - return board_is_mate(new_board); -} - -// move_to_can() - -bool move_to_can(int move, const board_t * board, char string[], int size) { - - int from, to; - - ASSERT(move_is_ok(move)); - ASSERT(board_is_ok(board)); - ASSERT(string!=NULL); - ASSERT(size>=6); - - ASSERT(move_is_legal(move,board)); - - if (size < 6) return false; - - // init - - from = move_from(move); - to = move_to(move); - - // king-slide castling - - if (move_is_castle(move,board) && !option_get_bool("Chess960")) { - if (false) { - } else if (from == E1 && to == H1) { - to = G1; - } else if (from == E1 && to == A1) { - to = C1; - } else if (from == E8 && to == H8) { - to = G8; - } else if (from == E8 && to == A8) { - to = C8; - } - } - - // normal moves - - if (!square_to_string(from,&string[0],3)) ASSERT(false); - if (!square_to_string(to,&string[2],3)) ASSERT(false); - ASSERT(strlen(string)==4); - - // promotes - - if (move_is_promote(move)) { - string[4] = piece_to_char(move_promote_hack(move)|Black); // HACK: black => lower-case - string[5] = '\0'; - } - - // debug - - ASSERT(move_from_can(string,board)==move); - - return true; -} - -// move_from_can() - -int move_from_can(const char string[], const board_t * board) { - - char tmp_string[256]; - int from, to; - int side; - int move; - - ASSERT(string!=NULL); - ASSERT(board_is_ok(board)); - - // from - - tmp_string[0] = string[0]; - tmp_string[1] = string[1]; - tmp_string[2] = '\0'; - - from = square_from_string(tmp_string); - if (from == SquareNone) return MoveNone; - - // to - - tmp_string[0] = string[2]; - tmp_string[1] = string[3]; - tmp_string[2] = '\0'; - - to = square_from_string(tmp_string); - if (to == SquareNone) return MoveNone; - - // convert "king slide" castling to KxR - - if (piece_is_king(board->square[from]) - && square_rank(to) == square_rank(from) - && abs(to-from) > 1) { - side = (to > from) ? SideH : SideA; - to = board->castle[board->turn][side]; - if (to == SquareNone) return MoveNone; - } - - // move - - move = move_make(from,to); - - // promote - - switch (string[4]) { - case '\0': // not a promotion - if (piece_is_pawn(board->square[from]) - && square_side_rank(to,board->turn) == Rank8 - && option_get_bool("PromoteWorkAround")) { - move |= MovePromoteQueen; - } - break; - case 'N': - case 'n': - move |= MovePromoteKnight; - break; - case 'B': - case 'b': - move |= MovePromoteBishop; - break; - case 'R': - case 'r': - move |= MovePromoteRook; - break; - case 'Q': - case 'q': - move |= MovePromoteQueen; - break; - default: - return MoveNone; - break; - } - - // debug - - ASSERT(move_is_legal(move,board)); - - return move; -} - -// move_order() - -int move_order(int move) { - - ASSERT(move_is_ok(move)); - - return ((move & 07777) << 3) | (move >> 12); // from, to, promote -} - -// move_disp() - -void move_disp(int move, const board_t * board) { - - char string[256]; - - ASSERT(move_is_ok(move)); - ASSERT(board_is_ok(board)); - - if (!move_to_can(move,board,string,256)) ASSERT(false); - my_log("POLYGLOT %s\n",string); -} - -// end of move.cpp - diff --git a/move_do.cpp b/move_do.cpp deleted file mode 100644 index b4b625a..0000000 --- a/move_do.cpp +++ /dev/null @@ -1,363 +0,0 @@ - -// move_do.cpp - -// includes - -#include - -#include "board.h" -#include "colour.h" -#include "hash.h" -#include "move.h" -#include "move_do.h" -#include "move_legal.h" -#include "piece.h" -#include "random.h" -#include "util.h" - -// prototypes - -static void square_clear (board_t * board, int square, int piece); -static void square_set (board_t * board, int square, int piece, int pos); -static void square_move (board_t * board, int from, int to, int piece); - -// functions - -// move_do() - -void move_do(board_t * board, int move) { - - int me, opp; - int from, to; - int piece, pos, capture; - int old_flags, new_flags; - int sq, ep_square; - int pawn; - - ASSERT(board_is_ok(board)); - ASSERT(move_is_ok(move)); - - ASSERT(move_is_pseudo(move,board)); - - // init - - me = board->turn; - opp = colour_opp(me); - - from = move_from(move); - to = move_to(move); - - piece = board->square[from]; - ASSERT(colour_equal(piece,me)); - - pos = board->pos[from]; - ASSERT(pos>=0); - - // update turn - - board->turn = opp; - board->key ^= random_64(RandomTurn); - - // update castling rights - - old_flags = board_flags(board); - - if (piece_is_king(piece)) { - board->castle[me][SideH] = SquareNone; - board->castle[me][SideA] = SquareNone; - } - - if (board->castle[me][SideH] == from) board->castle[me][SideH] = SquareNone; - if (board->castle[me][SideA] == from) board->castle[me][SideA] = SquareNone; - - if (board->castle[opp][SideH] == to) board->castle[opp][SideH] = SquareNone; - if (board->castle[opp][SideA] == to) board->castle[opp][SideA] = SquareNone; - - new_flags = board_flags(board); - - board->key ^= hash_castle_key(new_flags^old_flags); // HACK - - // update en-passant square - - ep_square = sq = board->ep_square; - if (sq != SquareNone) { - board->key ^= random_64(RandomEnPassant+square_file(sq)); - board->ep_square = SquareNone; - } - - if (piece_is_pawn(piece) && abs(to-from) == 32) { - pawn = piece_make_pawn(opp); - if (board->square[to-1] == pawn || board->square[to+1] == pawn) { - board->ep_square = sq = (from + to) / 2; - board->key ^= random_64(RandomEnPassant+square_file(sq)); - } - } - - // update ply number (captures are handled later) - - board->ply_nb++; - if (piece_is_pawn(piece)) board->ply_nb = 0; // conversion - - // update move number - - if (me == Black) board->move_nb++; - - // castle - - if (colour_equal(board->square[to],me)) { - - int rank; - int king_from, king_to; - int rook_from, rook_to; - int rook; - - rank = colour_is_white(me) ? Rank1 : Rank8; - - king_from = from; - rook_from = to; - - if (to > from) { // h side - king_to = square_make(FileG,rank); - rook_to = square_make(FileF,rank); - } else { // a side - king_to = square_make(FileC,rank); - rook_to = square_make(FileD,rank); - } - - // remove the rook - - pos = board->pos[rook_from]; - ASSERT(pos>=0); - - rook = Rook64 | me; // HACK - - square_clear(board,rook_from,rook); - - // move the king - - square_move(board,king_from,king_to,piece); - - // put the rook back - - square_set(board,rook_to,rook,pos); - - ASSERT(board->key==hash_key(board)); - - return; - } - - // remove the captured piece - - if (piece_is_pawn(piece) && to == ep_square) { - - // en-passant capture - - sq = square_ep_dual(to); - capture = board->square[sq]; - ASSERT(capture==piece_make_pawn(opp)); - - square_clear(board,sq,capture); - - board->ply_nb = 0; // conversion - - } else { - - capture = board->square[to]; - - if (capture != Empty) { - - // normal capture - - ASSERT(colour_equal(capture,opp)); - ASSERT(!piece_is_king(capture)); - - square_clear(board,to,capture); - - board->ply_nb = 0; // conversion - } - } - - // move the piece - - if (move_is_promote(move)) { - - // promote - - square_clear(board,from,piece); - piece = move_promote_hack(move) | me; // HACK - square_set(board,to,piece,pos); - - } else { - - // normal move - - square_move(board,from,to,piece); - } - - ASSERT(board->key==hash_key(board)); -} - -// square_clear() - -static void square_clear(board_t * board, int square, int piece) { - - int pos, piece_12, colour; - int sq, size; - - ASSERT(board!=NULL); - ASSERT(square_is_ok(square)); - ASSERT(piece_is_ok(piece)); - - // init - - pos = board->pos[square]; - ASSERT(pos>=0); - - colour = piece_colour(piece); - piece_12 = piece_to_12(piece); - - // square - - ASSERT(board->square[square]==piece); - board->square[square] = Empty; - - ASSERT(board->pos[square]==pos); - board->pos[square] = -1; // not needed - - // piece list - - ASSERT(board->list_size[colour]>=2); - size = --board->list_size[colour]; - ASSERT(pos<=size); - - if (pos != size) { - - sq = board->list[colour][size]; - ASSERT(square_is_ok(sq)); - ASSERT(sq!=square); - - ASSERT(board->pos[sq]==size); - board->pos[sq] = pos; - - ASSERT(board->list[colour][pos]==square); - board->list[colour][pos] = sq; - } - - board->list[colour][size] = SquareNone; - - // material - - ASSERT(board->number[piece_12]>=1); - board->number[piece_12]--; - - // hash key - - board->key ^= random_64(RandomPiece+piece_12*64+square_to_64(square)); -} - -// square_set() - -static void square_set(board_t * board, int square, int piece, int pos) { - - int piece_12, colour; - int sq, size; - - ASSERT(board!=NULL); - ASSERT(square_is_ok(square)); - ASSERT(piece_is_ok(piece)); - ASSERT(pos>=0); - - // init - - colour = piece_colour(piece); - piece_12 = piece_to_12(piece); - - // square - - ASSERT(board->square[square]==Empty); - board->square[square] = piece; - - ASSERT(board->pos[square]==-1); - board->pos[square] = pos; - - // piece list - - size = board->list_size[colour]++; - ASSERT(board->list[colour][size]==SquareNone); - ASSERT(pos<=size); - - if (pos != size) { - - sq = board->list[colour][pos]; - ASSERT(square_is_ok(sq)); - ASSERT(sq!=square); - - ASSERT(board->pos[sq]==pos); - board->pos[sq] = size; - - ASSERT(board->list[colour][size]==SquareNone); - board->list[colour][size] = sq; - } - - board->list[colour][pos] = square; - - // material - - ASSERT(board->number[piece_12]<=8); - board->number[piece_12]++; - - // hash key - - board->key ^= random_64(RandomPiece+piece_12*64+square_to_64(square)); -} - -// square_move() - -static void square_move(board_t * board, int from, int to, int piece) { - - int colour, pos; - int piece_index; - - ASSERT(board!=NULL); - ASSERT(square_is_ok(from)); - ASSERT(square_is_ok(to)); - ASSERT(piece_is_ok(piece)); - - // init - - colour = piece_colour(piece); - - pos = board->pos[from]; - ASSERT(pos>=0); - - // from - - ASSERT(board->square[from]==piece); - board->square[from] = Empty; - - ASSERT(board->pos[from]==pos); - board->pos[from] = -1; // not needed - - // to - - ASSERT(board->square[to]==Empty); - board->square[to] = piece; - - ASSERT(board->pos[to]==-1); - board->pos[to] = pos; - - // piece list - - ASSERT(board->list[colour][pos]==from); - board->list[colour][pos] = to; - - // hash key - - piece_index = RandomPiece + piece_to_12(piece) * 64; - - board->key ^= random_64(piece_index+square_to_64(from)) - ^ random_64(piece_index+square_to_64(to)); -} - -// end of move_do.cpp - diff --git a/move_gen.cpp b/move_gen.cpp deleted file mode 100644 index 5023885..0000000 --- a/move_gen.cpp +++ /dev/null @@ -1,328 +0,0 @@ - -// move_gen.cpp - -// includes - -#include "attack.h" -#include "board.h" -#include "colour.h" -#include "list.h" -#include "move.h" -#include "move_gen.h" -#include "move_legal.h" -#include "piece.h" -#include "util.h" - -// prototypes - -static void add_all_moves (list_t * list, const board_t * board); -static void add_castle_moves (list_t * list, const board_t * board); - -static void add_pawn_move (list_t * list, int from, int to); - -// functions - -// gen_legal_moves() - -void gen_legal_moves(list_t * list, const board_t * board) { - - ASSERT(list!=NULL); - ASSERT(board_is_ok(board)); - - gen_moves(list,board); - filter_legal(list,board); -} - -// gen_moves() - -void gen_moves(list_t * list, const board_t * board) { - - ASSERT(list!=NULL); - ASSERT(board_is_ok(board)); - - list_clear(list); - - add_all_moves(list,board); - if (!is_in_check(board,board->turn)) add_castle_moves(list,board); -} - -// add_all_moves() - -static void add_all_moves(list_t * list, const board_t * board) { - - int me, opp; - const uint8 * ptr; - const sint8 * ptr_inc; - int from, to; - int inc; - int piece, capture; - - ASSERT(list_is_ok(list)); - ASSERT(board_is_ok(board)); - - me = board->turn; - opp = colour_opp(me); - - for (ptr = board->list[me]; (from=*ptr) != SquareNone; ptr++) { - - piece = board->square[from]; - ASSERT(colour_equal(piece,me)); - - switch (piece_type(piece)) { - - case WhitePawn64: - - to = from + 15; - if (to == board->ep_square || colour_equal(board->square[to],opp)) { - add_pawn_move(list,from,to); - } - - to = from + 17; - if (to == board->ep_square || colour_equal(board->square[to],opp)) { - add_pawn_move(list,from,to); - } - - to = from + 16; - if (board->square[to] == Empty) { - add_pawn_move(list,from,to); - if (square_rank(from) == Rank2) { - to = from + 32; - if (board->square[to] == Empty) { - ASSERT(!square_is_promote(to)); - list_add(list,move_make(from,to)); - } - } - } - - break; - - case BlackPawn64: - - to = from - 17; - if (to == board->ep_square || colour_equal(board->square[to],opp)) { - add_pawn_move(list,from,to); - } - - to = from - 15; - if (to == board->ep_square || colour_equal(board->square[to],opp)) { - add_pawn_move(list,from,to); - } - - to = from - 16; - if (board->square[to] == Empty) { - add_pawn_move(list,from,to); - if (square_rank(from) == Rank7) { - to = from - 32; - if (board->square[to] == Empty) { - ASSERT(!square_is_promote(to)); - list_add(list,move_make(from,to)); - } - } - } - - break; - - case Knight64: - - for (ptr_inc = KnightInc; (inc=*ptr_inc) != IncNone; ptr_inc++) { - to = from + inc; - capture = board->square[to]; - if (capture == Empty || colour_equal(capture,opp)) { - list_add(list,move_make(from,to)); - } - } - - break; - - case Bishop64: - - for (ptr_inc = BishopInc; (inc=*ptr_inc) != IncNone; ptr_inc++) { - for (to = from+inc; (capture=board->square[to]) == Empty; to += inc) { - list_add(list,move_make(from,to)); - } - if (colour_equal(capture,opp)) { - list_add(list,move_make(from,to)); - } - } - - break; - - case Rook64: - - for (ptr_inc = RookInc; (inc=*ptr_inc) != IncNone; ptr_inc++) { - for (to = from+inc; (capture=board->square[to]) == Empty; to += inc) { - list_add(list,move_make(from,to)); - } - if (colour_equal(capture,opp)) { - list_add(list,move_make(from,to)); - } - } - - break; - - case Queen64: - - for (ptr_inc = QueenInc; (inc=*ptr_inc) != IncNone; ptr_inc++) { - for (to = from+inc; (capture=board->square[to]) == Empty; to += inc) { - list_add(list,move_make(from,to)); - } - if (colour_equal(capture,opp)) { - list_add(list,move_make(from,to)); - } - } - - break; - - case King64: - - for (ptr_inc = KingInc; (inc=*ptr_inc) != IncNone; ptr_inc++) { - to = from + inc; - capture = board->square[to]; - if (capture == Empty || colour_equal(capture,opp)) { - list_add(list,move_make(from,to)); - } - } - - break; - - default: - - ASSERT(false); - break; - } - } -} - -// add_castle_moves() - -static void add_castle_moves(list_t * list, const board_t * board) { - - int me, opp; - int rank; - int king_from, king_to; - int rook_from, rook_to; - bool legal; - int inc; - int sq; - - ASSERT(list_is_ok(list)); - ASSERT(board_is_ok(board)); - - ASSERT(!is_in_check(board,board->turn)); - - me = board->turn; - opp = colour_opp(me); - - rank = colour_is_white(me) ? Rank1 : Rank8; - - // h-side castling - - if (board->castle[me][SideH] != SquareNone) { - - king_from = king_pos(board,me); - king_to = square_make(FileG,rank); - rook_from = board->castle[me][SideH]; - rook_to = square_make(FileF,rank); - - ASSERT(square_rank(king_from)==rank); - ASSERT(square_rank(rook_from)==rank); - ASSERT(board->square[king_from]==(King64|me)); // HACK - ASSERT(board->square[rook_from]==(Rook64|me)); // HACK - ASSERT(rook_from>king_from); - - legal = true; - - if (king_to != king_from) { - - inc = (king_to > king_from) ? +1 : -1; - - for (sq = king_from+inc; true; sq += inc) { - - if (sq != rook_from && board->square[sq] != Empty) legal = false; - if (is_attacked(board,sq,opp)) legal = false; - - if (sq == king_to) break; - } - } - - if (rook_to != rook_from) { - - inc = (rook_to > rook_from) ? +1 : -1; - - for (sq = rook_from+inc; true; sq += inc) { - if (sq != king_from && board->square[sq] != Empty) legal = false; - if (sq == rook_to) break; - } - } - - if (legal) list_add(list,move_make(king_from,rook_from)); - } - - // a-side castling - - if (board->castle[me][SideA] != SquareNone) { - - king_from = king_pos(board,me); - king_to = square_make(FileC,rank); - rook_from = board->castle[me][SideA]; - rook_to = square_make(FileD,rank); - - ASSERT(square_rank(king_from)==rank); - ASSERT(square_rank(rook_from)==rank); - ASSERT(board->square[king_from]==(King64|me)); // HACK - ASSERT(board->square[rook_from]==(Rook64|me)); // HACK - ASSERT(rook_from king_from) ? +1 : -1; - - for (sq = king_from+inc; true; sq += inc) { - - if (sq != rook_from && board->square[sq] != Empty) legal = false; - if (is_attacked(board,sq,opp)) legal = false; - - if (sq == king_to) break; - } - } - - if (rook_to != rook_from) { - - inc = (rook_to > rook_from) ? +1 : -1; - - for (sq = rook_from+inc; true; sq += inc) { - if (sq != king_from && board->square[sq] != Empty) legal = false; - if (sq == rook_to) break; - } - } - - if (legal) list_add(list,move_make(king_from,rook_from)); - } -} - -// add_pawn_move() - -static void add_pawn_move(list_t * list, int from, int to) { - - int move; - - ASSERT(list_is_ok(list)); - ASSERT(square_is_ok(from)); - ASSERT(square_is_ok(to)); - - move = move_make(from,to); - - if (square_is_promote(to)) { - list_add(list,move|MovePromoteKnight); - list_add(list,move|MovePromoteBishop); - list_add(list,move|MovePromoteRook); - list_add(list,move|MovePromoteQueen); - } else { - list_add(list,move); - } -} - -// end of move_gen.cpp - diff --git a/move_legal.cpp b/move_legal.cpp deleted file mode 100644 index 93e9567..0000000 --- a/move_legal.cpp +++ /dev/null @@ -1,115 +0,0 @@ - -// move_legal.cpp - -// includes - -#include "attack.h" -#include "colour.h" -#include "fen.h" -#include "list.h" -#include "move.h" -#include "move_do.h" -#include "move_gen.h" -#include "move_legal.h" -#include "piece.h" -#include "square.h" -#include "util.h" - -// prototypes - -static bool move_is_legal_debug (int move, const board_t * board); - -// functions - -// move_is_pseudo() - -bool move_is_pseudo(int move, const board_t * board) { - - list_t list[1]; - - ASSERT(move_is_ok(move)); - ASSERT(board_is_ok(board)); - - gen_moves(list,board); - - return list_contain(list,move); -} - -// pseudo_is_legal() - -bool pseudo_is_legal(int move, const board_t * board) { - - board_t new_board[1]; - - ASSERT(move_is_ok(move)); - ASSERT(board_is_ok(board)); - - ASSERT(move_is_pseudo(move,board)); - - board_copy(new_board,board); - move_do(new_board,move); - - return !is_in_check(new_board,colour_opp(new_board->turn)); -} - -// move_is_legal() - -bool move_is_legal(int move, const board_t * board) { - - bool legal; - - ASSERT(move_is_ok(move)); - ASSERT(board_is_ok(board)); - - legal = move_is_pseudo(move,board) && pseudo_is_legal(move,board); - ASSERT(legal==move_is_legal_debug(move,board)); - - return legal; -} - -// filter_legal() - -void filter_legal(list_t * list, const board_t * board) { - - int pos; - int i, move, value; - - ASSERT(list_is_ok(list)); - ASSERT(board_is_ok(board)); - - pos = 0; - - for (i = 0; i < list_size(list); i++) { - - ASSERT(pos>=0&&pos<=i); - - move = list_move(list,i); - value = list_value(list,i); - - if (pseudo_is_legal(move,board)) { - list->move[pos] = move; - list->value[pos] = value; - pos++; - } - } - - ASSERT(pos>=0&&pos<=list_size(list)); - list->size = pos; -} - -// move_is_legal_debug() - -static bool move_is_legal_debug(int move, const board_t * board) { - - list_t list[1]; - - ASSERT(move_is_ok(move)); - ASSERT(board_is_ok(board)); - - gen_legal_moves(list,board); - - return list_contain(list,move); -} - -// end of move_legal.cpp - diff --git a/option.cpp b/option.cpp deleted file mode 100644 index a2e45ae..0000000 --- a/option.cpp +++ /dev/null @@ -1,230 +0,0 @@ - -// option.cpp - -// includes - -#include -#include - -#include "option.h" -#include "util.h" - -// constants - -static const bool UseDebug = false; - - -// variables - -#define NNB { NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL } -option_t Option[] = { - - { "OptionFile", "string","0","0", "polyglot.ini", NULL,0,NNB, PG}, - - // options - - { "EngineName", "string","0","0", "" , NULL,0,NNB, PG}, - { "EngineDir", "string","0","0", "." , NULL,0,NNB, PG}, - { "EngineCommand", "string","0","0", "" , NULL,0,NNB, PG}, - - { "Log", "check","0","0", "false" , NULL,0,NNB, PG|XBOARD|UCI}, - { "LogFile", "string","0","0", "polyglot.log", NULL,0,NNB, PG|XBOARD|UCI}, - - { "UCI", "string","0","0", "false" , NULL,0,NNB, PG}, - - { "UseNice", "check","0","0", "false" , NULL,0,NNB, PG|XBOARD|UCI}, - { "NiceValue", "spin", "0","20", "5" , NULL,0,NNB, PG|XBOARD|UCI}, - - { "Chess960", "check","0","0", "false" , NULL,0,NNB, PG|XBOARD}, - - { "Resign", "check","0","0", "false" , NULL,0,NNB, PG|XBOARD}, - { "ResignMoves", "spin","0","10000", "3" , NULL,0,NNB, PG|XBOARD}, - { "ResignScore", "spin","0","10000", "600" , NULL,0,NNB, PG|XBOARD}, - - { "MateScore", "spin","0","1000000", "10000" , NULL,0,NNB, PG|XBOARD}, - - { "Book", "check","0","0", "false" , NULL,0,NNB, PG|XBOARD|UCI}, - { "BookFile", "string","0","0", "book.bin" , NULL,0,NNB, PG|XBOARD|UCI}, - - { "BookRandom", "check","0","0", "true" , NULL,0,NNB, PG|XBOARD|UCI}, - { "BookLearn", "check","0","0", "false" , NULL,0,NNB, PG|XBOARD}, - - { "KibitzMove", "check","0","0", "false" , NULL,0,NNB, PG|XBOARD}, - { "KibitzPV", "check","0","0", "false" , NULL,0,NNB, PG|XBOARD}, - - { "KibitzCommand", "string","0","0", "tellall" , NULL,0,NNB, PG|XBOARD}, - { "KibitzDelay", "spin","0","10000", "5" , NULL,0,NNB, PG|XBOARD}, - { "KibitzInterval", "spin","0","10000", "0" , NULL,0,NNB, PG|XBOARD}, - - { "ShowPonder", "check","0","0", "false" , NULL,0,NNB, PG|XBOARD}, - { "ScoreWhite", "check","0","0", "false" , NULL,0,NNB, PG|XBOARD}, - - // work-arounds - - { "UCIVersion", "spin","1","2", "2" , NULL,0,NNB, PG|XBOARD}, - { "CanPonder", "check","1","2", "false" , NULL,0,NNB, PG|XBOARD}, - { "SyncStop", "check","1","2", "false" , NULL,0,NNB, PG|XBOARD}, - { "Affinity", "spin","-1","32", "-1" , NULL,0,NNB, PG}, - { "RepeatPV", "check","0","0", "true" , NULL,0,NNB, PG|XBOARD}, - { "PromoteWorkAround","check","0","0", "false" , NULL,0,NNB, PG|XBOARD}, - - { NULL, NULL,"0","0", NULL , NULL,0,NNB, 0}, -}; - -// prototypes - -static option_t * option_find (const char var[]); - -// functions - -// option_init() - -void option_init() { - - option_t *p=Option; - const char * name; - - while((name=(p++)->name)){ - option_set(name,option_get_default(name)); - } -} - - -// option_set() - -bool option_set(const char name[], const char value[]) { - - option_t * opt; - ASSERT(name!=NULL); - ASSERT(value!=NULL); - - opt = option_find(name); - if (opt == NULL) return false; - - my_string_set(&opt->value,value); - - if (UseDebug) my_log("POLYGLOT OPTION SET \"%s\" -> \"%s\"\n",opt->name,opt->value); - - return true; -} -// option_set() - -bool option_set_default(const char name[], const char value[]) { - - option_t * opt; - ASSERT(name!=NULL); - ASSERT(value!=NULL); - - opt = option_find(name); - if (opt == NULL) return false; - - opt->default_=my_strdup(value); - - if (UseDebug) my_log("POLYGLOT OPTION DEFAULT SET \"%s\" -> \"%s\"\n",opt->name,opt->default_); - - return true; -} - -// option_get() - -const char * option_get(const char name[]) { - - option_t * opt; - - ASSERT(name!=NULL); - - opt = option_find(name); - if (opt == NULL) my_fatal("option_get(): unknown option \"%s\"\n",name); - - if (UseDebug) my_log("POLYGLOT OPTION GET \"%s\" -> \"%s\"\n",opt->name,opt->value); - - return opt->value; -} - -// option_get_default() - -const char * option_get_default(const char name[]) { - - option_t * opt; - - ASSERT(name!=NULL); - - opt = option_find(name); - if (opt == NULL) my_fatal("option_get(): unknown option \"%s\"\n",name); - - if (UseDebug) my_log("POLYGLOT OPTION GET \"%s\" -> \"%s\"\n",opt->name,opt->value); - - return opt->default_; -} - -// option_get_bool() - -bool option_get_bool(const char name[]) { - - const char * value; - - value = option_get(name); - - if (false) { - } else if (my_string_case_equal(value,"true") || my_string_case_equal(value,"yes") || my_string_equal(value,"1")) { - return true; - } else if (my_string_case_equal(value,"false") || my_string_case_equal(value,"no") || my_string_equal(value,"0")) { - return false; - } - - ASSERT(false); - - return false; -} - -// option_get_double() - -double option_get_double(const char name[]) { - - const char * value; - - value = option_get(name); - - return atof(value); -} - -// option_get_int() - -int option_get_int(const char name[]) { - - const char * value; - - value = option_get(name); - - return atoi(value); -} - -// option_get_string() - -const char * option_get_string(const char name[]) { - - const char * value; - - value = option_get(name); - - return value; -} - -// option_find() - -static option_t * option_find(const char name[]) { - - option_t * opt; - - ASSERT(name!=NULL); - - - for (opt = &Option[0]; opt->name != NULL; opt++) { - if (my_string_case_equal(opt->name,name)) return opt; - } - - return NULL; -} - -// end of option.cpp - diff --git a/parse.cpp b/parse.cpp deleted file mode 100644 index f2340f4..0000000 --- a/parse.cpp +++ /dev/null @@ -1,264 +0,0 @@ - -// parse.cpp - -// includes - -#include - -#include "parse.h" -#include "util.h" - -// constants - -static const int StringSize = 256; - -// variables - -char * Star[STAR_NUMBER]; - -// prototypes - -static bool match_rec (char string[], const char pattern[], char * star[]); - -// functions - -// match() - -bool match(char string[], const char pattern[]) { - - ASSERT(string!=NULL); - ASSERT(pattern!=NULL); - - ASSERT(strstr(pattern,"**")==NULL); - - return match_rec(string,pattern,Star); -} - -// match_rec() - -static bool match_rec(char string[], const char pattern[], char * star[]) { - - int c; - - ASSERT(string!=NULL); - ASSERT(pattern!=NULL); - ASSERT(star!=NULL); - - // iterative matches - - while ((c=*pattern++) != '*') { - if (false) { - } else if (c == '\0') { // end of pattern - while (*string == ' ') string++; // skip trailing spaces - return *string == '\0'; - } else if (c == ' ') { // spaces - if (*string++ != ' ') return false; // mismatch - while (*string == ' ') string++; // skip trailing spaces - } else { // normal character - if (*string++ != c) return false; // mismatch - } - } - - // recursive wildcard match - - ASSERT(c=='*'); - - while (*string == ' ') string++; // skip leading spaces - *star++ = string; // remember beginning of star - - while ((c=*string++) != '\0') { // reject empty-string match - if (c != ' ' && match_rec(string,pattern,star)) { // shortest match - ASSERT(string>star[-1]); - *string = '\0'; // truncate star - return true; - } - } - - return false; -} - -// parse_is_ok() - -bool parse_is_ok(const parse_t * parse) { - - if (parse == NULL) return false; - if (parse->string == NULL) return false; - if (parse->pos < 0 || parse->pos > (int) strlen(parse->string)) return false; - if (parse->keyword_nb < 0 || parse->keyword_nb >= KEYWORD_NUMBER) return false; - - return true; -} - -// parse_open() - -void parse_open(parse_t * parse, const char string[]) { - - ASSERT(parse!=NULL); - ASSERT(string!=NULL); - - parse->string = string; - parse->pos = 0; - parse->keyword_nb = 0; -} - -// parse_close() - -void parse_close(parse_t * parse) { - - int i; - - ASSERT(parse_is_ok(parse)); - - parse->string = NULL; - parse->pos = 0; - - for (i = 0; i < parse->keyword_nb; i++) { - my_string_clear(&parse->keyword[i]); - } - - parse->keyword_nb = 0; -} - -// parse_add_keyword() - -void parse_add_keyword(parse_t * parse, const char keyword[]) { - - const char * * string; - - ASSERT(parse_is_ok(parse)); - ASSERT(keyword!=NULL); - - if (parse->keyword_nb < KEYWORD_NUMBER) { - - string = &parse->keyword[parse->keyword_nb]; - parse->keyword_nb++; - - *string = NULL; - my_string_set(string,keyword); - } -} - -// parse_get_word() - -bool parse_get_word(parse_t * parse, char string[], int size) { - - int pos; - int c; - - ASSERT(parse!=NULL); - ASSERT(string!=NULL); - ASSERT(size>=256); - - // skip blanks - - for (; parse->string[parse->pos] == ' '; parse->pos++) - ; - - ASSERT(parse->string[parse->pos]!=' '); - - // copy word - - pos = 0; - - while (true) { - - c = parse->string[parse->pos]; - if (c == ' ' || pos >= size-1) c = '\0'; - - string[pos] = c; - if (c == '\0') break; - - parse->pos++; - pos++; - } - - ASSERT(strchr(string,' ')==NULL); - - return pos > 0; // non-empty word? -} - -// parse_get_string() - -bool parse_get_string(parse_t * parse, char string[], int size) { - - int pos; - parse_t parse_2[1]; - char word[StringSize]; - int i; - int c; - - ASSERT(parse!=NULL); - ASSERT(string!=NULL); - ASSERT(size>=256); - - // skip blanks - - for (; parse->string[parse->pos] == ' '; parse->pos++) - ; - - ASSERT(parse->string[parse->pos]!=' '); - - // copy string - - pos = 0; - - while (true) { - - parse_open(parse_2,&parse->string[parse->pos]); - - if (!parse_get_word(parse_2,word,StringSize)) { - string[pos] = '\0'; - parse_close(parse_2); - goto finished; - } - - for (i = 0; i < parse->keyword_nb; i++) { - if (my_string_equal(parse->keyword[i],word)) { - string[pos] = '\0'; - parse_close(parse_2); - goto finished; - } - } - - parse_close(parse_2); - - // copy spaces - - while (true) { - - c = parse->string[parse->pos]; - if (c != ' ') break; - - if (pos >= size-1) c = '\0'; - - string[pos] = c; - if (c == '\0') break; - - parse->pos++; - pos++; - } - - // copy non spaces - - while (true) { - - c = parse->string[parse->pos]; - if (c == ' ' || pos >= size-1) c = '\0'; - - string[pos] = c; - if (c == '\0') break; - - parse->pos++; - pos++; - } - - string[pos] = '\0'; - } - -finished: ; - - return pos > 0; // non-empty string? -} - -// end of parse.cpp - diff --git a/pgn.cpp b/pgn.cpp deleted file mode 100644 index 5fe07fe..0000000 --- a/pgn.cpp +++ /dev/null @@ -1,641 +0,0 @@ - -// pgn.cpp - -// includes - -#include -#include -#include -#include - -#include "pgn.h" -#include "util.h" - -// constants - -static const bool DispMove = false; -static const bool DispToken = false; -static const bool DispChar = false; - -static const int TAB_SIZE = 8; - -static const int CHAR_EOF = 256; - -// types - -enum token_t { - TOKEN_ERROR = -1, - TOKEN_EOF = 256, - TOKEN_SYMBOL = 257, - TOKEN_STRING = 258, - TOKEN_INTEGER = 259, - TOKEN_NAG = 260, - TOKEN_RESULT = 261 -}; - -// prototypes - -static void pgn_token_read (pgn_t * pgn); -static void pgn_token_unread (pgn_t * pgn); - -static void pgn_read_token (pgn_t * pgn); - -static bool is_symbol_start (int c); -static bool is_symbol_next (int c); - -static void pgn_skip_blanks (pgn_t * pgn); - -static void pgn_char_read (pgn_t * pgn); -static void pgn_char_unread (pgn_t * pgn); - -// functions - -// pgn_open() - -void pgn_open(pgn_t * pgn, const char file_name[]) { - - ASSERT(pgn!=NULL); - ASSERT(file_name!=NULL); - - pgn->file = fopen(file_name,"r"); - if (pgn->file == NULL) my_fatal("pgn_open(): can't open file \"%s\": %s\n",file_name,strerror(errno)); - - pgn->char_hack = CHAR_EOF; // DEBUG - pgn->char_line = 1; - pgn->char_column = 0; - pgn->char_unread = false; - pgn->char_first = true; - - pgn->token_type = TOKEN_ERROR; // DEBUG - strcpy(pgn->token_string,"?"); // DEBUG - pgn->token_length = -1; // DEBUG - pgn->token_line = -1; // DEBUG - pgn->token_column = -1; // DEBUG - pgn->token_unread = false; - pgn->token_first = true; - - strcpy(pgn->result,"?"); // DEBUG - strcpy(pgn->fen,"?"); // DEBUG - - pgn->move_line = -1; // DEBUG - pgn->move_column = -1; // DEBUG -} - -// pgn_close() - -void pgn_close(pgn_t * pgn) { - - ASSERT(pgn!=NULL); - - fclose(pgn->file); -} - -// pgn_next_game() - -bool pgn_next_game(pgn_t * pgn) { - - char name[PGN_STRING_SIZE]; - char value[PGN_STRING_SIZE]; - - ASSERT(pgn!=NULL); - - // init - - strcpy(pgn->result,"*"); - strcpy(pgn->fen,""); - - // loop - - while (true) { - - pgn_token_read(pgn); - - if (pgn->token_type != '[') break; - - // tag - - pgn_token_read(pgn); - if (pgn->token_type != TOKEN_SYMBOL) { - my_fatal("pgn_next_game(): malformed tag at line %d, column %d, game %d\n",pgn->token_line,pgn->token_column,pgn->game_nb); - } - strcpy(name,pgn->token_string); - - pgn_token_read(pgn); - if (pgn->token_type != TOKEN_STRING) { - my_fatal("pgn_next_game(): malformed tag at line %d, column %d, game %d\n",pgn->token_line,pgn->token_column,pgn->game_nb); - } - strcpy(value,pgn->token_string); - - pgn_token_read(pgn); - if (pgn->token_type != ']') { - my_fatal("pgn_next_game(): malformed tag at line %d, column %d, game %d\n",pgn->token_line,pgn->token_column,pgn->game_nb); - } - - // special tag? - - if (false) { - } else if (my_string_equal(name,"Result")) { - strcpy(pgn->result,value); - } else if (my_string_equal(name,"FEN")) { - strcpy(pgn->fen,value); - } - } - - if (pgn->token_type == TOKEN_EOF) return false; - - pgn_token_unread(pgn); - - return true; -} - -// pgn_next_move() - -bool pgn_next_move(pgn_t * pgn, char string[], int size) { - - int depth; - - ASSERT(pgn!=NULL); - ASSERT(string!=NULL); - ASSERT(size>=PGN_STRING_SIZE); - - // init - - pgn->move_line = -1; // DEBUG - pgn->move_column = -1; // DEBUG - - // loop - - depth = 0; - - while (true) { - - pgn_token_read(pgn); - - if (false) { - - } else if (pgn->token_type == '(') { - - // open RAV - - depth++; - - } else if (pgn->token_type == ')') { - - // close RAV - - if (depth == 0) { - my_fatal("pgn_next_move(): malformed variation at line %d, column %d, game %d\n",pgn->token_line,pgn->token_column,pgn->game_nb); - } - - depth--; - ASSERT(depth>=0); - - } else if (pgn->token_type == TOKEN_RESULT) { - - // game finished - - if (depth > 0) { - my_fatal("pgn_next_move(): malformed variation at line %d, column %d, game %d\n",pgn->token_line,pgn->token_column,pgn->game_nb); - } - - return false; - - } else { - - // skip optional move number - - if (pgn->token_type == TOKEN_INTEGER) { - do pgn_token_read(pgn); while (pgn->token_type == '.'); - } - - // move must be a symbol - - if (pgn->token_type != TOKEN_SYMBOL) { - my_fatal("pgn_next_move(): malformed move at line %d, column %d, game %d\n",pgn->token_line,pgn->token_column,pgn->game_nb); - } - - // store move for later use - - if (depth == 0) { - - if (pgn->token_length >= size) { - my_fatal("pgn_next_move(): move too long at line %d, column %d, game %d\n",pgn->token_line,pgn->token_column,pgn->game_nb); - } - - strcpy(string,pgn->token_string); - pgn->move_line = pgn->token_line; - pgn->move_column = pgn->token_column; - } - - // skip optional NAGs - - do pgn_token_read(pgn); while (pgn->token_type == TOKEN_NAG); - pgn_token_unread(pgn); - - // return move - - if (depth == 0) { - if (DispMove) printf("move=\"%s\"\n",string); - return true; - } - } - } - - ASSERT(false); - - return false; -} - -// pgn_token_read() - -static void pgn_token_read(pgn_t * pgn) { - - ASSERT(pgn!=NULL); - - // token "stack" - - if (pgn->token_unread) { - pgn->token_unread = false; - return; - } - - // consume the current token - - if (pgn->token_first) { - pgn->token_first = false; - } else { - ASSERT(pgn->token_type!=TOKEN_ERROR); - ASSERT(pgn->token_type!=TOKEN_EOF); - } - - // read a new token - - pgn_read_token(pgn); - if (pgn->token_type == TOKEN_ERROR) my_fatal("pgn_token_read(): lexical error at line %d, column %d, game %d\n",pgn->char_line,pgn->char_column,pgn->game_nb); - - if (DispToken) printf("< L%d C%d \"%s\" (%03X)\n",pgn->token_line,pgn->token_column,pgn->token_string,pgn->token_type); -} - -// pgn_token_unread() - -static void pgn_token_unread(pgn_t * pgn) { - - ASSERT(pgn!=NULL); - - ASSERT(!pgn->token_unread); - ASSERT(!pgn->token_first); - - pgn->token_unread = true; -} - -// pgn_read_token() - -static void pgn_read_token(pgn_t * pgn) { - - ASSERT(pgn!=NULL); - - // skip white-space characters - - pgn_skip_blanks(pgn); - - // init - - pgn->token_type = TOKEN_ERROR; - strcpy(pgn->token_string,""); - pgn->token_length = 0; - pgn->token_line = pgn->char_line; - pgn->token_column = pgn->char_column; - - // determine token type - - if (false) { - - } else if (pgn->char_hack == CHAR_EOF) { - - pgn->token_type = TOKEN_EOF; - - } else if (strchr(".[]()<>",pgn->char_hack) != NULL) { - - // single-character token - - pgn->token_type = pgn->char_hack; - sprintf(pgn->token_string,"%c",pgn->char_hack); - pgn->token_length = 1; - - } else if (pgn->char_hack == '*') { - - pgn->token_type = TOKEN_RESULT; - sprintf(pgn->token_string,"%c",pgn->char_hack); - pgn->token_length = 1; - - } else if (pgn->char_hack == '!') { - - pgn_char_read(pgn); - - if (false) { - - } else if (pgn->char_hack == '!') { // "!!" - - pgn->token_type = TOKEN_NAG; - strcpy(pgn->token_string,"3"); - pgn->token_length = 1; - - } else if (pgn->char_hack == '?') { // "!?" - - pgn->token_type = TOKEN_NAG; - strcpy(pgn->token_string,"5"); - pgn->token_length = 1; - - } else { // "!" - - pgn_char_unread(pgn); - - pgn->token_type = TOKEN_NAG; - strcpy(pgn->token_string,"1"); - pgn->token_length = 1; - } - - } else if (pgn->char_hack == '?') { - - pgn_char_read(pgn); - - if (false) { - - } else if (pgn->char_hack == '?') { // "??" - - pgn->token_type = TOKEN_NAG; - strcpy(pgn->token_string,"4"); - pgn->token_length = 1; - - } else if (pgn->char_hack == '!') { // "?!" - - pgn->token_type = TOKEN_NAG; - strcpy(pgn->token_string,"6"); - pgn->token_length = 1; - - } else { // "?" - - pgn_char_unread(pgn); - - pgn->token_type = TOKEN_NAG; - strcpy(pgn->token_string,"2"); - pgn->token_length = 1; - } - - } else if (is_symbol_start(pgn->char_hack)) { - - // symbol, integer, or result - - pgn->token_type = TOKEN_INTEGER; - pgn->token_length = 0; - - do { - - if (pgn->token_length >= PGN_STRING_SIZE-1) { - my_fatal("pgn_read_token(): symbol too long at line %d, column %d,game %d\n",pgn->char_line,pgn->char_column,pgn->game_nb); - } - - if (!isdigit(pgn->char_hack)) pgn->token_type = TOKEN_SYMBOL; - - pgn->token_string[pgn->token_length++] = pgn->char_hack; - - pgn_char_read(pgn); - - } while (is_symbol_next(pgn->char_hack)); - - pgn_char_unread(pgn); - - ASSERT(pgn->token_length>0&&pgn->token_lengthtoken_string[pgn->token_length] = '\0'; - - if (my_string_equal(pgn->token_string,"1-0") - || my_string_equal(pgn->token_string,"0-1") - || my_string_equal(pgn->token_string,"1/2-1/2")) { - pgn->token_type = TOKEN_RESULT; - } - - } else if (pgn->char_hack == '"') { - - // string - - pgn->token_type = TOKEN_STRING; - pgn->token_length = 0; - - while (true) { - - pgn_char_read(pgn); - - if (pgn->char_hack == CHAR_EOF) { - my_fatal("pgn_read_token(): EOF in string at line %d, column %d, game %d\n",pgn->char_line,pgn->char_column,pgn->game_nb); - } - - if (pgn->char_hack == '"') break; - - if (pgn->char_hack == '\\') { - - pgn_char_read(pgn); - - if (pgn->char_hack == CHAR_EOF) { - my_fatal("pgn_read_token(): EOF in string at line %d, column %d, game %d\n",pgn->char_line,pgn->char_column,pgn->game_nb); - } - - if (pgn->char_hack != '"' && pgn->char_hack != '\\') { - - // bad escape, ignore - - if (pgn->token_length >= PGN_STRING_SIZE-1) { - my_fatal("pgn_read_token(): string too long at line %d, column %d,game %d\n",pgn->char_line,pgn->char_column,pgn->game_nb); - } - - pgn->token_string[pgn->token_length++] = '\\'; - } - } - - if (pgn->token_length >= PGN_STRING_SIZE-1) { - my_fatal("pgn_read_token(): string too long at line %d, column %d,game %d\n",pgn->char_line,pgn->char_column,pgn->game_nb); - } - - pgn->token_string[pgn->token_length++] = pgn->char_hack; - } - - ASSERT(pgn->token_length>=0&&pgn->token_lengthtoken_string[pgn->token_length] = '\0'; - - } else if (pgn->char_hack == '$') { - - // NAG - - pgn->token_type = TOKEN_NAG; - pgn->token_length = 0; - - while (true) { - - pgn_char_read(pgn); - - if (!isdigit(pgn->char_hack)) break; - - if (pgn->token_length >= 3) { - my_fatal("pgn_read_token(): NAG too long at line %d, column %d, game %d\n",pgn->char_line,pgn->char_column,pgn->game_nb); - } - - pgn->token_string[pgn->token_length++] = pgn->char_hack; - } - - pgn_char_unread(pgn); - - if (pgn->token_length == 0) { - my_fatal("pgn_read_token(): malformed NAG at line %d, column %d,game %d\n",pgn->char_line,pgn->char_column,pgn->game_nb); - } - - ASSERT(pgn->token_length>0&&pgn->token_length<=3); - pgn->token_string[pgn->token_length] = '\0'; - - } else { - - // unknown token - - my_fatal("lexical error at line %d, column %d, game %d\n",pgn->char_line,pgn->char_column,pgn->game_nb); - } -} - -// pgn_skip_blanks() - -static void pgn_skip_blanks(pgn_t * pgn) { - - ASSERT(pgn!=NULL); - - while (true) { - - pgn_char_read(pgn); - - if (false) { - }else if(pgn->char_hack==CHAR_EOF){ break; - } else if (isspace(pgn->char_hack)) { - - // skip white space - - } else if (pgn->char_hack == ';') { - - // skip comment to EOL - - do { - - pgn_char_read(pgn); - - if (pgn->char_hack == CHAR_EOF) { - my_fatal("pgn_skip_blanks(): EOF in comment at line %d, column %d,game %d\n",pgn->char_line,pgn->char_column,pgn->game_nb); - } - - } while (pgn->char_hack != '\n'); - - } else if (pgn->char_hack == '%' && pgn->char_column == 0) { - - // skip comment to EOL - - do { - - pgn_char_read(pgn); - - if (pgn->char_hack == CHAR_EOF) { - my_fatal("pgn_skip_blanks(): EOF in comment at line %d, column %d, game %d\n",pgn->char_line,pgn->char_column,pgn->game_nb); - } - - } while (pgn->char_hack != '\n'); - - } else if (pgn->char_hack == '{') { - - // skip comment to next '}' - - do { - - pgn_char_read(pgn); - - if (pgn->char_hack == CHAR_EOF) { - my_fatal("pgn_skip_blanks(): EOF in comment at line %d, column %d, game %d\n",pgn->char_line,pgn->char_column,pgn->game_nb); - } - - } while (pgn->char_hack != '}'); - - } else { // not a white space - - break; - } - } -} - -// is_symbol_start() - -static bool is_symbol_start(int c) { - - return strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",c) != NULL; -} - -// is_symbol_next() - -static bool is_symbol_next(int c) { - - return strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_+#=:-/",c) != NULL; -} - -// pgn_char_read() - -static void pgn_char_read(pgn_t * pgn) { - - ASSERT(pgn!=NULL); - - // char "stack" - - if (pgn->char_unread) { - pgn->char_unread = false; - return; - } - - // consume the current character - - if (pgn->char_first) { - - pgn->char_first = false; - - } else { - - // update counters - - ASSERT(pgn->char_hack!=CHAR_EOF); - - if (false) { - } else if (pgn->char_hack == '\n') { - pgn->char_line++; - pgn->char_column = 0; - } else if (pgn->char_hack == '\t') { - pgn->char_column += TAB_SIZE - (pgn->char_column % TAB_SIZE); - } else { - pgn->char_column++; - } - } - - // read a new character - - pgn->char_hack = fgetc(pgn->file); - - if (pgn->char_hack == EOF) { - if (ferror(pgn->file)) my_fatal("pgn_char_read(): fgetc(): %s\n",strerror(errno)); - pgn->char_hack = CHAR_EOF; - } - - if (DispChar) printf("< L%d C%d '%c' (%02X)\n",pgn->char_line,pgn->char_column,pgn->char_hack,pgn->char_hack); -} - -// pgn_char_unread() - -static void pgn_char_unread(pgn_t * pgn) { - - ASSERT(pgn!=NULL); - - ASSERT(!pgn->char_unread); - ASSERT(!pgn->char_first); - - pgn->char_unread = true; -} - -// end of pgn.cpp - diff --git a/piece.cpp b/piece.cpp deleted file mode 100644 index 719299f..0000000 --- a/piece.cpp +++ /dev/null @@ -1,203 +0,0 @@ - -// piece.cpp - -// includes - -#include - -#include "colour.h" -#include "piece.h" -#include "util.h" - -// "constants" - -static const uint8 MakePawn[ColourNb] = { PieceNone256, BlackPawn256, WhitePawn256 }; // -BW - -static const uint8 PieceFrom12[12] = { - BlackPawn256, WhitePawn256, - BlackKnight256, WhiteKnight256, - BlackBishop256, WhiteBishop256, - BlackRook256, WhiteRook256, - BlackQueen256, WhiteQueen256, - BlackKing256, WhiteKing256, -}; - -static const char PieceString[12+1] = "pPnNbBrRqQkK"; - -// variables - -static sint8 PieceTo12[256]; - -// functions - -// piece_init() - -void piece_init() { - - int piece; - - for (piece = 0; piece < 256; piece++) PieceTo12[piece] = -1; - - for (piece = 0; piece < 12; piece++) { - PieceTo12[PieceFrom12[piece]] = piece; - } -} - -// piece_is_ok() - -bool piece_is_ok(int piece) { - - if (piece < 0 || piece >= 256) return false; - - if (PieceTo12[piece] < 0) return false; - - return true; -} - -// piece_make_pawn() - -int piece_make_pawn(int colour) { - - ASSERT(colour_is_ok(colour)); - - return MakePawn[colour]; -} - -// piece_pawn_opp() - -int piece_pawn_opp(int piece) { - - ASSERT(piece==BlackPawn256||piece==WhitePawn256); - - return piece ^ 15; -} - -// piece_colour() - -int piece_colour(int piece) { - - ASSERT(piece_is_ok(piece)); - - return piece & 3; -} - -// piece_type() - -int piece_type(int piece) { - - ASSERT(piece_is_ok(piece)); - - return piece & ~3; -} - -// piece_is_pawn() - -bool piece_is_pawn(int piece) { - - ASSERT(piece_is_ok(piece)); - - return (piece & PawnFlags) != 0; -} - -// piece_is_knight() - -bool piece_is_knight(int piece) { - - ASSERT(piece_is_ok(piece)); - - return (piece & KnightFlag) != 0; -} - -// piece_is_bishop() - -bool piece_is_bishop(int piece) { - - ASSERT(piece_is_ok(piece)); - - return (piece & QueenFlags) == BishopFlag; -} - -// piece_is_rook() - -bool piece_is_rook(int piece) { - - ASSERT(piece_is_ok(piece)); - - return (piece & QueenFlags) == RookFlag; -} - -// piece_is_queen() - -bool piece_is_queen(int piece) { - - ASSERT(piece_is_ok(piece)); - - return (piece & QueenFlags) == QueenFlags; -} - -// piece_is_king() - -bool piece_is_king(int piece) { - - ASSERT(piece_is_ok(piece)); - - return (piece & KingFlag) != 0; -} - -// piece_is_slider() - -bool piece_is_slider(int piece) { - - ASSERT(piece_is_ok(piece)); - - return (piece & QueenFlags) != 0; -} - -// piece_to_12() - -int piece_to_12(int piece) { - - ASSERT(piece_is_ok(piece)); - - return PieceTo12[piece]; -} - -// piece_from_12() - -int piece_from_12(int piece) { - - ASSERT(piece>=0&&piece<12); - - return PieceFrom12[piece]; -} - -// piece_to_char() - -int piece_to_char(int piece) { - - ASSERT(piece_is_ok(piece)); - - return PieceString[piece_to_12(piece)]; -} - -// piece_from_char() - -int piece_from_char(int c) { - - const char * ptr; - - ptr = strchr(PieceString,c); - if (ptr == NULL) return PieceNone256; - - return piece_from_12(ptr-PieceString); -} - -// char_is_piece() - -bool char_is_piece(int c) { - - return strchr("PNBRQK",c) != NULL; -} - -// end of piece.cpp - diff --git a/pipe.cpp b/pipe.cpp deleted file mode 100644 index 170da4a..0000000 --- a/pipe.cpp +++ /dev/null @@ -1,265 +0,0 @@ -#ifdef _WIN32 -#include "pipe.h" -#include "util.h" - -// functions - -DWORD WINAPI ThreadProc(LPVOID lpParam){ - PipeStruct *p=(PipeStruct *) lpParam; - while(!p->EOF_input()){ - if(p->nReadEndReadInput(); - }else{ - // wait until there is room in buffer - Sleep(10); - } - } - return 0; -} - - - -void PipeStruct::Open(const char *szProcFile) { - DWORD dwMode, dwThreadId; - HANDLE hStdinRead, hStdinWrite, hStdoutRead, hStdoutWrite; - SECURITY_ATTRIBUTES sa; - STARTUPINFO si; - PROCESS_INFORMATION pi; - int fdInput; - state=0; - if (szProcFile == NULL) { - hInput = GetStdHandle(STD_INPUT_HANDLE); - hOutput = GetStdHandle(STD_OUTPUT_HANDLE); - bConsole = GetConsoleMode(hInput, &dwMode); - bPipe=FALSE; - } else { - sa.nLength = sizeof(SECURITY_ATTRIBUTES); - sa.bInheritHandle = TRUE; - sa.lpSecurityDescriptor = NULL; - CreatePipe(&hStdinRead, &hStdinWrite, &sa, 0); - CreatePipe(&hStdoutRead, &hStdoutWrite, &sa, 0); - si.cb = sizeof(STARTUPINFO); - si.lpReserved = si.lpDesktop = si.lpTitle = NULL; - si.dwFlags = STARTF_USESTDHANDLES; - si.cbReserved2 = 0; - si.lpReserved2 = NULL; - si.hStdInput = hStdinRead; - si.hStdOutput = hStdoutWrite; - si.hStdError = hStdoutWrite; - if(CreateProcess(NULL, - (LPSTR) szProcFile, - NULL, - NULL, - TRUE, - DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP, - NULL, - NULL, - &si, - &pi)){ - hProcess=pi.hProcess; - CloseHandle(pi.hThread); - CloseHandle(hStdinRead); - CloseHandle(hStdoutWrite); - hInput = hStdoutRead; - hOutput = hStdinWrite; - bConsole = FALSE; - bPipe=TRUE; - }else{ - my_fatal("PipeStruct::Open(): %s",my_error()); - } - } - if (bConsole) { - SetConsoleMode(hInput, - dwMode & ~(ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT)); - FlushConsoleInputBuffer(hInput); - } - fdInput=_open_osfhandle((long) hInput,_O_RDONLY); - if(fdInput==-1){ - my_fatal("PipeStruct::Open(): %s",my_error()); - } - fpInput=fdopen(fdInput,"r"); - if(fpInput==NULL){ - my_fatal("PipeStruct::Open(): %s",my_error()); - } - nReadEnd = 0; - lpFeedEnd = NULL; - InitializeCriticalSection(&CriticalSection); - hEvent=CreateEvent(NULL, // default security - FALSE, // auto reset - FALSE, // not signaled - NULL // nameless - ); - if(!hEvent){ - my_fatal("PipeStruct::Open(): %s",my_error()); - } - hThread=CreateThread(NULL, // default security - 0, // default stacksize - ThreadProc, // worker function - this, // tell worker about ourselves - 0, // run immediately - &dwThreadId // dropped, but needed for the call to work in Win9x - ); - if(!hThread){ - my_fatal("PipeStruct::Open(): %s",my_error()); - } - set_Active(); -} - - -void PipeStruct::Close(void) const { - CloseHandle(hOutput); -} - -void PipeStruct::Kill(void) const { - CloseHandle(hInput); - CloseHandle(hOutput); - DWORD lpexit; - - if(GetExitCodeProcess(hProcess,&lpexit)){ - if(lpexit==STILL_ACTIVE) - //must be java,hammer it down! - TerminateProcess(hProcess,lpexit); - } - CloseHandle(hProcess); -} - -bool PipeStruct::EOF_input(void){ // EOF is defined - int ret; - EnterCriticalSection(&CriticalSection); - ret=state&PIPE_EOF; - LeaveCriticalSection(&CriticalSection); - return ret; -} - -void PipeStruct::set_EOF_input(void){ - EnterCriticalSection(&CriticalSection); - state|=PIPE_EOF; - LeaveCriticalSection(&CriticalSection); -} - -bool PipeStruct::Active(void){ - int ret; - EnterCriticalSection(&CriticalSection); - ret=state&PIPE_ACTIVE; - LeaveCriticalSection(&CriticalSection); - return ret; -} - -void PipeStruct::set_Active(void){ - EnterCriticalSection(&CriticalSection); - state|=PIPE_ACTIVE; - LeaveCriticalSection(&CriticalSection); -} - -int PipeStruct::ReadData(void){ - DWORD dwBytes; - char * ret; - // No protection. Access to nReadEnd is atomic. - // It is not a problem that nReadEnd becomes smaller after the call. - // This just means we have read less than we could have. - ret=fgets(lpReadBuffer,LINE_INPUT_MAX_CHAR-nReadEnd,fpInput); - if(!ret){ - set_EOF_input(); - lpReadBuffer[0]='\0'; - return 0; - } - dwBytes=strlen(lpReadBuffer); - lpReadBuffer[dwBytes]='\0'; - return dwBytes; -} - -void PipeStruct::ReadInput(void) { - DWORD dwBytes; - int ret; - BOOL bSetEvent=FALSE; - // ReadData is outside the critical section otherwise everything - // would block during the blocking read - ret=ReadData(); - EnterCriticalSection(&CriticalSection); - if(!EOF_input()){ - if(ret+nReadEnd>=LINE_INPUT_MAX_CHAR){ - my_fatal("PipeStruct::ReadInput(): Internal error: buffer overflow\n"); - } - memcpy(lpBuffer+nReadEnd,lpReadBuffer,ret+1); - nReadEnd += ret; - if(!lpFeedEnd){ - lpFeedEnd = (char *) memchr(lpBuffer, '\n', nReadEnd); - } - if(lpFeedEnd){ - bSetEvent=TRUE; - }else if(nReadEnd>=LINE_INPUT_MAX_CHAR-1){ - my_fatal("PipeStruct::ReadInput(): LINE_INPUT_MAX_CHAR is equal to %d which is too small to contain a full line of engine output or GUI input.\n",LINE_INPUT_MAX_CHAR); - } - } - LeaveCriticalSection(&CriticalSection); - if(EOF_input() || bSetEvent){ - SetEvent(hEvent); - } -} - -bool PipeStruct::EOF_(void){ - int ret; - EnterCriticalSection(&CriticalSection); - if(lpFeedEnd != NULL){ - ret=FALSE; - }else if(EOF_input()){ - ret=TRUE; - }else{ - ret=FALSE; - } - LeaveCriticalSection(&CriticalSection); - return ret; -} - -bool PipeStruct::GetBuffer(char *szLineStr) { - int nFeedEnd; - int ret; - EnterCriticalSection(&CriticalSection); - if (lpFeedEnd == NULL) { - ret=FALSE; - } else { - nFeedEnd = lpFeedEnd - lpBuffer; - memcpy(szLineStr, lpBuffer, nFeedEnd); - if (szLineStr[nFeedEnd - 1] == '\r') { - szLineStr[nFeedEnd - 1] = '\0'; - } else { - szLineStr[nFeedEnd] = '\0'; - } - nFeedEnd ++; - nReadEnd -= nFeedEnd; - memcpy(lpBuffer, lpBuffer + nFeedEnd, nReadEnd); - lpFeedEnd = (char *) memchr(lpBuffer, '\n', nReadEnd); - ret=TRUE; - } - LeaveCriticalSection(&CriticalSection); - return ret; -} - - - -void PipeStruct::LineInput(char *szLineStr) { - while(!EOF_()){ - if (GetBuffer(szLineStr)) { - break; - }else{ - WaitForSingleObject(hEvent,INFINITE); - } - } -} - -void PipeStruct::LineOutput(const char *szLineStr) const { - DWORD dwBytes; - int nStrLen; - char szWriteBuffer[LINE_INPUT_MAX_CHAR]; - if(bPipe){ - nStrLen = strlen(szLineStr); - memcpy(szWriteBuffer, szLineStr, nStrLen); - szWriteBuffer[nStrLen] = '\r'; - szWriteBuffer[nStrLen + 1] = '\n'; - WriteFile(hOutput, szWriteBuffer, nStrLen + 2, &dwBytes, NULL); - }else{ - printf("%s\n",szLineStr); - fflush(stdout); - } -} -#endif diff --git a/pipe.h b/pipe.h deleted file mode 100644 index d24ed8c..0000000 --- a/pipe.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef PIPE_H -#define PIPE_H -#ifdef _WIN32 -// includes - -#include -#include -#include -#include - -// constants - -// This should be bigger than the maximum length of an engine output or GUI -// input line. -const int LINE_INPUT_MAX_CHAR = 40960; - -// defines - -#define PIPE_EOF 1 -#define PIPE_ACTIVE 2 - -// types - -class PipeStruct { - friend DWORD WINAPI ThreadProc(LPVOID lpParam); - public: - HANDLE hProcess; - HANDLE hEvent; - bool GetBuffer(char *szLineStr); - void LineInput(char *szLineStr); - void LineOutput(const char *szLineStr) const; - void Open(const char *szExecFile = NULL); - void Close(void) const; - void Kill(void) const; - bool Active(void); - bool EOF_(void); - private: - HANDLE hInput, hOutput; - FILE *fpInput; - HANDLE hThread; - BOOL bConsole; - BOOL bPipe; - - CRITICAL_SECTION CriticalSection; - - volatile DWORD state; - volatile char * lpFeedEnd; - volatile int nReadEnd; - char lpBuffer[LINE_INPUT_MAX_CHAR]; - char lpReadBuffer[LINE_INPUT_MAX_CHAR]; - - bool EOF_input(void); - void set_EOF_input(void); - void set_Active(void); - void ReadInput(void); - int ReadData(void); - -}; - -// pipe - -#endif -#endif diff --git a/posix.cpp b/posix.cpp deleted file mode 100644 index d5f0a9d..0000000 --- a/posix.cpp +++ /dev/null @@ -1,101 +0,0 @@ - -// posix.cpp - -// includes - -#include -#include -#include -#include - -#ifdef _WIN32 - -#include - -#else - -#include // Mac OS X needs this one first -#include -#include -#include - -#endif - -#include "posix.h" -#include "util.h" - -#ifndef _WIN32 -// prototypes - -static double duration (const struct timeval *t); - -// functions - - -// input_available() - -bool input_available() { - - int val; - fd_set set[1]; - struct timeval time_val[1]; - - FD_ZERO(set); - FD_SET(STDIN_FILENO,set); - - time_val->tv_sec = 0; - time_val->tv_usec = 0; - - val = select(STDIN_FILENO+1,set,NULL,NULL,time_val); - if (val == -1) my_fatal("input_available(): select(): %s\n",strerror(errno)); - - return val != 0; -} - - -// now_real() - -double now_real() { - - struct timeval tv[1]; - struct timezone tz[1]; - - tz->tz_minuteswest = 0; - tz->tz_dsttime = 0; // DST_NONE not declared in linux - - if (gettimeofday(tv,tz) == -1) { - my_fatal("now_real(): gettimeofday(): %s\n",strerror(errno)); - } - - return duration(tv); -} - -// now_cpu() - -double now_cpu() { - - struct rusage ru[1]; - - if (getrusage(RUSAGE_SELF,ru) == -1) { - my_fatal("now_cpu(): getrusage(): %s\n",strerror(errno)); - } - - return duration(&ru->ru_utime); -} - -// duration() - -static double duration(const struct timeval *tv) { - - return tv->tv_sec + tv->tv_usec * 1E-6; -} - -#else - -double now_real(void) { - return (double) GetTickCount() / 1000.0; -} - -#endif - -// end of posix.cpp diff --git a/posix.h b/posix.h deleted file mode 100644 index b667872..0000000 --- a/posix.h +++ /dev/null @@ -1,20 +0,0 @@ - -// posix.h - -#ifndef POSIX_H -#define POSIX_H - -// includes - -#include "util.h" - -// functions - -extern bool input_available (); - -extern double now_real (); - -#endif // !defined POSIX_H - -// end of posix.h - diff --git a/random.cpp b/random.cpp deleted file mode 100644 index 9b5d8b0..0000000 --- a/random.cpp +++ /dev/null @@ -1,231 +0,0 @@ - -// random.cpp - -// includes - -#include "random.h" -#include "util.h" - -// "constants" - -const uint64 Random64[RandomNb] = { - U64(0x9D39247E33776D41), U64(0x2AF7398005AAA5C7), U64(0x44DB015024623547), U64(0x9C15F73E62A76AE2), - U64(0x75834465489C0C89), U64(0x3290AC3A203001BF), U64(0x0FBBAD1F61042279), U64(0xE83A908FF2FB60CA), - U64(0x0D7E765D58755C10), U64(0x1A083822CEAFE02D), U64(0x9605D5F0E25EC3B0), U64(0xD021FF5CD13A2ED5), - U64(0x40BDF15D4A672E32), U64(0x011355146FD56395), U64(0x5DB4832046F3D9E5), U64(0x239F8B2D7FF719CC), - U64(0x05D1A1AE85B49AA1), U64(0x679F848F6E8FC971), U64(0x7449BBFF801FED0B), U64(0x7D11CDB1C3B7ADF0), - U64(0x82C7709E781EB7CC), U64(0xF3218F1C9510786C), U64(0x331478F3AF51BBE6), U64(0x4BB38DE5E7219443), - U64(0xAA649C6EBCFD50FC), U64(0x8DBD98A352AFD40B), U64(0x87D2074B81D79217), U64(0x19F3C751D3E92AE1), - U64(0xB4AB30F062B19ABF), U64(0x7B0500AC42047AC4), U64(0xC9452CA81A09D85D), U64(0x24AA6C514DA27500), - U64(0x4C9F34427501B447), U64(0x14A68FD73C910841), U64(0xA71B9B83461CBD93), U64(0x03488B95B0F1850F), - U64(0x637B2B34FF93C040), U64(0x09D1BC9A3DD90A94), U64(0x3575668334A1DD3B), U64(0x735E2B97A4C45A23), - U64(0x18727070F1BD400B), U64(0x1FCBACD259BF02E7), U64(0xD310A7C2CE9B6555), U64(0xBF983FE0FE5D8244), - U64(0x9F74D14F7454A824), U64(0x51EBDC4AB9BA3035), U64(0x5C82C505DB9AB0FA), U64(0xFCF7FE8A3430B241), - U64(0x3253A729B9BA3DDE), U64(0x8C74C368081B3075), U64(0xB9BC6C87167C33E7), U64(0x7EF48F2B83024E20), - U64(0x11D505D4C351BD7F), U64(0x6568FCA92C76A243), U64(0x4DE0B0F40F32A7B8), U64(0x96D693460CC37E5D), - U64(0x42E240CB63689F2F), U64(0x6D2BDCDAE2919661), U64(0x42880B0236E4D951), U64(0x5F0F4A5898171BB6), - U64(0x39F890F579F92F88), U64(0x93C5B5F47356388B), U64(0x63DC359D8D231B78), U64(0xEC16CA8AEA98AD76), - U64(0x5355F900C2A82DC7), U64(0x07FB9F855A997142), U64(0x5093417AA8A7ED5E), U64(0x7BCBC38DA25A7F3C), - U64(0x19FC8A768CF4B6D4), U64(0x637A7780DECFC0D9), U64(0x8249A47AEE0E41F7), U64(0x79AD695501E7D1E8), - U64(0x14ACBAF4777D5776), U64(0xF145B6BECCDEA195), U64(0xDABF2AC8201752FC), U64(0x24C3C94DF9C8D3F6), - U64(0xBB6E2924F03912EA), U64(0x0CE26C0B95C980D9), U64(0xA49CD132BFBF7CC4), U64(0xE99D662AF4243939), - U64(0x27E6AD7891165C3F), U64(0x8535F040B9744FF1), U64(0x54B3F4FA5F40D873), U64(0x72B12C32127FED2B), - U64(0xEE954D3C7B411F47), U64(0x9A85AC909A24EAA1), U64(0x70AC4CD9F04F21F5), U64(0xF9B89D3E99A075C2), - U64(0x87B3E2B2B5C907B1), U64(0xA366E5B8C54F48B8), U64(0xAE4A9346CC3F7CF2), U64(0x1920C04D47267BBD), - U64(0x87BF02C6B49E2AE9), U64(0x092237AC237F3859), U64(0xFF07F64EF8ED14D0), U64(0x8DE8DCA9F03CC54E), - U64(0x9C1633264DB49C89), U64(0xB3F22C3D0B0B38ED), U64(0x390E5FB44D01144B), U64(0x5BFEA5B4712768E9), - U64(0x1E1032911FA78984), U64(0x9A74ACB964E78CB3), U64(0x4F80F7A035DAFB04), U64(0x6304D09A0B3738C4), - U64(0x2171E64683023A08), U64(0x5B9B63EB9CEFF80C), U64(0x506AACF489889342), U64(0x1881AFC9A3A701D6), - U64(0x6503080440750644), U64(0xDFD395339CDBF4A7), U64(0xEF927DBCF00C20F2), U64(0x7B32F7D1E03680EC), - U64(0xB9FD7620E7316243), U64(0x05A7E8A57DB91B77), U64(0xB5889C6E15630A75), U64(0x4A750A09CE9573F7), - U64(0xCF464CEC899A2F8A), U64(0xF538639CE705B824), U64(0x3C79A0FF5580EF7F), U64(0xEDE6C87F8477609D), - U64(0x799E81F05BC93F31), U64(0x86536B8CF3428A8C), U64(0x97D7374C60087B73), U64(0xA246637CFF328532), - U64(0x043FCAE60CC0EBA0), U64(0x920E449535DD359E), U64(0x70EB093B15B290CC), U64(0x73A1921916591CBD), - U64(0x56436C9FE1A1AA8D), U64(0xEFAC4B70633B8F81), U64(0xBB215798D45DF7AF), U64(0x45F20042F24F1768), - U64(0x930F80F4E8EB7462), U64(0xFF6712FFCFD75EA1), U64(0xAE623FD67468AA70), U64(0xDD2C5BC84BC8D8FC), - U64(0x7EED120D54CF2DD9), U64(0x22FE545401165F1C), U64(0xC91800E98FB99929), U64(0x808BD68E6AC10365), - U64(0xDEC468145B7605F6), U64(0x1BEDE3A3AEF53302), U64(0x43539603D6C55602), U64(0xAA969B5C691CCB7A), - U64(0xA87832D392EFEE56), U64(0x65942C7B3C7E11AE), U64(0xDED2D633CAD004F6), U64(0x21F08570F420E565), - U64(0xB415938D7DA94E3C), U64(0x91B859E59ECB6350), U64(0x10CFF333E0ED804A), U64(0x28AED140BE0BB7DD), - U64(0xC5CC1D89724FA456), U64(0x5648F680F11A2741), U64(0x2D255069F0B7DAB3), U64(0x9BC5A38EF729ABD4), - U64(0xEF2F054308F6A2BC), U64(0xAF2042F5CC5C2858), U64(0x480412BAB7F5BE2A), U64(0xAEF3AF4A563DFE43), - U64(0x19AFE59AE451497F), U64(0x52593803DFF1E840), U64(0xF4F076E65F2CE6F0), U64(0x11379625747D5AF3), - U64(0xBCE5D2248682C115), U64(0x9DA4243DE836994F), U64(0x066F70B33FE09017), U64(0x4DC4DE189B671A1C), - U64(0x51039AB7712457C3), U64(0xC07A3F80C31FB4B4), U64(0xB46EE9C5E64A6E7C), U64(0xB3819A42ABE61C87), - U64(0x21A007933A522A20), U64(0x2DF16F761598AA4F), U64(0x763C4A1371B368FD), U64(0xF793C46702E086A0), - U64(0xD7288E012AEB8D31), U64(0xDE336A2A4BC1C44B), U64(0x0BF692B38D079F23), U64(0x2C604A7A177326B3), - U64(0x4850E73E03EB6064), U64(0xCFC447F1E53C8E1B), U64(0xB05CA3F564268D99), U64(0x9AE182C8BC9474E8), - U64(0xA4FC4BD4FC5558CA), U64(0xE755178D58FC4E76), U64(0x69B97DB1A4C03DFE), U64(0xF9B5B7C4ACC67C96), - U64(0xFC6A82D64B8655FB), U64(0x9C684CB6C4D24417), U64(0x8EC97D2917456ED0), U64(0x6703DF9D2924E97E), - U64(0xC547F57E42A7444E), U64(0x78E37644E7CAD29E), U64(0xFE9A44E9362F05FA), U64(0x08BD35CC38336615), - U64(0x9315E5EB3A129ACE), U64(0x94061B871E04DF75), U64(0xDF1D9F9D784BA010), U64(0x3BBA57B68871B59D), - U64(0xD2B7ADEEDED1F73F), U64(0xF7A255D83BC373F8), U64(0xD7F4F2448C0CEB81), U64(0xD95BE88CD210FFA7), - U64(0x336F52F8FF4728E7), U64(0xA74049DAC312AC71), U64(0xA2F61BB6E437FDB5), U64(0x4F2A5CB07F6A35B3), - U64(0x87D380BDA5BF7859), U64(0x16B9F7E06C453A21), U64(0x7BA2484C8A0FD54E), U64(0xF3A678CAD9A2E38C), - U64(0x39B0BF7DDE437BA2), U64(0xFCAF55C1BF8A4424), U64(0x18FCF680573FA594), U64(0x4C0563B89F495AC3), - U64(0x40E087931A00930D), U64(0x8CFFA9412EB642C1), U64(0x68CA39053261169F), U64(0x7A1EE967D27579E2), - U64(0x9D1D60E5076F5B6F), U64(0x3810E399B6F65BA2), U64(0x32095B6D4AB5F9B1), U64(0x35CAB62109DD038A), - U64(0xA90B24499FCFAFB1), U64(0x77A225A07CC2C6BD), U64(0x513E5E634C70E331), U64(0x4361C0CA3F692F12), - U64(0xD941ACA44B20A45B), U64(0x528F7C8602C5807B), U64(0x52AB92BEB9613989), U64(0x9D1DFA2EFC557F73), - U64(0x722FF175F572C348), U64(0x1D1260A51107FE97), U64(0x7A249A57EC0C9BA2), U64(0x04208FE9E8F7F2D6), - U64(0x5A110C6058B920A0), U64(0x0CD9A497658A5698), U64(0x56FD23C8F9715A4C), U64(0x284C847B9D887AAE), - U64(0x04FEABFBBDB619CB), U64(0x742E1E651C60BA83), U64(0x9A9632E65904AD3C), U64(0x881B82A13B51B9E2), - U64(0x506E6744CD974924), U64(0xB0183DB56FFC6A79), U64(0x0ED9B915C66ED37E), U64(0x5E11E86D5873D484), - U64(0xF678647E3519AC6E), U64(0x1B85D488D0F20CC5), U64(0xDAB9FE6525D89021), U64(0x0D151D86ADB73615), - U64(0xA865A54EDCC0F019), U64(0x93C42566AEF98FFB), U64(0x99E7AFEABE000731), U64(0x48CBFF086DDF285A), - U64(0x7F9B6AF1EBF78BAF), U64(0x58627E1A149BBA21), U64(0x2CD16E2ABD791E33), U64(0xD363EFF5F0977996), - U64(0x0CE2A38C344A6EED), U64(0x1A804AADB9CFA741), U64(0x907F30421D78C5DE), U64(0x501F65EDB3034D07), - U64(0x37624AE5A48FA6E9), U64(0x957BAF61700CFF4E), U64(0x3A6C27934E31188A), U64(0xD49503536ABCA345), - U64(0x088E049589C432E0), U64(0xF943AEE7FEBF21B8), U64(0x6C3B8E3E336139D3), U64(0x364F6FFA464EE52E), - U64(0xD60F6DCEDC314222), U64(0x56963B0DCA418FC0), U64(0x16F50EDF91E513AF), U64(0xEF1955914B609F93), - U64(0x565601C0364E3228), U64(0xECB53939887E8175), U64(0xBAC7A9A18531294B), U64(0xB344C470397BBA52), - U64(0x65D34954DAF3CEBD), U64(0xB4B81B3FA97511E2), U64(0xB422061193D6F6A7), U64(0x071582401C38434D), - U64(0x7A13F18BBEDC4FF5), U64(0xBC4097B116C524D2), U64(0x59B97885E2F2EA28), U64(0x99170A5DC3115544), - U64(0x6F423357E7C6A9F9), U64(0x325928EE6E6F8794), U64(0xD0E4366228B03343), U64(0x565C31F7DE89EA27), - U64(0x30F5611484119414), U64(0xD873DB391292ED4F), U64(0x7BD94E1D8E17DEBC), U64(0xC7D9F16864A76E94), - U64(0x947AE053EE56E63C), U64(0xC8C93882F9475F5F), U64(0x3A9BF55BA91F81CA), U64(0xD9A11FBB3D9808E4), - U64(0x0FD22063EDC29FCA), U64(0xB3F256D8ACA0B0B9), U64(0xB03031A8B4516E84), U64(0x35DD37D5871448AF), - U64(0xE9F6082B05542E4E), U64(0xEBFAFA33D7254B59), U64(0x9255ABB50D532280), U64(0xB9AB4CE57F2D34F3), - U64(0x693501D628297551), U64(0xC62C58F97DD949BF), U64(0xCD454F8F19C5126A), U64(0xBBE83F4ECC2BDECB), - U64(0xDC842B7E2819E230), U64(0xBA89142E007503B8), U64(0xA3BC941D0A5061CB), U64(0xE9F6760E32CD8021), - U64(0x09C7E552BC76492F), U64(0x852F54934DA55CC9), U64(0x8107FCCF064FCF56), U64(0x098954D51FFF6580), - U64(0x23B70EDB1955C4BF), U64(0xC330DE426430F69D), U64(0x4715ED43E8A45C0A), U64(0xA8D7E4DAB780A08D), - U64(0x0572B974F03CE0BB), U64(0xB57D2E985E1419C7), U64(0xE8D9ECBE2CF3D73F), U64(0x2FE4B17170E59750), - U64(0x11317BA87905E790), U64(0x7FBF21EC8A1F45EC), U64(0x1725CABFCB045B00), U64(0x964E915CD5E2B207), - U64(0x3E2B8BCBF016D66D), U64(0xBE7444E39328A0AC), U64(0xF85B2B4FBCDE44B7), U64(0x49353FEA39BA63B1), - U64(0x1DD01AAFCD53486A), U64(0x1FCA8A92FD719F85), U64(0xFC7C95D827357AFA), U64(0x18A6A990C8B35EBD), - U64(0xCCCB7005C6B9C28D), U64(0x3BDBB92C43B17F26), U64(0xAA70B5B4F89695A2), U64(0xE94C39A54A98307F), - U64(0xB7A0B174CFF6F36E), U64(0xD4DBA84729AF48AD), U64(0x2E18BC1AD9704A68), U64(0x2DE0966DAF2F8B1C), - U64(0xB9C11D5B1E43A07E), U64(0x64972D68DEE33360), U64(0x94628D38D0C20584), U64(0xDBC0D2B6AB90A559), - U64(0xD2733C4335C6A72F), U64(0x7E75D99D94A70F4D), U64(0x6CED1983376FA72B), U64(0x97FCAACBF030BC24), - U64(0x7B77497B32503B12), U64(0x8547EDDFB81CCB94), U64(0x79999CDFF70902CB), U64(0xCFFE1939438E9B24), - U64(0x829626E3892D95D7), U64(0x92FAE24291F2B3F1), U64(0x63E22C147B9C3403), U64(0xC678B6D860284A1C), - U64(0x5873888850659AE7), U64(0x0981DCD296A8736D), U64(0x9F65789A6509A440), U64(0x9FF38FED72E9052F), - U64(0xE479EE5B9930578C), U64(0xE7F28ECD2D49EECD), U64(0x56C074A581EA17FE), U64(0x5544F7D774B14AEF), - U64(0x7B3F0195FC6F290F), U64(0x12153635B2C0CF57), U64(0x7F5126DBBA5E0CA7), U64(0x7A76956C3EAFB413), - U64(0x3D5774A11D31AB39), U64(0x8A1B083821F40CB4), U64(0x7B4A38E32537DF62), U64(0x950113646D1D6E03), - U64(0x4DA8979A0041E8A9), U64(0x3BC36E078F7515D7), U64(0x5D0A12F27AD310D1), U64(0x7F9D1A2E1EBE1327), - U64(0xDA3A361B1C5157B1), U64(0xDCDD7D20903D0C25), U64(0x36833336D068F707), U64(0xCE68341F79893389), - U64(0xAB9090168DD05F34), U64(0x43954B3252DC25E5), U64(0xB438C2B67F98E5E9), U64(0x10DCD78E3851A492), - U64(0xDBC27AB5447822BF), U64(0x9B3CDB65F82CA382), U64(0xB67B7896167B4C84), U64(0xBFCED1B0048EAC50), - U64(0xA9119B60369FFEBD), U64(0x1FFF7AC80904BF45), U64(0xAC12FB171817EEE7), U64(0xAF08DA9177DDA93D), - U64(0x1B0CAB936E65C744), U64(0xB559EB1D04E5E932), U64(0xC37B45B3F8D6F2BA), U64(0xC3A9DC228CAAC9E9), - U64(0xF3B8B6675A6507FF), U64(0x9FC477DE4ED681DA), U64(0x67378D8ECCEF96CB), U64(0x6DD856D94D259236), - U64(0xA319CE15B0B4DB31), U64(0x073973751F12DD5E), U64(0x8A8E849EB32781A5), U64(0xE1925C71285279F5), - U64(0x74C04BF1790C0EFE), U64(0x4DDA48153C94938A), U64(0x9D266D6A1CC0542C), U64(0x7440FB816508C4FE), - U64(0x13328503DF48229F), U64(0xD6BF7BAEE43CAC40), U64(0x4838D65F6EF6748F), U64(0x1E152328F3318DEA), - U64(0x8F8419A348F296BF), U64(0x72C8834A5957B511), U64(0xD7A023A73260B45C), U64(0x94EBC8ABCFB56DAE), - U64(0x9FC10D0F989993E0), U64(0xDE68A2355B93CAE6), U64(0xA44CFE79AE538BBE), U64(0x9D1D84FCCE371425), - U64(0x51D2B1AB2DDFB636), U64(0x2FD7E4B9E72CD38C), U64(0x65CA5B96B7552210), U64(0xDD69A0D8AB3B546D), - U64(0x604D51B25FBF70E2), U64(0x73AA8A564FB7AC9E), U64(0x1A8C1E992B941148), U64(0xAAC40A2703D9BEA0), - U64(0x764DBEAE7FA4F3A6), U64(0x1E99B96E70A9BE8B), U64(0x2C5E9DEB57EF4743), U64(0x3A938FEE32D29981), - U64(0x26E6DB8FFDF5ADFE), U64(0x469356C504EC9F9D), U64(0xC8763C5B08D1908C), U64(0x3F6C6AF859D80055), - U64(0x7F7CC39420A3A545), U64(0x9BFB227EBDF4C5CE), U64(0x89039D79D6FC5C5C), U64(0x8FE88B57305E2AB6), - U64(0xA09E8C8C35AB96DE), U64(0xFA7E393983325753), U64(0xD6B6D0ECC617C699), U64(0xDFEA21EA9E7557E3), - U64(0xB67C1FA481680AF8), U64(0xCA1E3785A9E724E5), U64(0x1CFC8BED0D681639), U64(0xD18D8549D140CAEA), - U64(0x4ED0FE7E9DC91335), U64(0xE4DBF0634473F5D2), U64(0x1761F93A44D5AEFE), U64(0x53898E4C3910DA55), - U64(0x734DE8181F6EC39A), U64(0x2680B122BAA28D97), U64(0x298AF231C85BAFAB), U64(0x7983EED3740847D5), - U64(0x66C1A2A1A60CD889), U64(0x9E17E49642A3E4C1), U64(0xEDB454E7BADC0805), U64(0x50B704CAB602C329), - U64(0x4CC317FB9CDDD023), U64(0x66B4835D9EAFEA22), U64(0x219B97E26FFC81BD), U64(0x261E4E4C0A333A9D), - U64(0x1FE2CCA76517DB90), U64(0xD7504DFA8816EDBB), U64(0xB9571FA04DC089C8), U64(0x1DDC0325259B27DE), - U64(0xCF3F4688801EB9AA), U64(0xF4F5D05C10CAB243), U64(0x38B6525C21A42B0E), U64(0x36F60E2BA4FA6800), - U64(0xEB3593803173E0CE), U64(0x9C4CD6257C5A3603), U64(0xAF0C317D32ADAA8A), U64(0x258E5A80C7204C4B), - U64(0x8B889D624D44885D), U64(0xF4D14597E660F855), U64(0xD4347F66EC8941C3), U64(0xE699ED85B0DFB40D), - U64(0x2472F6207C2D0484), U64(0xC2A1E7B5B459AEB5), U64(0xAB4F6451CC1D45EC), U64(0x63767572AE3D6174), - U64(0xA59E0BD101731A28), U64(0x116D0016CB948F09), U64(0x2CF9C8CA052F6E9F), U64(0x0B090A7560A968E3), - U64(0xABEEDDB2DDE06FF1), U64(0x58EFC10B06A2068D), U64(0xC6E57A78FBD986E0), U64(0x2EAB8CA63CE802D7), - U64(0x14A195640116F336), U64(0x7C0828DD624EC390), U64(0xD74BBE77E6116AC7), U64(0x804456AF10F5FB53), - U64(0xEBE9EA2ADF4321C7), U64(0x03219A39EE587A30), U64(0x49787FEF17AF9924), U64(0xA1E9300CD8520548), - U64(0x5B45E522E4B1B4EF), U64(0xB49C3B3995091A36), U64(0xD4490AD526F14431), U64(0x12A8F216AF9418C2), - U64(0x001F837CC7350524), U64(0x1877B51E57A764D5), U64(0xA2853B80F17F58EE), U64(0x993E1DE72D36D310), - U64(0xB3598080CE64A656), U64(0x252F59CF0D9F04BB), U64(0xD23C8E176D113600), U64(0x1BDA0492E7E4586E), - U64(0x21E0BD5026C619BF), U64(0x3B097ADAF088F94E), U64(0x8D14DEDB30BE846E), U64(0xF95CFFA23AF5F6F4), - U64(0x3871700761B3F743), U64(0xCA672B91E9E4FA16), U64(0x64C8E531BFF53B55), U64(0x241260ED4AD1E87D), - U64(0x106C09B972D2E822), U64(0x7FBA195410E5CA30), U64(0x7884D9BC6CB569D8), U64(0x0647DFEDCD894A29), - U64(0x63573FF03E224774), U64(0x4FC8E9560F91B123), U64(0x1DB956E450275779), U64(0xB8D91274B9E9D4FB), - U64(0xA2EBEE47E2FBFCE1), U64(0xD9F1F30CCD97FB09), U64(0xEFED53D75FD64E6B), U64(0x2E6D02C36017F67F), - U64(0xA9AA4D20DB084E9B), U64(0xB64BE8D8B25396C1), U64(0x70CB6AF7C2D5BCF0), U64(0x98F076A4F7A2322E), - U64(0xBF84470805E69B5F), U64(0x94C3251F06F90CF3), U64(0x3E003E616A6591E9), U64(0xB925A6CD0421AFF3), - U64(0x61BDD1307C66E300), U64(0xBF8D5108E27E0D48), U64(0x240AB57A8B888B20), U64(0xFC87614BAF287E07), - U64(0xEF02CDD06FFDB432), U64(0xA1082C0466DF6C0A), U64(0x8215E577001332C8), U64(0xD39BB9C3A48DB6CF), - U64(0x2738259634305C14), U64(0x61CF4F94C97DF93D), U64(0x1B6BACA2AE4E125B), U64(0x758F450C88572E0B), - U64(0x959F587D507A8359), U64(0xB063E962E045F54D), U64(0x60E8ED72C0DFF5D1), U64(0x7B64978555326F9F), - U64(0xFD080D236DA814BA), U64(0x8C90FD9B083F4558), U64(0x106F72FE81E2C590), U64(0x7976033A39F7D952), - U64(0xA4EC0132764CA04B), U64(0x733EA705FAE4FA77), U64(0xB4D8F77BC3E56167), U64(0x9E21F4F903B33FD9), - U64(0x9D765E419FB69F6D), U64(0xD30C088BA61EA5EF), U64(0x5D94337FBFAF7F5B), U64(0x1A4E4822EB4D7A59), - U64(0x6FFE73E81B637FB3), U64(0xDDF957BC36D8B9CA), U64(0x64D0E29EEA8838B3), U64(0x08DD9BDFD96B9F63), - U64(0x087E79E5A57D1D13), U64(0xE328E230E3E2B3FB), U64(0x1C2559E30F0946BE), U64(0x720BF5F26F4D2EAA), - U64(0xB0774D261CC609DB), U64(0x443F64EC5A371195), U64(0x4112CF68649A260E), U64(0xD813F2FAB7F5C5CA), - U64(0x660D3257380841EE), U64(0x59AC2C7873F910A3), U64(0xE846963877671A17), U64(0x93B633ABFA3469F8), - U64(0xC0C0F5A60EF4CDCF), U64(0xCAF21ECD4377B28C), U64(0x57277707199B8175), U64(0x506C11B9D90E8B1D), - U64(0xD83CC2687A19255F), U64(0x4A29C6465A314CD1), U64(0xED2DF21216235097), U64(0xB5635C95FF7296E2), - U64(0x22AF003AB672E811), U64(0x52E762596BF68235), U64(0x9AEBA33AC6ECC6B0), U64(0x944F6DE09134DFB6), - U64(0x6C47BEC883A7DE39), U64(0x6AD047C430A12104), U64(0xA5B1CFDBA0AB4067), U64(0x7C45D833AFF07862), - U64(0x5092EF950A16DA0B), U64(0x9338E69C052B8E7B), U64(0x455A4B4CFE30E3F5), U64(0x6B02E63195AD0CF8), - U64(0x6B17B224BAD6BF27), U64(0xD1E0CCD25BB9C169), U64(0xDE0C89A556B9AE70), U64(0x50065E535A213CF6), - U64(0x9C1169FA2777B874), U64(0x78EDEFD694AF1EED), U64(0x6DC93D9526A50E68), U64(0xEE97F453F06791ED), - U64(0x32AB0EDB696703D3), U64(0x3A6853C7E70757A7), U64(0x31865CED6120F37D), U64(0x67FEF95D92607890), - U64(0x1F2B1D1F15F6DC9C), U64(0xB69E38A8965C6B65), U64(0xAA9119FF184CCCF4), U64(0xF43C732873F24C13), - U64(0xFB4A3D794A9A80D2), U64(0x3550C2321FD6109C), U64(0x371F77E76BB8417E), U64(0x6BFA9AAE5EC05779), - U64(0xCD04F3FF001A4778), U64(0xE3273522064480CA), U64(0x9F91508BFFCFC14A), U64(0x049A7F41061A9E60), - U64(0xFCB6BE43A9F2FE9B), U64(0x08DE8A1C7797DA9B), U64(0x8F9887E6078735A1), U64(0xB5B4071DBFC73A66), - U64(0x230E343DFBA08D33), U64(0x43ED7F5A0FAE657D), U64(0x3A88A0FBBCB05C63), U64(0x21874B8B4D2DBC4F), - U64(0x1BDEA12E35F6A8C9), U64(0x53C065C6C8E63528), U64(0xE34A1D250E7A8D6B), U64(0xD6B04D3B7651DD7E), - U64(0x5E90277E7CB39E2D), U64(0x2C046F22062DC67D), U64(0xB10BB459132D0A26), U64(0x3FA9DDFB67E2F199), - U64(0x0E09B88E1914F7AF), U64(0x10E8B35AF3EEAB37), U64(0x9EEDECA8E272B933), U64(0xD4C718BC4AE8AE5F), - U64(0x81536D601170FC20), U64(0x91B534F885818A06), U64(0xEC8177F83F900978), U64(0x190E714FADA5156E), - U64(0xB592BF39B0364963), U64(0x89C350C893AE7DC1), U64(0xAC042E70F8B383F2), U64(0xB49B52E587A1EE60), - U64(0xFB152FE3FF26DA89), U64(0x3E666E6F69AE2C15), U64(0x3B544EBE544C19F9), U64(0xE805A1E290CF2456), - U64(0x24B33C9D7ED25117), U64(0xE74733427B72F0C1), U64(0x0A804D18B7097475), U64(0x57E3306D881EDB4F), - U64(0x4AE7D6A36EB5DBCB), U64(0x2D8D5432157064C8), U64(0xD1E649DE1E7F268B), U64(0x8A328A1CEDFE552C), - U64(0x07A3AEC79624C7DA), U64(0x84547DDC3E203C94), U64(0x990A98FD5071D263), U64(0x1A4FF12616EEFC89), - U64(0xF6F7FD1431714200), U64(0x30C05B1BA332F41C), U64(0x8D2636B81555A786), U64(0x46C9FEB55D120902), - U64(0xCCEC0A73B49C9921), U64(0x4E9D2827355FC492), U64(0x19EBB029435DCB0F), U64(0x4659D2B743848A2C), - U64(0x963EF2C96B33BE31), U64(0x74F85198B05A2E7D), U64(0x5A0F544DD2B1FB18), U64(0x03727073C2E134B1), - U64(0xC7F6AA2DE59AEA61), U64(0x352787BAA0D7C22F), U64(0x9853EAB63B5E0B35), U64(0xABBDCDD7ED5C0860), - U64(0xCF05DAF5AC8D77B0), U64(0x49CAD48CEBF4A71E), U64(0x7A4C10EC2158C4A6), U64(0xD9E92AA246BF719E), - U64(0x13AE978D09FE5557), U64(0x730499AF921549FF), U64(0x4E4B705B92903BA4), U64(0xFF577222C14F0A3A), - U64(0x55B6344CF97AAFAE), U64(0xB862225B055B6960), U64(0xCAC09AFBDDD2CDB4), U64(0xDAF8E9829FE96B5F), - U64(0xB5FDFC5D3132C498), U64(0x310CB380DB6F7503), U64(0xE87FBB46217A360E), U64(0x2102AE466EBB1148), - U64(0xF8549E1A3AA5E00D), U64(0x07A69AFDCC42261A), U64(0xC4C118BFE78FEAAE), U64(0xF9F4892ED96BD438), - U64(0x1AF3DBE25D8F45DA), U64(0xF5B4B0B0D2DEEEB4), U64(0x962ACEEFA82E1C84), U64(0x046E3ECAAF453CE9), - U64(0xF05D129681949A4C), U64(0x964781CE734B3C84), U64(0x9C2ED44081CE5FBD), U64(0x522E23F3925E319E), - U64(0x177E00F9FC32F791), U64(0x2BC60A63A6F3B3F2), U64(0x222BBFAE61725606), U64(0x486289DDCC3D6780), - U64(0x7DC7785B8EFDFC80), U64(0x8AF38731C02BA980), U64(0x1FAB64EA29A2DDF7), U64(0xE4D9429322CD065A), - U64(0x9DA058C67844F20C), U64(0x24C0E332B70019B0), U64(0x233003B5A6CFE6AD), U64(0xD586BD01C5C217F6), - U64(0x5E5637885F29BC2B), U64(0x7EBA726D8C94094B), U64(0x0A56A5F0BFE39272), U64(0xD79476A84EE20D06), - U64(0x9E4C1269BAA4BF37), U64(0x17EFEE45B0DEE640), U64(0x1D95B0A5FCF90BC6), U64(0x93CBE0B699C2585D), - U64(0x65FA4F227A2B6D79), U64(0xD5F9E858292504D5), U64(0xC2B5A03F71471A6F), U64(0x59300222B4561E00), - U64(0xCE2F8642CA0712DC), U64(0x7CA9723FBB2E8988), U64(0x2785338347F2BA08), U64(0xC61BB3A141E50E8C), - U64(0x150F361DAB9DEC26), U64(0x9F6A419D382595F4), U64(0x64A53DC924FE7AC9), U64(0x142DE49FFF7A7C3D), - U64(0x0C335248857FA9E7), U64(0x0A9C32D5EAE45305), U64(0xE6C42178C4BBB92E), U64(0x71F1CE2490D20B07), - U64(0xF1BCC3D275AFE51A), U64(0xE728E8C83C334074), U64(0x96FBF83A12884624), U64(0x81A1549FD6573DA5), - U64(0x5FA7867CAF35E149), U64(0x56986E2EF3ED091B), U64(0x917F1DD5F8886C61), U64(0xD20D8C88C8FFE65F), - U64(0x31D71DCE64B2C310), U64(0xF165B587DF898190), U64(0xA57E6339DD2CF3A0), U64(0x1EF6E6DBB1961EC9), - U64(0x70CC73D90BC26E24), U64(0xE21A6B35DF0C3AD7), U64(0x003A93D8B2806962), U64(0x1C99DED33CB890A1), - U64(0xCF3145DE0ADD4289), U64(0xD0E4427A5514FB72), U64(0x77C621CC9FB3A483), U64(0x67A34DAC4356550B), - U64(0xF8D626AAAF278509), -}; - -// functions - -// random_init() - -void random_init() { - - if ((Random64[RandomNb-1] >> 32) != 0xF8D626AA) { // upper half of the last element of the array - my_fatal("random_init(): broken 64-bit types\n"); - } -} - -// random_64() - -uint64 random_64(int n) { - - ASSERT(n>=0&&n -#include -#include -#include - -#include "attack.h" -#include "board.h" -#include "list.h" -#include "move.h" -#include "move_gen.h" -#include "move_legal.h" -#include "piece.h" -#include "san.h" -#include "square.h" -#include "util.h" - -// constants - -static const bool UseSlowDebug = false; - -enum ambiguity_t { - AMBIGUITY_NONE, - AMBIGUITY_FILE, - AMBIGUITY_RANK, - AMBIGUITY_SQUARE -}; - -// functions - -static bool san_to_lan (const char san[], const board_t * board, char string[], int size); -static int move_from_lan (const char string[], const board_t * board); - -static int ambiguity (int move, const board_t * board); - -// move_to_san() - -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; -} - -// move_from_san() - -int move_from_san(const char string[], const board_t * board) { - - char s[256]; - int move; - - ASSERT(string!=NULL); - ASSERT(board_is_ok(board)); - - san_to_lan(string,board,s,256); - move = move_from_lan(s,board); - - ASSERT(!UseSlowDebug||move==move_from_san_debug(string,board)); - - return move; -} - -// move_from_san_debug() - -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; -} - -// san_to_lan() - -static bool san_to_lan(const char san[], const board_t * board, char string[], int size) { - - int len; - int left, right; - int c; - int king, rook; - char king_string[3], rook_string[3]; - - ASSERT(san!=NULL); - ASSERT(board_is_ok(board)); - ASSERT(string!=NULL); - ASSERT(size>=8); - - // init - - if (size < 8) return false; - strcpy(string,"???????"); - - len = strlen(san); - - left = 0; - right = len; - - // skip trailing '+' or '#' - - if (left < right) { - c = san[right-1]; - if (c == '+' || c == '#') right--; - } - - // castling - - ASSERT(left==0); - - if (false) { - - } else if (right == 3 && strncmp(san,"O-O",3) == 0) { - - if (board->castle[board->turn][SideH] == SquareNone) return false; - - king = king_pos(board,board->turn); - rook = board->castle[board->turn][SideH]; - - square_to_string(king,king_string,3); - square_to_string(rook,rook_string,3); - - sprintf(string,"K%s?%s?",king_string,rook_string); - - } else if (right == 5 && strncmp(san,"O-O-O",5) == 0) { - - if (board->castle[board->turn][SideA] == SquareNone) return false; - - king = king_pos(board,board->turn); - rook = board->castle[board->turn][SideA]; - - square_to_string(king,king_string,3); - square_to_string(rook,rook_string,3); - - sprintf(string,"K%s?%s?",king_string,rook_string); - - } else { - - // moved piece - - if (left < right) { - - c = san[left]; - - if (char_is_piece(c)) { - string[0] = c; - left++; - } - } - - // promotion - - if (left < right) { - - c = toupper(san[right-1]); - - if (char_is_piece(c)) { - - string[6] = c; - right--; - - // skip '=' - - if (left < right && san[right-1] == '=') right--; - } - } - - // to-square rank - - if (left < right) { - - c = san[right-1]; - - if (char_is_rank(c)) { - string[5] = c; - right--; - } - } - - // to-square file - - if (left < right) { - - c = san[right-1]; - - if (char_is_file(c)) { - string[4] = c; - right--; - } - } - - // captured piece - - if (left < right) { - - c = san[right-1]; - - if (char_is_piece(c)) { - string[3] = c; - right--; - } - } - - // skip middle '-' or 'x' - - if (left < right) { - c = san[right-1]; - if (c == '-' || c == 'x') right--; - } - - // from-square file - - if (left < right) { - - c = san[left]; - - if (char_is_file(c)) { - string[1] = c; - left++; - } - } - - // from-square rank - - if (left < right) { - - c = san[left]; - - if (char_is_rank(c)) { - string[2] = c; - left++; - } - } - - if (left != right) return false; - } - - // end - - return true; -} - -// move_from_lan() - -static int move_from_lan(const char string[], const board_t * board) { - - int len; - int move; - int promote; - char s[256]; - int from, to; - int colour; - int inc; - int piece_char; - int n; - const uint8 * ptr; - int piece; - int side; - - ASSERT(string!=NULL); - ASSERT(board_is_ok(board)); - - // init - - len = strlen(string); - if (len != 7) return MoveNone; - - move = MoveNone; - colour = board->turn; - - // promote - - promote = 0; - - switch (string[6]) { - case '?': // not a promotion - break; - case 'N': - promote = MovePromoteKnight; - break; - case 'B': - promote = MovePromoteBishop; - break; - case 'R': - promote = MovePromoteRook; - break; - case 'Q': - promote = MovePromoteQueen; - break; - default: - return MoveNone; - break; - } - - // to square - - s[0] = string[4]; - s[1] = string[5]; - s[2] = '\0'; - - to = square_from_string(s); - if (to == SquareNone) return MoveNone; - - // known from square? - - if (string[1] != '?' && string[2] != '?') { - - // from square - - s[0] = string[1]; - s[1] = string[2]; - s[2] = '\0'; - - from = square_from_string(s); - if (from == SquareNone) return MoveNone; - - // convert "king slide" castling to KxR - - if (piece_is_king(board->square[from]) - && square_rank(to) == square_rank(from) - && abs(to-from) > 1) { - side = (to > from) ? SideH : SideA; - to = board->castle[colour][side]; - if (to == SquareNone) return MoveNone; - } - - // move - - move = move_make(from,to) | promote; - - return move; - } - - // pawn non-capture? - - if (string[0] == '?' && string[1] == '?') { - - if (board->square[to] != Empty) return MoveNone; // useful? - - inc = (colour_is_white(colour)) ? +16 : -16; - - from = to - inc; - if (board->square[from] == Empty && square_side_rank(to,colour) == Rank4) { - from -= inc; - } - - if (board->square[from] != piece_make_pawn(colour)) { // useful? - return MoveNone; - } - - // move - - move = move_make(from,to) | promote; - - return move; - } - - // pawn capture? - - piece_char = string[0]; - - if (piece_char == '?' && string[1] != '?') { - piece_char = 'P'; - } - - // attack loop - - n = 0; - - for (ptr = board->list[colour]; (from=*ptr) != SquareNone; ptr++) { - - piece = board->square[from]; - - if (toupper(piece_to_char(piece)) == piece_char) { - if (piece_attack(board,piece,from,to)) { - if (true - && (string[1] == '?' || file_to_char(square_file(from)) == string[1]) - && (string[2] == '?' || rank_to_char(square_rank(from)) == string[2])) { - if (!is_pinned(board,from,to,colour)) { - move = move_make(from,to) | promote; - n++; - } - } - } - } - } - - if (n != 1) move = MoveNone; - - return move; -} - -// ambiguity() - -static int ambiguity(int move, const board_t * board) { - - int from, to, piece; - list_t list[1]; - int i, n, m; - - // init - - from = move_from(move); - to = move_to(move); - piece = move_piece(move,board); - - gen_legal_moves(list,board); - - // no ambiguity? - - n = 0; - - for (i = 0; i < list_size(list); i++) { - m = list_move(list,i); - if (move_piece(m,board) == piece && move_to(m) == to) { - n++; - } - } - - if (n == 1) return AMBIGUITY_NONE; - - // file ambiguity? - - n = 0; - - for (i = 0; i < list_size(list); i++) { - m = list_move(list,i); - if (move_piece(m,board) == piece && move_to(m) == to) { - if (square_file(move_from(m)) == square_file(from)) n++; - } - } - - if (n == 1) return AMBIGUITY_FILE; - - // rank ambiguity? - - n = 0; - - for (i = 0; i < list_size(list); i++) { - m = list_move(list,i); - if (move_piece(m,board) == piece && move_to(m) == to) { - if (square_rank(move_from(m)) == square_rank(from)) n++; - } - } - - if (n == 1) return AMBIGUITY_RANK; - - // square ambiguity - - return AMBIGUITY_SQUARE; -} - -// end of san.cpp - diff --git a/search.cpp b/search.cpp deleted file mode 100644 index 8b1ae60..0000000 --- a/search.cpp +++ /dev/null @@ -1,252 +0,0 @@ -// search.cpp - -// includes - -#include -#include -#include - -#include "attack.h" -#include "board.h" -#include "colour.h" -#include "engine.h" -#include "fen.h" -#include "line.h" -#include "list.h" -#include "move.h" -#include "move_do.h" -#include "move_gen.h" -#include "move_legal.h" -#include "option.h" -#include "parse.h" -#include "san.h" -#include "search.h" -#include "uci.h" -#include "util.h" - -// constants - -static const int StringSize = 4096; - -// variables - -static int Depth; - -static int BestMove; -static int BestValue; -static move_t BestPV[LineSize]; - -static sint64 NodeNb; -static sint64 LeafNb; -static double Time; - -static int Move; -static int MovePos; -static int MoveNb; - -// prototypes - -static bool depth_is_ok (int depth); -static void perft (const board_t * board, int depth); - -// functions - -// depth_is_ok() - -static bool depth_is_ok(int depth) { - - return depth >= 0 && depth < DepthMax; -} - -// search() - -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=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 (!engine_eof(Engine)) { - - 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"); -} - -// do_perft() - -void do_perft(int argc,char * argv[]){ - const char * fen=NULL; - int depth=1; - board_t board[1]; - int i; - for (i = 1; i < argc; i++) { - if (false) { - } else if (my_string_equal(argv[i],"perft")) { - // skip - } else if (my_string_equal(argv[i],"-fen")) { - i++; - if (argv[i] == NULL) my_fatal("do_perft(): missing argument\n"); - my_string_set(&fen,argv[i]); - } else if (my_string_equal(argv[i],"-max-depth")){ - i++; - if (argv[i] == NULL) my_fatal("do_perft(): missing argument\n"); - depth=atoi(argv[i]); - if(depth<1) my_fatal("do_perft(): illegal depth %d\n",depth); - } else { - my_fatal("do_perft(): unknown option \"%s\"\n",argv[i]); - } - } - if(fen==NULL){ - my_string_set(&fen,StartFen); - } - board_from_fen(board,fen); - search_perft(board,depth); -} - -// search_perft() - -void search_perft(const board_t * board, int depth_max) { - - int depth; - my_timer_t timer[1]; - double time, speed; - char node_string[StringSize]; - char leafnode_string[StringSize]; - - ASSERT(board_is_ok(board)); - ASSERT(depth_max>=1&&depth_maxturn))); - - // init - - NodeNb++; - - // leaf - - if (depth == 0) { - LeafNb++; - return; - } - - // more init - - me = board->turn; - - // move loop - - gen_moves(list,board); - - for (i = 0; i < list_size(list); i++) { - - move = list_move(list,i); - - board_copy(new_board,board); - move_do(new_board,move); - - if (!is_in_check(new_board,me)) perft(new_board,depth-1); - } -} - -// end of search.cpp - diff --git a/square.cpp b/square.cpp deleted file mode 100644 index 2519d38..0000000 --- a/square.cpp +++ /dev/null @@ -1,246 +0,0 @@ - -// square.cpp - -// includes - -#include "colour.h" -#include "square.h" -#include "util.h" - -// "constants" - -static const uint8 SquareFrom64[64] = { - A1, B1, C1, D1, E1, F1, G1, H1, - A2, B2, C2, D2, E2, F2, G2, H2, - A3, B3, C3, D3, E3, F3, G3, H3, - A4, B4, C4, D4, E4, F4, G4, H4, - A5, B5, C5, D5, E5, F5, G5, H5, - A6, B6, C6, D6, E6, F6, G6, H6, - A7, B7, C7, D7, E7, F7, G7, H7, - A8, B8, C8, D8, E8, F8, G8, H8, -}; - -// variables - -static sint8 SquareTo64[SquareNb]; - -// functions - -// square_init() - -void square_init() { - - int sq; - - for (sq = 0; sq < SquareNb; sq++) SquareTo64[sq] = -1; - - for (sq = 0; sq < 64; sq++) { - SquareTo64[SquareFrom64[sq]] = sq; - } -} - -// square_is_ok() - -bool square_is_ok(int square) { - - if (square < 0 || square >= SquareNb) return false; - - if (SquareTo64[square] < 0) return false; - - return true; -} - -// square_make() - -int square_make(int file, int rank) { - - int sq_64; - - ASSERT(file>=0&&file<8); - ASSERT(rank>=0&&rank<8); - - sq_64 = (rank << 3) | file; - - return square_from_64(sq_64); -} - -// square_file() - -int square_file(int square) { - - int file; - - ASSERT(square_is_ok(square)); - - file = (square - 4) & 7; - ASSERT(file==(square_to_64(square)&7)); - - return file; -} - -// square_rank() - -int square_rank(int square) { - - int rank; - - ASSERT(square_is_ok(square)); - - rank = (square >> 4) - 2; - ASSERT(rank==square_to_64(square)>>3); - - return rank; -} - -// square_side_rank() - -int square_side_rank(int square, int colour) { - - int rank; - - ASSERT(square_is_ok(square)); - ASSERT(colour_is_ok(colour)); - - rank = square_rank(square); - if (colour_is_black(colour)) rank = 7-rank; - - return rank; -} - -// square_from_64() - -int square_from_64(int square) { - - ASSERT(square>=0&&square<64); - - return SquareFrom64[square]; -} - -// square_to_64() - -int square_to_64(int square) { - - ASSERT(square_is_ok(square)); - - return SquareTo64[square]; -} - -// square_is_promote() - -bool square_is_promote(int square) { - - int rank; - - ASSERT(square_is_ok(square)); - - rank = square_rank(square); - - return rank == Rank1 || rank == Rank8; -} - -// square_ep_dual() - -int square_ep_dual(int square) { - - ASSERT(square_is_ok(square)); - ASSERT(square_rank(square)>=2&&square_rank(square)<=5); - - return square ^ 16; -} - -// square_colour() - -int square_colour(int square) { - - ASSERT(square_is_ok(square)); - - return (square ^ (square >> 4)) & 1; -} - -// file_from_char() - -int file_from_char(int c) { - - ASSERT(c>='a'&&c<='h'); - - return c - 'a'; -} - -// rank_from_char() - -int rank_from_char(int c) { - - ASSERT(c>='1'&&c<='8'); - - return c - '1'; -} - -// file_to_char() - -int file_to_char(int file) { - - ASSERT(file>=0&&file<8); - - return 'a' + file; -} - -// rank_to_char() - -int rank_to_char(int rank) { - - ASSERT(rank>=0&&rank<8); - - return '1' + rank; -} - -// char_is_file() - -bool char_is_file(int c) { - - return c >= 'a' && c <= 'h'; -} - -// char_is_rank() - -bool char_is_rank(int c) { - - return c >= '1' && c <= '8'; -} - -// square_to_string() - -bool square_to_string(int square, char string[], int size) { - - ASSERT(square_is_ok(square)); - ASSERT(string!=NULL); - ASSERT(size>=3); - - if (size < 3) return false; - - string[0] = 'a' + square_file(square); - string[1] = '1' + square_rank(square); - string[2] = '\0'; - - return true; -} - -// square_from_string() - -int square_from_string(const char string[]) { - - int file, rank; - - ASSERT(string!=NULL); - - if (string[0] < 'a' || string[0] > 'h') return SquareNone; - if (string[1] < '1' || string[1] > '8') return SquareNone; - if (string[2] != '\0') return SquareNone; - - file = file_from_char(string[0]); - rank = rank_from_char(string[1]); - - return square_make(file,rank); -} - -// end of square.cpp - diff --git a/uci.cpp b/uci.cpp deleted file mode 100644 index 35b84de..0000000 --- a/uci.cpp +++ /dev/null @@ -1,978 +0,0 @@ - -// uci.cpp - -// includes - -#include -#include -#include -#include - -#include "board.h" -#include "engine.h" -#include "move.h" -#include "move_do.h" -#include "move_legal.h" -#include "option.h" -#include "parse.h" -#include "line.h" -#include "uci.h" - -// constants - -static const bool UseDebug = false; - -static const int StringSize = 4096; - -// variables - -uci_t Uci[1]; - -// Hopefully the following confusion is temporary -// Normally we should check for the engine name but this is a hack anyway -// Some of there where provided by Marc Lacrosse - -const char * thread_options[]={ - "number of threads", // toga - "number threads", // Deep Learning Toga - "threads", // glaurung, zappa, cyclone, grapefruit, - // Deep Shredder, Deep Junior - "core threads", // HIARCS - "max cpus", // rybka - "cpus", // Deep Sjeng, Fruit2.3.5 - "maxthreads", // Naum - NULL -}; - -// prototypes - -static bool uci_is_ok (const uci_t * uci); - -static int parse_bestmove (uci_t * uci, const char string[]); -static void parse_id (uci_t * uci, const char string[]); -static int parse_info (uci_t * uci, const char string[]); -static void parse_option (uci_t * uci, const char string[]); -static void parse_score (uci_t * uci, const char string[]); - -static int mate_score (int dist); - -// functions - -// uci_set_threads() - -void uci_set_threads(uci_t * uci, int n) { - const char **thread_options_copy = thread_options; - const char *thread_option; - ASSERT(n>=1); - while((thread_option = *(thread_options_copy++))){ - uci_send_option(uci,thread_option,"%d",n); // checks also for existence - } -} - -// uci_thread_option_exists() - -bool uci_thread_option_exist(uci_t * uci) { - const char **thread_options_copy = thread_options; - const char *thread_option; - while((thread_option = *(thread_options_copy++))){ - if(uci_option_exist(uci,thread_option)) return true; - } - return false; -} - -const char * uci_thread_option(uci_t * uci){ - const char **thread_options_copy = thread_options; - const char *thread_option; - int i; - while((thread_option = *(thread_options_copy++))){ - i=uci_get_option(uci,thread_option); - if(i>=0){ - return Uci->option[i].name; - break; - } - } - return NULL; -} - -// uci_is_ok() - -static bool uci_is_ok(const uci_t * uci) { - - if (uci == NULL) return false; - if (uci->engine == NULL) return false; - if (uci->option_nb < 0 || uci->option_nb >= OptionNb) return false; - - return true; -} - -// uci_open() - -void uci_open(uci_t * uci, engine_t * engine) { - - char string[StringSize]; - int event; - - ASSERT(uci!=NULL); - ASSERT(engine!=NULL); - - // init - - uci->engine = engine; - - uci->name = NULL; - my_string_set(&uci->name,""); - uci->author = NULL; - my_string_set(&uci->author,""); - uci->option_nb = 0; - - uci->ready_nb = 0; - uci->searching = 0; - uci->pending_nb = 0; - uci->multipv_mode = false; - board_start(uci->board); - uci_clear(uci); - - // send "uci" and wait for "uciok" - - engine_send(uci->engine,"uci"); - - do { - engine_get(uci->engine,string,StringSize); - event = uci_parse(uci,string); - } while (!engine_eof(Engine) && (event & EVENT_UCI) == 0); -} - -// uci_close() - -void uci_close(uci_t * uci) { - - int i; - option_t * opt; - - ASSERT(uci_is_ok(uci)); - engine_close(uci->engine); - uci->engine = NULL; - my_string_clear(&uci->name); - my_string_clear(&uci->author); - - for (i = 0; i < uci->option_nb; i++) { - opt = &uci->option[i]; - my_string_clear(&opt->name); - my_string_clear(&opt->default_); - } - - uci->option_nb = 0; -} - -// uci_clear() - -void uci_clear(uci_t * uci) { - - ASSERT(uci_is_ok(uci)); - - ASSERT(!uci->searching); - - uci->best_move = MoveNone; - uci->ponder_move = MoveNone; - - uci->score = 0; - uci->depth = 0; - uci->sel_depth = 0; - line_clear(uci->pv); - - uci->best_score = 0; - uci->best_depth = 0; - uci->best_sel_depth = 0; - line_clear(uci->best_pv); - - uci->node_nb = 0; - uci->time = 0.0; - uci->speed = 0.0; - uci->cpu = 0.0; - uci->hash = 0.0; - line_clear(uci->current_line); - - uci->root_move = MoveNone; - uci->root_move_pos = 0; - uci->root_move_nb = board_mobility(uci->board); -} - -// uci_send_isready() - -void uci_send_isready(uci_t * uci) { - - ASSERT(uci!=NULL); - - engine_send(uci->engine,"isready"); - uci->ready_nb++; -} - -// uci_send_isready_sync() - -void uci_send_isready_sync(uci_t * uci) { - - char string[StringSize]; - int event; - - ASSERT(uci_is_ok(uci)); - - // send "isready" and wait for "readyok" - - uci_send_isready(uci); - - do { - engine_get(uci->engine,string,StringSize); - event = uci_parse(uci,string); - } while (!engine_eof(Engine) && (event & EVENT_READY) == 0); -} - -// uci_send_stop() - -void uci_send_stop(uci_t * uci) { - - ASSERT(uci_is_ok(uci)); - - ASSERT(uci->searching); - ASSERT(uci->pending_nb>=1); - - engine_send(Engine,"stop"); - uci->searching = false; -} - -// uci_send_stop_sync() - -void uci_send_stop_sync(uci_t * uci) { - - char string[StringSize]; - int event; - - ASSERT(uci_is_ok(uci)); - - ASSERT(uci->searching); - ASSERT(uci->pending_nb>=1); - - // send "stop" and wait for "bestmove" - - uci_send_stop(uci); - - do { - engine_get(uci->engine,string,StringSize); - event = uci_parse(uci,string); - } while (!engine_eof(Engine) && (event & EVENT_STOP) == 0); -} - -// uci_send_ucinewgame() - -void uci_send_ucinewgame(uci_t * uci) { - - ASSERT(uci!=NULL); - - if (option_get_int("UCIVersion") >= 2) { - engine_send(uci->engine,"ucinewgame"); - } -} - -// uci_option_exist() - -bool uci_option_exist(uci_t * uci, const char option[]) { - - int i; - option_t * opt; - - ASSERT(uci_is_ok(uci)); - ASSERT(option!=NULL); - - // scan options - - for (i = 0; i < uci->option_nb; i++) { - opt = &uci->option[i]; - if (my_string_case_equal(opt->name,option)) return true; - } - - return false; -} - -// uci_send_option() - -void uci_send_option(uci_t * uci, const char option[], const char format[], ...) { - - va_list arg_list; - char value[StringSize]; - int i; - option_t * opt; - - ASSERT(uci_is_ok(uci)); - ASSERT(option!=NULL); - ASSERT(format!=NULL); - - // format - - va_start(arg_list,format); - vsprintf(value,format,arg_list); - va_end(arg_list); - - if (UseDebug) my_log("POLYGLOT OPTION %s VALUE %s\n",option,value); - - // scan options - - for (i = 0; i < uci->option_nb; i++) { - - opt = &uci->option[i]; - - if (my_string_case_equal(opt->name,option) && !my_string_equal(opt->default_,value)) { - engine_send(uci->engine,"setoption name %s value %s",opt->name,value); - my_string_set(&opt->default_,value); - break; - } - } -} - -// uci_parse() - -int uci_parse(uci_t * uci, const char string[]) { - - int event; - parse_t parse[1]; - char command[StringSize]; - char argument[StringSize]; - - ASSERT(uci_is_ok(uci)); - ASSERT(string!=NULL); - - // init - - event = EVENT_NONE; - - // parse - - parse_open(parse,string); - - if (parse_get_word(parse,command,StringSize)) { - - parse_get_string(parse,argument,StringSize); - if (UseDebug) my_log("POLYGLOT COMMAND \"%s\" ARGUMENT \"%s\"\n",command,argument); - - if (false) { - - } else if (my_string_equal(command,"bestmove")) { - - // search end - - ASSERT(uci->pending_nb>0); - - if (uci->searching && uci->pending_nb == 1) { - - // current search - - uci->searching = false; - uci->pending_nb--; - - event = parse_bestmove(uci,argument); // updates uci->best_move and uci->ponder_move - - } else { - - // obsolete search - - if (uci->pending_nb > 0) { - uci->pending_nb--; - if (uci->pending_nb == 0) event = EVENT_STOP; - } - } - - } else if (my_string_equal(command,"id")) { - - parse_id(uci,argument); - - } else if (my_string_equal(command,"info")) { - - // search information - - if (uci->searching && uci->pending_nb == 1) { // current search - event = parse_info(uci,argument); - } - - } else if (my_string_equal(command,"option")) { - - parse_option(uci,argument); - - } else if (my_string_equal(command,"readyok")) { - - // engine is ready - - ASSERT(uci->ready_nb>0); - - if (uci->ready_nb > 0) { - uci->ready_nb--; - if (uci->ready_nb == 0) event = EVENT_READY; - } - - } else if (my_string_equal(command,"uciok")) { - - event = EVENT_UCI; - - } else { - - if (UseDebug) my_log("POLYGLOT unknown command \"%s\"\n",command); - } - } - - parse_close(parse); - - return event; -} - -// parse_bestmove() - -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; -} - -// parse_id() - -static void parse_id(uci_t * uci, const char string[]) { - - parse_t parse[1]; - char command[StringSize]; - char option[StringSize]; - char argument[StringSize]; - - ASSERT(uci!=NULL); - ASSERT(string!=NULL); - - // init - - strcpy(command,"id"); - - parse_open(parse,string); - parse_add_keyword(parse,"author"); - parse_add_keyword(parse,"name"); - - // 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,"author")) { - ASSERT(!my_string_empty(argument)); - my_string_set(&uci->author,argument); - } else if (my_string_equal(option,"name")) { - ASSERT(!my_string_empty(argument)); - my_string_set(&uci->name,argument); - } else { - my_log("POLYGLOT unknown option \"%s\" for command \"%s\"\n",option,command); - } - } - - parse_close(parse); - - if (UseDebug) my_log("POLYGLOT engine name \"%s\" author \"%s\"\n",uci->name,uci->author); -} - -// parse_info() - -static int parse_info(uci_t * uci, const char string[]) { - - int event; - parse_t parse[1]; - char command[StringSize]; - char option[StringSize]; - char argument[StringSize]; - int n; - int multipvline=0; - sint64 ln; - - ASSERT(uci_is_ok(uci)); - ASSERT(string!=NULL); - - // init - - event = EVENT_NONE; - - strcpy(command,"info"); - - parse_open(parse,string); - parse_add_keyword(parse,"cpuload"); - parse_add_keyword(parse,"currline"); - parse_add_keyword(parse,"currmove"); - parse_add_keyword(parse,"currmovenumber"); - parse_add_keyword(parse,"depth"); - parse_add_keyword(parse,"hashfull"); - parse_add_keyword(parse,"multipv"); - parse_add_keyword(parse,"nodes"); - parse_add_keyword(parse,"nps"); - parse_add_keyword(parse,"pv"); - parse_add_keyword(parse,"refutation"); - parse_add_keyword(parse,"score"); - parse_add_keyword(parse,"seldepth"); - parse_add_keyword(parse,"string"); - parse_add_keyword(parse,"tbhits"); - parse_add_keyword(parse,"time"); - - // 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,"cpuload")) { - - ASSERT(!my_string_empty(argument)); - - n = atoi(argument); - ASSERT(n>=0); - - if (n >= 0) uci->cpu = double(n) / 1000.0; - - } else if (my_string_equal(option,"currline")) { - - ASSERT(!my_string_empty(argument)); - - line_from_can(uci->current_line,uci->board,argument,LineSize); - - } else if (my_string_equal(option,"currmove")) { - - ASSERT(!my_string_empty(argument)); - - uci->root_move = move_from_can(argument,uci->board); - ASSERT(uci->root_move!=MoveNone); - - } else if (my_string_equal(option,"currmovenumber")) { - - ASSERT(!my_string_empty(argument)); - - n = atoi(argument); - ASSERT(n>=1&&n<=uci->root_move_nb); - - if (n >= 1 && n <= uci->root_move_nb) { - uci->root_move_pos = n - 1; - ASSERT(uci->root_move_pos>=0&&uci->root_move_posroot_move_nb); - } - - } else if (my_string_equal(option,"depth")) { - - ASSERT(!my_string_empty(argument)); - - n = atoi(argument); - ASSERT(n>=1); - - if (n >= 0) { - if (n > uci->depth) event |= EVENT_DEPTH; - uci->depth = n; - } - - } else if (my_string_equal(option,"hashfull")) { - - ASSERT(!my_string_empty(argument)); - - n = atoi(argument); - ASSERT(n>=0); - - if (n >= 0) uci->hash = double(n) / 1000.0; - - } else if (my_string_equal(option,"multipv")) { - - ASSERT(!my_string_empty(argument)); - - n = atoi(argument); - if(Uci->multipv_mode) multipvline=n; - - ASSERT(n>=1); - - } else if (my_string_equal(option,"nodes")) { - - ASSERT(!my_string_empty(argument)); - - ln = my_atoll(argument); - ASSERT(ln>=0); - - if (ln >= 0) uci->node_nb = ln; - - } else if (my_string_equal(option,"nps")) { - - ASSERT(!my_string_empty(argument)); - - n = atoi(argument); - ASSERT(n>=0); - - if (n >= 0) uci->speed = double(n); - - } else if (my_string_equal(option,"pv")) { - - ASSERT(!my_string_empty(argument)); - - line_from_can(uci->pv,uci->board,argument,LineSize); - event |= EVENT_PV; - - } else if (my_string_equal(option,"refutation")) { - - ASSERT(!my_string_empty(argument)); - - line_from_can(uci->pv,uci->board,argument,LineSize); - - } else if (my_string_equal(option,"score")) { - - ASSERT(!my_string_empty(argument)); - - parse_score(uci,argument); - - } else if (my_string_equal(option,"seldepth")) { - - ASSERT(!my_string_empty(argument)); - - n = atoi(argument); - ASSERT(n>=0); - - if (n >= 0) uci->sel_depth = n; - - } else if (my_string_equal(option,"string")) { - if(!strncmp(argument,"DrawOffer",9)) - event |= EVENT_DRAW; - if(!strncmp(argument,"Resign",6)) - event |= EVENT_RESIGN; - - // TODO: argument to EOS - - ASSERT(!my_string_empty(argument)); - - } else if (my_string_equal(option,"tbhits")) { - - ASSERT(!my_string_empty(argument)); - - ln = my_atoll(argument); - ASSERT(ln>=0); - - } else if (my_string_equal(option,"time")) { - - ASSERT(!my_string_empty(argument)); - - n = atoi(argument); - ASSERT(n>=0); - - if (n >= 0) uci->time = double(n) / 1000.0; - - } else { - - my_log("POLYGLOT unknown option \"%s\" for command \"%s\"\n",option,command); - } - } - - parse_close(parse); - - // update display - //lousy uci,filter out lower depth multipv lines that have been repeated from the engine - if(multipvline>1 && uci->depthbest_depth) event &= ~EVENT_PV; - if ((event & EVENT_PV) != 0) { - uci->best_score = uci->score; - uci->best_depth = uci->depth; - if(multipvline==1)uci->depth=-1; //HACK ,clears the engine outpout window,see send_pv in adapter.cpp - uci->best_sel_depth = uci->sel_depth; - line_copy(uci->best_pv,uci->pv); - } - return event; -} - -int uci_get_option(uci_t * uci, const char * name){ - int i; - for(i=0;ioption_nb;i++){ - if(my_string_case_equal(Uci->option[i].name,name)){ - return i; - } - } - return -1; -} - - - -// uci_set_option() - -void uci_set_option(uci_t * uci, - const char * name, - const char * default_, - const char * type, - const char * max, - const char * min, - int var_nb, - const char * var[]){ - int i,j; - for(i=0;ioption_nb;i++){ - if(my_string_equal(Uci->option[i].name,name)){ - break; - } - } - if(ioption[i].name),name); - my_string_set(&(Uci->option[i].default_),default_); - my_string_set(&(Uci->option[i].type),type); - my_string_set(&(Uci->option[i].min),min); - my_string_set(&(Uci->option[i].max),max); - Uci->option[i].var_nb=var_nb; - for(j=0;joption[i].var[j]),var[j]); - } - if(i==Uci->option_nb){ - Uci->option_nb++; - } - } -} - -// parse_option() - -static void parse_option(uci_t * uci, const char string[]) { - - option_t * opt; - parse_t parse[1]; - char command[StringSize]; - char option[StringSize]; - char argument[StringSize]; - - ASSERT(uci!=NULL); - ASSERT(string!=NULL); - - // init - - strcpy(command,"option"); - - if (uci->option_nb >= OptionNb) return; - - opt = &uci->option[uci->option_nb]; - uci->option_nb++; - - opt->value=NULL; - my_string_set(&opt->value,""); - opt->mode=0; - - opt->name = NULL; - my_string_set(&opt->name,""); - - - opt->default_ = NULL; - my_string_set(&opt->default_,""); - - opt->max = NULL; - my_string_set(&opt->max,""); - - opt->min = NULL; - my_string_set(&opt->min,""); - - opt->type = NULL; - my_string_set(&opt->type,""); - - opt->var_nb=0; - - parse_open(parse,string); - parse_add_keyword(parse,"default"); - parse_add_keyword(parse,"max"); - parse_add_keyword(parse,"min"); - parse_add_keyword(parse,"name"); - parse_add_keyword(parse,"type"); - parse_add_keyword(parse,"var"); - - // 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,"default")) { - - // ASSERT(!my_string_empty(argument)); // HACK for Pepito - - if (!my_string_empty(argument)) { - my_string_set(&opt->default_,argument); - my_string_set(&opt->value,argument); - } - - } else if (my_string_equal(option,"max")) { - - ASSERT(!my_string_empty(argument)); - my_string_set(&opt->max,argument); - - } else if (my_string_equal(option,"min")) { - - ASSERT(!my_string_empty(argument)); - my_string_set(&opt->min,argument); - - } else if (my_string_equal(option,"name")) { - - ASSERT(!my_string_empty(argument)); - - if (!my_string_empty(argument)) { - my_string_set(&opt->name,argument); - } - - } else if (my_string_equal(option,"type")) { - - ASSERT(!my_string_empty(argument)); - my_string_set(&opt->type,argument); - - } else if (my_string_equal(option,"var")) { - - ASSERT(!my_string_empty(argument)); - my_string_set(&opt->var[opt->var_nb++],argument); - if(opt->var_nb==VarNb) break; - - } else { - - my_log("POLYGLOT unknown option \"%s\" for command \"%s\"\n",option,command); - } - } - - parse_close(parse); - - if (UseDebug) my_log("POLYGLOT option name \"%s\" default \"%s\"\n",opt->name,opt->default_); -} - -// parse_score() - -static void parse_score(uci_t * uci, const char string[]) { - - parse_t parse[1]; - char command[StringSize]; - char option[StringSize]; - char argument[StringSize]; - int n; - - ASSERT(uci_is_ok(uci)); - ASSERT(string!=NULL); - - // init - - strcpy(command,"score"); - - parse_open(parse,string); - parse_add_keyword(parse,"cp"); - parse_add_keyword(parse,"lowerbound"); - parse_add_keyword(parse,"mate"); - parse_add_keyword(parse,"upperbound"); - - // 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,"cp")) { - - ASSERT(!my_string_empty(argument)); - - n = atoi(argument); - - uci->score = n; - - } else if (my_string_equal(option,"lowerbound")) { - - ASSERT(my_string_empty(argument)); - - } else if (my_string_equal(option,"mate")) { - - ASSERT(!my_string_empty(argument)); - - n = atoi(argument); - ASSERT(n!=0); - - uci->score = mate_score(n); - - } else if (my_string_equal(option,"upperbound")) { - - ASSERT(my_string_empty(argument)); - - } else { - - my_log("POLYGLOT unknown option \"%s\" for command \"%s\"\n",option,command); - } - } - - parse_close(parse); -} - -// mate_score() - -static int mate_score(int dist) { - - ASSERT(dist!=0); - - if (false) { - } else if (dist > 0) { - return +option_get_int("MateScore") - (+dist) * 2 + 1; - } else if (dist < 0) { - return -option_get_int("MateScore") + (-dist) * 2; - } - - return 0; -} - -// end of uci.cpp - diff --git a/uci2uci.cpp b/uci2uci.cpp deleted file mode 100644 index edadeb4..0000000 --- a/uci2uci.cpp +++ /dev/null @@ -1,247 +0,0 @@ -// uci2uci.cpp - -// includes - -#include -#include - -#include "util.h" -#include "board.h" -#include "engine.h" -#include "fen.h" -#include "gui.h" -#include "move.h" -#include "move_do.h" -#include "move_legal.h" -#include "parse.h" -#include "option.h" -#include "book.h" -#include "main.h" -#include "uci.h" - -// constants - -static const int StringSize = 4096; - -// variables - -static board_t UCIboard[1]; -static bool Init=true; -static int SavedMove=MoveNone; - -// prototypes - -static void send_uci_options(); - -// parse_position() - -static void parse_position(const char string[]) { - -/* This is borrowed from Toga II. This code is quite hacky and will be - rewritten using the routines in parse.cpp. -*/ - - const char * fen; - char * moves; - const char * ptr; - char move_string[256]; - int move; - char * string_copy; - - // init - - string_copy=my_strdup(string); - - fen = strstr(string_copy,"fen "); - moves = strstr(string_copy,"moves "); - - // start position - - if (fen != NULL) { // "fen" present - - if (moves != NULL) { // "moves" present - ASSERT(moves>fen); - moves[-1] = '\0'; // dirty, but so is UCI - } - - board_from_fen(UCIboard,fen+4); // CHANGE ME - - } else { - - // HACK: assumes startpos - - board_from_fen(UCIboard,StartFen); - } - - // moves - - if (moves != NULL) { // "moves" present - - ptr = moves + 6; - - while (*ptr != '\0') { - - while (*ptr == ' ') ptr++; - - move_string[0] = *ptr++; - move_string[1] = *ptr++; - move_string[2] = *ptr++; - move_string[3] = *ptr++; - - if (*ptr == '\0' || *ptr == ' ') { - move_string[4] = '\0'; - } else { // promote - move_string[4] = *ptr++; - move_string[5] = '\0'; - } - move = move_from_can(move_string,UCIboard); - - move_do(UCIboard,move); - - } - } - free(string_copy); -} - - -// send_book_move() - -static void send_book_move(int move){ - char move_string[256]; - my_log("POLYGLOT *BOOK MOVE*\n"); - move_to_can(move,UCIboard,move_string,256); - // bogus info lines - gui_send(GUI,"info depth 1 time 0 nodes 0 nps 0 cpuload 0"); - gui_send(GUI,"bestmove %s",move_string); -} - -// format_uci_option_line() - -static void format_uci_option_line(char * option_line,option_t *opt){ - char option_string[StringSize]; - int j; - strcpy(option_line,""); - strcat(option_line,"option name"); - if(opt->mode&PG){ - strcat(option_line," Polyglot"); - } - sprintf(option_string," %s",opt->name); - strcat(option_line,option_string); - sprintf(option_string," type %s",opt->type); - strcat(option_line,option_string); - if(strcmp(opt->type,"button")){ - sprintf(option_string," default %s",opt->default_); - strcat(option_line,option_string); - } - if(!strcmp(opt->type,"spin")){ - sprintf(option_string," min %s",opt->min); - strcat(option_line,option_string); - } - if(!strcmp(opt->type,"spin")){ - sprintf(option_string," max %s",opt->max); - strcat(option_line,option_string); - } - for(j=0;jvar_nb;j++){ - sprintf(option_string," var %s",opt->var[j]); - strcat(option_line,option_string); - } -} - -// send_uci_options() - -static void send_uci_options() { - int i; - option_t *p=Option; - char option_line[StringSize]=""; - gui_send(GUI,"id name %s", Uci->name); - gui_send(GUI,"id author %s", Uci->author); - for(i=0;ioption_nb;i++){ - format_uci_option_line(option_line,Uci->option+i); - gui_send(GUI,"%s",option_line); - } - while(p->name){ - if(p->mode &UCI){ - format_uci_option_line(option_line,p); - gui_send(GUI,"%s",option_line); - } - p++; - } - gui_send(GUI,"uciok"); -} - -// parse_setoption() - - - -static void parse_setoption(const char string[]) { - char *name; - char *pg_name; - char *value; - char * string_copy; - string_copy=my_strdup(string); - if(match(string_copy,"setoption name * value *")){ - name=Star[0]; - value=Star[1]; - if(match(name, "Polyglot *")){ - pg_name=Star[0]; - polyglot_set_option(pg_name,value); - }else{ - engine_send(Engine,"%s",string); - } - }else{ - engine_send(Engine,"%s",string); - } - free(string_copy); -} - - -// uci2uci_gui_step() - -void uci2uci_gui_step(char string[]) { - int move; - if(false){ - }else if(match(string,"uci")){ - send_uci_options(); - return; - }else if(match(string,"setoption *")){ - parse_setoption(string); - return; - }else if(match(string,"position *")){ - parse_position(string); - Init=false; - }else if(match(string,"go *")){ - if(Init){ - board_from_fen(UCIboard,StartFen); - Init=false; - } - SavedMove=MoveNone; - if(!strstr(string,"infinite")){ - move=book_move(UCIboard,option_get_bool("BookRandom")); - if (move != MoveNone && move_is_legal(move,UCIboard)) { - if(strstr(string,"ponder")){ - SavedMove=move; - return; - }else{ - send_book_move(move); - return; - } - } - } - }else if(match(string,"ponderhit") || match(string,"stop")){ - if(SavedMove!=MoveNone){ - send_book_move(SavedMove); - SavedMove=MoveNone; - return; - } - }else if(match(string,"quit")){ - my_log("POLYGLOT *** \"quit\" from GUI ***\n"); - quit(); - } - engine_send(Engine,"%s",string); -} - -void uci2uci_engine_step(char string[]) { - gui_send(GUI,string); -} - -// end of uci2uci.cpp diff --git a/util.cpp b/util.cpp deleted file mode 100644 index a7a733c..0000000 --- a/util.cpp +++ /dev/null @@ -1,392 +0,0 @@ - -// util.cpp - -// includes - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "main.h" -#include "posix.h" -#include "util.h" - -// - -const int ErrorBufferSize=4096; - -// variables - -static bool Error; -static char ErrorBuffer[ErrorBufferSize]; - -FILE * LogFile=NULL; - - -// functions - -// util_init() - -void util_init() { - - Error = false; - - // init log file - - LogFile = NULL; - - // switch file buffering off - - setbuf(stdin,NULL); - setbuf(stdout,NULL); -} - -// my_random_init() - -void my_random_init() { - srand(time(NULL)); -} - -// my_random_int() - -int my_random_int(int n) { - - int r; - - ASSERT(n>0); - - r = int(floor(my_random_double()*double(n))); - ASSERT(r>=0&&r=0.0&&r<1.0); - - return r; -} - -// my_atoll() - -sint64 my_atoll(const char string[]) { - - sint64 n; - - sscanf(string,S64_FORMAT,&n); - - return n; -} - -// my_round() - -int my_round(double x) { - - return int(floor(x+0.5)); -} - -// my_malloc() - -void * my_malloc(size_t size) { - - void * address; - - ASSERT(size>0); - - address = malloc(size); - if (address == NULL) my_fatal("my_malloc(): malloc(): %s\n",strerror(errno)); - - return address; -} - -// my_realloc() - -void * my_realloc(void * address, size_t size) { - - ASSERT(address!=NULL); - ASSERT(size>0); - - address = realloc(address,size); - if (address == NULL) my_fatal("my_realloc(): realloc(): %s\n",strerror(errno)); - - return address; -} - -// my_free() - -void my_free(void * address) { - - ASSERT(address!=NULL); - - free(address); -} - -// my_log_open() - -void my_log_open(const char file_name[]) { - - ASSERT(file_name!=NULL); - - LogFile = fopen(file_name,"a"); -#ifndef _WIN32 -//line buffering doesn't work too well in MSVC and/or windows - if (LogFile != NULL) setvbuf(LogFile,NULL,_IOLBF,0); // line buffering -#endif -} - -// my_log_close() - -void my_log_close() { - - if (LogFile != NULL) fclose(LogFile); - LogFile=NULL; -} - -// my_log() - -void my_log(const char format[], ...) { - - va_list ap; - - ASSERT(format!=NULL); - - if (LogFile != NULL) { - fprintf(LogFile,"%.3f ",now_real()); - va_start(ap,format); - - vfprintf(LogFile,format,ap); - va_end(ap); -#ifdef _WIN32 - fflush(LogFile); -#endif - } -} - -// my_fatal() - -void my_fatal(const char format[], ...) { - - va_list ap; - - ASSERT(format!=NULL); - - va_start(ap,format); - - vfprintf(stderr,format,ap); - if (LogFile != NULL) vfprintf(LogFile,format,ap); - - va_end(ap); - if (Error) { // recursive error - my_log("POLYGLOT *** RECURSIVE ERROR ***\n"); - exit(EXIT_FAILURE); - // abort(); - } else { - Error = true; - quit(); - } -} - -// my_file_read_line() - -bool my_file_read_line(FILE * file, char string[], int size) { - - int src, dst; - int c; - - ASSERT(file!=NULL); - ASSERT(string!=NULL); - ASSERT(size>0); - - if (fgets(string,size,file) == NULL) { - if (feof(file)) { - return false; - } else { // error - my_fatal("my_file_read_line(): fgets(): %s\n",strerror(errno)); - } - } - - // remove CRs and LFs - - src = 0; - dst = 0; - - while ((c=string[src++]) != '\0') { - if (c != '\r' && c != '\n') string[dst++] = c; - } - - string[dst] = '\0'; - - return true; -} - -// my_string_empty() - -bool my_string_empty(const char string[]) { - - return string == NULL || string[0] == '\0'; -} - -// my_string_whitespace() - -bool my_string_whitespace(const char string[]){ - int pos=0; - while(string[pos]!='\0'){ - if(string[pos]!=' ' && string[pos]!='\t'){ - return false; - } - pos++; - } - return true; -} - -// my_string_equal() - -bool my_string_equal(const char string_1[], const char string_2[]) { - - ASSERT(string_1!=NULL); - ASSERT(string_2!=NULL); - - return strcmp(string_1,string_2) == 0; -} - -// my_string_case_equal() - -bool my_string_case_equal(const char string_1[], const char string_2[]) { - - int c1, c2; - - ASSERT(string_1!=NULL); - ASSERT(string_2!=NULL); - - while (true) { - - c1 = *string_1++; - c2 = *string_2++; - - if (tolower(c1) != tolower(c2)) return false; - if (c1 == '\0') return true; - } - - return false; -} - -// my_strdup() - -char * my_strdup(const char string[]) { - - char * address; - - ASSERT(string!=NULL); - - // strdup() is not ANSI C - - address = (char *) my_malloc(strlen(string)+1); - strcpy(address,string); - - return address; -} - -// my_string_clear() - -void my_string_clear(const char * * variable) { - - ASSERT(variable!=NULL); - - if (*variable != NULL) { - my_free((void*)(*variable)); - *variable = NULL; - } -} - -// my_string_set() - -void my_string_set(const char * * variable, const char string[]) { - - ASSERT(variable!=NULL); - ASSERT(string!=NULL); - - if (*variable != NULL) my_free((void*)(*variable)); - *variable = my_strdup(string); -} - -// my_timer_reset() - -void my_timer_reset(my_timer_t * timer) { - - ASSERT(timer!=NULL); - - timer->start_real = 0.0; - timer->elapsed_real = 0.0; - timer->running = false; -} - -// my_timer_start() - -void my_timer_start(my_timer_t * timer) { -// timer->start_real = 0.0; - timer->elapsed_real = 0.0; -// timer->running = false; - ASSERT(timer!=NULL); - - timer->running = true; - timer->start_real = now_real(); -} - -// my_timer_stop() - -void my_timer_stop(my_timer_t * timer) { - - ASSERT(timer!=NULL); - - ASSERT(timer->running); - - timer->elapsed_real += now_real() - timer->start_real; - timer->start_real = 0.0; - timer->running = false; -} - -// my_timer_elapsed_real() - -double my_timer_elapsed_real(const my_timer_t * timer) { - - double elapsed; - - ASSERT(timer!=NULL); - - elapsed = timer->elapsed_real; - if (timer->running) elapsed += now_real() - timer->start_real; - - if (elapsed < 0.0) elapsed = 0.0; - - return elapsed; -} - -// my_timer() - -char * my_error(){ -#ifdef _WIN32 - FormatMessage( - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - GetLastError(), - LANG_USER_DEFAULT, - ErrorBuffer, - ErrorBufferSize, - NULL); - return ErrorBuffer; -#else - return strerror(errno); -#endif -} - diff --git a/xboard2uci.cpp b/xboard2uci.cpp deleted file mode 100644 index 5ad952a..0000000 --- a/xboard2uci.cpp +++ /dev/null @@ -1,1551 +0,0 @@ - -// xboard2uci.cpp - -// includes - -#include -#include -#include -#include -#include - -#include "board.h" -#include "book.h" -#include "colour.h" -#include "engine.h" -#include "fen.h" -#include "game.h" -#include "gui.h" -#include "line.h" -#include "main.h" -#include "move.h" -#include "move_do.h" -#include "move_legal.h" -#include "option.h" -#include "parse.h" -#include "san.h" -#include "uci.h" -#include "uci2uci.h" -#include "util.h" - -// constants - -static const bool UseDebug = false; -static const bool DelayPong = false; - -static const int StringSize = 4096; - -// types - -struct state_t { - int state; - bool computer[ColourNb]; - int exp_move; - int resign_nb; - my_timer_t timer[1]; -}; - -struct xb_t { - bool has_feature_memory; - bool has_feature_smp; - bool has_feature_egt; - bool analyse; - bool computer; - const char * name; - bool ics; - bool new_hack; // "new" is a C++ keyword - bool ponder; - int ping; - bool post; - int proto_ver; - bool result; - - int mps; - double base; - double inc; - - bool time_limit; - double time_max; - - bool depth_limit; - int depth_max; - - double my_time; - double opp_time; -}; - -enum dummy_state_t { WAIT, THINK, PONDER, ANALYSE }; - -// variables - -static state_t State[1]; -static xb_t XB[1]; - -// prototypes - -static void comp_move (int move); -static void move_step (int move); -static void board_update (); - -static void mess (); -static void no_mess (int move); - -static void search_update (); -static void search_clear (); -static void update_remaining_time(); -static int report_best_score(); -static bool kibitz_throttle (bool searching); -static void start_protected_command(); -static void end_protected_command(); - -static bool active (); -static bool ponder (); -static bool ponder_ok (int ponder_move); - -static void stop_search (); - -static void send_board (int extra_move); -static void send_pv (); - -static void send_xboard_options (); - -static void learn (int result); - - -// functions - -// xboard2uci_init() - -void xboard2uci_init() { - // init - - game_clear(Game); - - // state - - State->state = WAIT; - - State->computer[White] = false; - State->computer[Black] = true; - - State->exp_move = MoveNone; - State->resign_nb = 0; - my_timer_reset(State->timer); - - // yes there are engines that do not have the "Hash" option.... - XB->has_feature_memory= uci_option_exist(Uci,"Hash"); - XB->has_feature_smp = uci_thread_option_exist(Uci); - // TODO: support for other types of table bases - XB->has_feature_egt = uci_option_exist(Uci,"NalimovPath"); - XB->analyse = false; - XB->computer = false; - XB->name = NULL; - my_string_set(&XB->name,""); - XB->ics = false; - XB->new_hack = true; - XB->ping = -1; - XB->ponder = false; - XB->post = false; - XB->proto_ver = 1; - XB->result = false; - - XB->mps = 0; - XB->base = 300.0; - XB->inc = 0.0; - - XB->time_limit = false; - XB->time_max = 5.0; - - XB->depth_limit = false; - XB->depth_max = 127; - - XB->my_time = 300.0; - XB->opp_time = 300.0; -} - -// xboard2uci_gui_step() - -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("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(uci_option_exist(Uci,"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")) { - - 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); - 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(Uci); - 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,""); - - 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(Uci); - } else { - ASSERT(XB->ping==-1); - gui_send(GUI,"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 *")) { - - 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 (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 - - gui_send(GUI,"Error (unknown command): %s",string); - - } else if (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{ - start_protected_command(); - engine_send(Engine,"setoption name %s value %s",name,value); - end_protected_command(); - } - } else if (match(string,"option *")){ - char *name=Star[0]; - start_protected_command(); - engine_send(Engine,"setoption name %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 (XB->has_feature_egt && match(string,"egtpath * *")){ - char *type=Star[0]; - char *path=Star[1]; - if(!my_string_case_equal(type,"nalimov")){ - // refuse - gui_send(GUI,"Error (unsupported table base format): %s",string); - }else if(my_string_empty(path)){ - // refuse - gui_send(GUI,"Error (unknown command): %s",string); - }else{ - // 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 (XB->has_feature_memory && match(string,"memory *")){ - int memory = atoi(Star[0]); - int nalimov_cache; - int real_memory; - if(memory>=1){ - // updating the available memory - my_log("POLYGLOT setting the amount of memory to %dMb\n",memory); - if(uci_get_option(Uci,"NalimovCache")>=0){ - nalimov_cache=atoi(Uci->option[uci_get_option(Uci,"NalimovCache")].value); - }else{ - nalimov_cache=0; - } - my_log("POLYGLOT Nalimov Cache is %dMb\n",nalimov_cache); - real_memory=memory-nalimov_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],"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) { - 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; -} - -// xboard2uci_engine_step() - -void xboard2uci_engine_step(char string[]) { - - int event; - event = uci_parse(Uci,string); - - // react to events - - if ((event & EVENT_READY) != 0) { - - // the engine is now ready - - if (!Uci->ready) { - Uci->ready = true; - // if (XB->proto_ver >= 2) xboard_send(XBoard,"feature done=1"); - } - - if (!DelayPong && XB->ping >= 0) { - gui_send(GUI,"pong %d",XB->ping); - XB->ping = -1; - } - } - - if ((event & EVENT_MOVE) != 0 && State->state == THINK) { - - // the engine is playing a move - - // MEGA HACK: estimate remaining time because XBoard won't send it! - - my_timer_stop(State->timer); - - XB->my_time -= my_timer_elapsed_real(State->timer); - XB->my_time += XB->inc; - if (XB->mps != 0 && (game_move_nb(Game) + 1) % XB->mps == 0) XB->my_time += XB->base; - - if (XB->my_time < 0.0) XB->my_time = 0.0; - - // play the engine move - - comp_move(Uci->best_move); - } - - if ((event & EVENT_PV) != 0) { - - // the engine has sent a new PV - - send_pv(); - } - if((event & (EVENT_DRAW|EVENT_RESIGN))!=0){ - my_log("POYGLOT draw offer/resign from engine\n"); - if(uci_option_exist(Uci,"UCI_DrawOffers")){ - if(event & EVENT_DRAW) - gui_send(GUI,"offer draw"); - else - gui_send(GUI,"resign"); - } - } -} - -// format_xboard_option_line - -void format_xboard_option_line(char * option_line, option_t *opt){ - int j; - char option_string[StringSize]; - strcpy(option_line,""); - strcat(option_line,"feature option=\""); - if(opt->mode&PG){ - strcat(option_line,"Polyglot "); - } - sprintf(option_string,"%s",opt->name); - strcat(option_line,option_string); - sprintf(option_string," -%s",opt->type); - strcat(option_line,option_string); - if(strcmp(opt->type,"button") && strcmp(opt->type,"combo")){ - if(strcmp(opt->type,"check")){ - sprintf(option_string," %s",opt->default_); - }else{ - sprintf(option_string," %d", - strcmp(opt->default_,"true")?0:1); - } - strcat(option_line,option_string); - } - if(!strcmp(opt->type,"spin")){ - sprintf(option_string," %s",opt->min); - strcat(option_line,option_string); - } - if(!strcmp(opt->type,"spin")){ - sprintf(option_string," %s",opt->max); - strcat(option_line,option_string); - } - for(j=0;jvar_nb;j++){ - if(!strcmp(opt->var[j],opt->default_)){ - sprintf(option_string," *%s",opt->var[j]); - }else{ - sprintf(option_string," %s",opt->var[j]); - } - strcat(option_line,option_string); - if(j!=opt->var_nb-1){ - strcat(option_line," ///"); - } - } - strcat(option_line,"\""); -} - -// send_xboard_options - -static void send_xboard_options(){ - int i; - char option_line[StringSize]=""; - option_t *p=Option; - const char * name; - XB->proto_ver = atoi(Star[0]); - ASSERT(XB->proto_ver>=2); - - gui_send(GUI,"feature done=0"); - - gui_send(GUI,"feature analyze=1"); - gui_send(GUI,"feature colors=0"); - gui_send(GUI,"feature draw=1"); - gui_send(GUI,"feature ics=1"); - gui_send(GUI,"feature myname=\"%s\"",option_get_string("EngineName")); - gui_send(GUI,"feature name=1"); - gui_send(GUI,"feature pause=0"); - gui_send(GUI,"feature ping=1"); - gui_send(GUI,"feature playother=1"); - gui_send(GUI,"feature reuse=1"); - gui_send(GUI,"feature san=0"); - gui_send(GUI,"feature setboard=1"); - gui_send(GUI,"feature sigint=0"); - gui_send(GUI,"feature sigterm=0"); - gui_send(GUI,"feature time=1"); - gui_send(GUI,"feature usermove=1"); - if (XB->has_feature_memory){ - gui_send(GUI,"feature memory=1"); - }else{ - gui_send(GUI,"feature memory=0"); - } - if (XB->has_feature_smp){ - gui_send(GUI,"feature smp=1"); - }else{ - gui_send(GUI,"feature smp=0"); - } - if (XB->has_feature_egt){ - // TODO: support for other types of table bases - gui_send(GUI,"feature egt=\"nalimov\""); - }else{ - gui_send(GUI,"feature egt=\"\""); - } - - if (uci_option_exist(Uci,"UCI_Chess960")) { - gui_send(GUI,"feature variants=\"normal,fischerandom\""); - } else { - gui_send(GUI,"feature variants=\"normal\""); - } - - for(i=0;ioption_nb;i++){ - if(my_string_case_equal(Uci->option[i].name,"UCI_AnalyseMode")) continue; - if(my_string_case_equal(Uci->option[i].name,"Ponder")) continue; - if(my_string_case_equal(Uci->option[i].name,"Hash")) continue; - if(my_string_case_equal(Uci->option[i].name,"NalimovPath")) continue; - if((name=uci_thread_option(Uci))!=NULL && my_string_case_equal(Uci->option[i].name,name)) continue; - format_xboard_option_line(option_line,Uci->option+i); - - gui_send(GUI,"%s",option_line); - - } - while(p->name){ - if(p->mode &XBOARD){ - format_xboard_option_line(option_line,p); - gui_send(GUI,"%s",option_line); - } - p++; - } - gui_send(GUI,"feature done=1"); - -} - -// report_best_score() - -static int report_best_score(){ - if(!option_get_bool("ScoreWhite") || colour_is_white(Uci->board->turn)){ - return Uci->best_score; - }else{ - return -Uci->best_score; - } -} - -// comp_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("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("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("Resign") && Uci->root_move_nb > 1) { - - if (Uci->best_score <= -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"); - 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); -} - -// move_step() - -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(); -} - -// board_update() - -static void board_update() { - - // handle game end - - ASSERT(!XB->result); - - switch (game_status(Game)) { - case PLAYING: - break; - case WHITE_MATES: - gui_send(GUI,"1-0 {White mates}"); - break; - case BLACK_MATES: - gui_send(GUI,"0-1 {Black mates}"); - break; - case STALEMATE: - gui_send(GUI,"1/2-1/2 {Stalemate}"); - break; - case DRAW_MATERIAL: - gui_send(GUI,"1/2-1/2 {Draw by insufficient material}"); - break; - case DRAW_FIFTY: - gui_send(GUI,"1/2-1/2 {Draw by fifty-move rule}"); - break; - case DRAW_REPETITION: - gui_send(GUI,"1/2-1/2 {Draw by repetition}"); - break; - default: - ASSERT(false); - break; - } -} - -// mess() - -static void mess() { - - // clear state variables - - State->resign_nb = 0; - State->exp_move = MoveNone; - my_timer_reset(State->timer); - - // abort a possible search - - stop_search(); - - // calculate the new state - - if (false) { - } else if (!active()) { - State->state = WAIT; - my_log("POLYGLOT WAIT\n"); - } else if (XB->analyse) { - State->state = ANALYSE; - my_log("POLYGLOT ANALYSE\n"); - } else if (State->computer[game_turn(Game)]) { - State->state = THINK; - my_log("POLYGLOT THINK\n"); - } else { - State->state = WAIT; - my_log("POLYGLOT WAIT\n"); - } - - search_update(); -} - -// no_mess() - -static void no_mess(int move) { - - ASSERT(move_is_ok(move)); - - // just received a move, calculate the new state - - if (false) { - - } else if (!active()) { - - stop_search(); // abort a possible search - - State->state = WAIT; - State->exp_move = MoveNone; - - my_log("POLYGLOT WAIT\n"); - - } else if (State->state == WAIT) { - - ASSERT(State->computer[game_turn(Game)]); - ASSERT(!State->computer[colour_opp(game_turn(Game))]); - ASSERT(!XB->analyse); - - my_log("POLYGLOT WAIT -> THINK\n"); - - State->state = THINK; - State->exp_move = MoveNone; - - } else if (State->state == THINK) { - - ASSERT(!State->computer[game_turn(Game)]); - ASSERT(State->computer[colour_opp(game_turn(Game))]); - ASSERT(!XB->analyse); - - if (ponder() && ponder_ok(Uci->ponder_move)) { - - my_log("POLYGLOT THINK -> PONDER\n"); - - State->state = PONDER; - State->exp_move = Uci->ponder_move; - - } else { - - my_log("POLYGLOT THINK -> WAIT\n"); - - State->state = WAIT; - State->exp_move = MoveNone; - } - - } else if (State->state == PONDER) { - - ASSERT(State->computer[game_turn(Game)]); - ASSERT(!State->computer[colour_opp(game_turn(Game))]); - ASSERT(!XB->analyse); - - if (move == State->exp_move && Uci->searching) { - - ASSERT(Uci->searching); - ASSERT(Uci->pending_nb>=1); - - my_timer_start(State->timer);//also resets - - my_log("POLYGLOT PONDER -> THINK (*** HIT ***)\n"); - engine_send(Engine,"ponderhit"); - - State->state = THINK; - State->exp_move = MoveNone; - - send_pv(); // update display - - return; // do not launch a new search - - } else { - - my_log("POLYGLOT PONDER -> THINK (miss)\n"); - - stop_search(); - - State->state = THINK; - State->exp_move = MoveNone; - } - - } else if (State->state == ANALYSE) { - - ASSERT(XB->analyse); - - my_log("POLYGLOT ANALYSE -> ANALYSE\n"); - - stop_search(); - - } else { - - ASSERT(false); - } - - search_update(); -} - -// start_protected_command() - -static void start_protected_command(){ - stop_search(); -} - -static void end_protected_command(){ - if(Uci->ready){ // not init faze - uci_send_isready_sync(Uci); // gobble up spurious "bestmove" - } - update_remaining_time(); - search_update(); // relaunch search if necessary -} - -// update_remaining_time() - -static void update_remaining_time(){ - double reduce; - if(State->timer->running){ - my_timer_stop(State->timer); - reduce = my_timer_elapsed_real(State->timer); - my_log("POLYGLOT reducing remaing time by %f seconds\n",reduce); - XB->my_time -= reduce; - if(XB->my_time<0.0){ - XB->my_time=0.0; - } - } -} - - -// search_update() - -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++; - } -} - -// search_clear() - -static void search_clear() { - - uci_clear(Uci); - - // TODO: MOVE ME - - my_timer_start(State->timer);//also resets -} - -// active() - -static bool active() { - - // position state - - if (game_status(Game) != PLAYING) return false; // game ended - - // xboard state - - if (XB->analyse) return true; // analysing - if (!State->computer[White] && !State->computer[Black]) return false; // force mode - if (XB->new_hack || XB->result) return false; // unstarted or ended game - - return true; // playing -} - -// ponder() - -static bool ponder() { - - return XB->ponder && (option_get_bool("CanPonder") || uci_option_exist(Uci,"Ponder")); -} -// ponder_ok() - -static bool ponder_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; -} - -// stop_search() - -static void stop_search() { - - if (Uci->searching) { - - ASSERT(Uci->searching); - ASSERT(Uci->pending_nb>=1); - - my_log("POLYGLOT STOP SEARCH\n"); - -/* - engine_send(Engine,"stop"); - Uci->searching = false; -*/ - - if (option_get_bool("SyncStop")) { - uci_send_stop_sync(Uci); - } else { - uci_send_stop(Uci); - } - } -} - -// send_board() - -static void send_board(int extra_move) { - - char fen[256]; - int start, end; - board_t board[1]; - int pos; - int move; - char string[256]; - - ASSERT(extra_move==MoveNone||move_is_ok(extra_move)); - - ASSERT(!Uci->searching); - - // init - - game_get_board(Game,Uci->board); - if (extra_move != MoveNone) move_do(Uci->board,extra_move); - - board_to_fen(Uci->board,fen,256); - my_log("POLYGLOT FEN %s\n",fen); - - ASSERT(board_can_play(Uci->board)); - - // more init - - start = 0; - end = game_pos(Game); - ASSERT(end>=start); - - // position - - game_get_board(Game,board,start); - board_to_fen(board,string,256); - - engine_send_queue(Engine,"position"); - - if (my_string_equal(string,StartFen)) { - engine_send_queue(Engine," startpos"); - } else { - engine_send_queue(Engine," fen %s",string); - } - - // move list - - if (end > start || extra_move != MoveNone) engine_send_queue(Engine," moves"); - - for (pos = start; pos < end; pos++) { // game moves - - move = game_move(Game,pos); - - move_to_can(move,board,string,256); - engine_send_queue(Engine," %s",string); - - move_do(board,move); - } - - if (extra_move != MoveNone) { // move to ponder on - move_to_can(extra_move,board,string,256); - engine_send_queue(Engine," %s",string); - } - - // end - - engine_send(Engine,""); // newline -} - -// send_pv() - -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); - - if(Uci->depth==-1) //hack to clear the engine output window - gui_send(GUI,"%d %+d %.0f "S64_FORMAT" ",0,report_best_score(),Uci->time*100.0,Uci->node_nb); - - gui_send(GUI,"%d %+d %.0f "S64_FORMAT" %s",Uci->best_depth,report_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); - gui_send(GUI,"%d %+d %.0f "S64_FORMAT" (%s) %s",Uci->best_depth,report_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); - if(kibitz_throttle(Uci->searching)){ - gui_send(GUI,"%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(report_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); - if(kibitz_throttle(Uci->searching)){ - gui_send(GUI,"%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(report_best_score())/100.0,move_string,pv_string); - } - } - } - } -} - -// kibitz_throttle() - -static bool kibitz_throttle(bool searching){ - time_t curr_time; - static time_t lastKibitzMove=0; - static time_t lastKibitzPV=0; - curr_time = time(NULL); - if(searching){ // KibitzPV - if(curr_time >= (option_get_int("KibitzInterval") + lastKibitzPV)){ - lastKibitzPV=curr_time; - return true; - } - }else{ // KibitzMove - if(curr_time >= (option_get_int("KibitzInterval") + lastKibitzMove)){ - lastKibitzPV=curr_time; - lastKibitzMove=curr_time; - return true; - } - } - return false; -} - -// learn() - -static void learn(int result) { - - int pos; - board_t board[1]; - int move; - - ASSERT(result>=-1&&result<=+1); - - ASSERT(XB->result); - ASSERT(State->computer[White]||State->computer[Black]); - - // init - - pos = 0; - - if (false) { - } else if (State->computer[White]) { - pos = 0; - } else if (State->computer[Black]) { - pos = 1; - result = -result; - } else { - my_fatal("learn(): unknown side\n"); - } - - if (false) { - } else if (result > 0) { - my_log("POLYGLOT *LEARN WIN*\n"); - } else if (result < 0) { - my_log("POLYGLOT *LEARN LOSS*\n"); - } else { - my_log("POLYGLOT *LEARN DRAW*\n"); - } - - // loop - - for (; pos < Game->size; pos += 2) { - - game_get_board(Game,board,pos); - move = game_move(Game,pos); - - book_learn_move(board,move,result); - } - - book_flush(); -} - -// end of adapter.cpp