return proce_cui( ptree );
}
+#ifdef XBOARD
+#define IF(X) else if(!strcmp(command, X))
+
+int myTime, hisTime, movesPerSession, inc, plyNr;
+char xboard_mode;
+
+static void
+SetTimes(void)
+{ // set white and black times from own and opponent time.
+ int moves;
+ if(movesPerSession <= 0) moves = 35; else {
+ moves = - plyNr/2;
+ while(moves <= 0) moves += movesPerSession;
+ }
+ time_limit = (myTime-inc-30)/(moves+2) + inc;
+ time_max_limit = 3*time_limit;
+ if(time_max_limit > myTime - 30)time_max_limit = myTime - 30; // keep 0.3 sec margin, as Bonanza reads the clock infrequently
+ time_limit *= 10; // msec
+ time_max_limit *= 10;
+Out("# moves=%d, time=%d inc=%d t=%d, max=%d\n", moves, myTime, inc, time_limit, time_max_limit);
+}
+
+static int
+proce_xboard(char *line, const char *command, tree_t * restrict ptree)
+{ // [HGM] added to make Bonanza.exe a native WinBoard engine
+ int value = -100000;
+ static char forceMode = 0;
+ sscanf(line + strlen(command) + 1, "%d", &value);
+Out("# command = '%s'\n", line);
+ if(0) ;
+ IF("protover") { Out("feature variants=\"shogi\" usermove=1 myname=\"Bonanza " BNZ_VER
+ "\" memory=1 smp=1 debug=1 colors=0 setboard=1 ping=1 done=1\n"); }
+ IF("new") { forceMode = plyNr = 0; SetTimes(); return 0; }
+ IF("easy") { strcpy(line, "ponder off"); return 0; }
+ IF("hard") { strcpy(line, "ponder on"); return 0; }
+ IF("post") { ; }
+ IF("nopost") { ; }
+ IF("time") { sscanf(line+5, "%d", &myTime); }
+ IF("otim") { sscanf(line+5, "%d", &hisTime); }
+ IF("force") { forceMode = 1; }
+ IF("go") { forceMode = 0; SetTimes(); plyNr++; strcpy(line, "move"); return 0; }
+ IF("memory") { ; }
+ IF("cores") { sprintf(line, "tlp num %d", value); return 0; }
+ IF("sd") { sprintf(line, "limit depth %d", value); return 0; }
+ IF("st") { ; }
+ IF("quit") { return 0; }
+ IF("analyze") { ; }
+ IF("exit") { ; }
+ IF("variant") { /* ignore, since it must be Shogi */; }
+ IF("setboard") { ; }
+ IF("option") { ; }
+ IF("level") { int min, sec; float fsec=0.;
+ if(sscanf(line+6, "%d %d:%d %f", &movesPerSession, &min, &sec, &fsec) != 4)
+ sscanf(line+6, "%d %d %f", &movesPerSession, &min, &fsec);
+ min = 60*min + sec; myTime = hisTime = 100*min; inc = 100 * fsec;
+ }
+ IF("usermove") { char fromX=line[9], fromY=line[10], toX=line[11], toY=line[12], promo=line[13];
+ int from;
+{int i,j;for(i=0;i<81;i+=9){printf("# ");for(j=0;j<9;j++)printf(" %3d", BOARD[i+j]);printf("\n");}}
+ if(forceMode) strcpy(line, "move "), line += 5; else plyNr++, SetTimes();
+ if(fromY == '@') { // drop
+ if(fromX >= 'a') fromX += 'A' - 'a';
+ switch(fromX) { // encode piece
+ case 'P': fromX = pawn; break;
+ case 'L': fromX = lance; break;
+ case 'N': fromX = knight; break;
+ case 'S': fromX = silver; break;
+ case 'G': fromX = gold; break;
+ case 'B': fromX = bishop; break;
+ case 'R': fromX = rook; break;
+ }
+ sprintf(line, "00%c%c%s", 'a'+'9'-toX, '1'+'9'-toY, astr_table_piece[(int)fromX]);
+ } else {
+ from = ('9' - fromY)*9 + (fromX - 'a');
+Out("# from=%d\n",from);
+ sprintf(line, "%c%c%c%c%s", 'a'+'9'-fromX, '1'+'9'-fromY, 'a'+'9'-toX, '1'+'9'-toY,
+ astr_table_piece[abs(BOARD[from]) + (promo == '+' ? promote : 0)]);
+ }
+ plyNr++; return 0;
+ }
+ IF("undo") { ; }
+ IF("remove") { ; }
+ IF("ping") { Out("pong %d\n", value); }
+ return 1;
+}
+#endif
static int CONV proce_cui( tree_t * restrict ptree )
{
token = strtok_r( str_cmdline, str_delimiters, &last );
if ( token == NULL || *token == '#' ) { return 1; }
+#ifdef XBOARD
+ {
+ if(xboard_mode) {
+ if( proce_xboard(str_cmdline, token, ptree) ) return 1; // command already processed
+ Out("# translated command '%s'\n", str_cmdline); // command translated for processing by Bonanza
+ token = strtok_r( str_cmdline, str_delimiters, &last ); // redo parsing
+ } else
+ if ( ! strcmp( token, "xboard" ) ) { xboard_mode = 1; game_status |= flag_noprompt; return 1; }
+ }
+#endif
if ( is_move( token ) ) { return cmd_usrmove( ptree, token, &last ); }
if ( ! strcmp( token, "s" ) ) { return cmd_move_now(); }
if ( ! strcmp( token, "beep" ) ) { return cmd_beep( &last); }
game_status &= ~flag_pondering;
game_status |= flag_thinking;
+#ifdef XBOARD
+ if(!xboard_mode)
+#endif
set_search_limit_time( root_turn );
OutCsaShogi( "info ponder end\n" );
static int CONV next_root_move( tree_t * restrict ptree, int turn );
#endif
+#ifdef XBOARD
+extern char xboard_mode;
+#endif
+
static int CONV
search_wrapper( tree_t * restrict ptree, int alpha, int beta, int turn,
int depth, int ply, unsigned int state_node )
if ( ptree->pv[0].length )
{
+#ifdef XBOARD
+ if(xboard_mode) Out("%2d %6d %6d %8d ", iteration_depth, value, time/10, 1); else
+#endif
if ( root_move_list[root_index].status & flag_first )
{
Out( " %2d %6s %7.2f ", iteration_depth, str, dvalue );
for ( ply = 1; ply <= ptree->pv[0].length; ply++ )
{
+#ifdef XBOARD
+ if(xboard_mode && is_out) { // print PV move in WB format
+ int move = ptree->pv[0].a[ply], from = I2From(move), to = I2To(move);
+ char inPromoZone = tt > 0 ? from >= 6*9 || to >= 6*9 : to < 3*9|| from < 3*9;
+ if(from >= nsquare)
+ Out(" %c@%c%c", "PLNSGBR"[From2Drop(from)-1], 'a'+to%9, '9'-to/9);
+ else
+ Out(" %c%c%c%c%s", 'a'+from%9, '9'-from/9, 'a'+to%9, '9'-to/9,
+ inPromoZone ? I2IsPromote(move) ? "+" : "=" : "");
+ } else
+#endif
if ( is_out )
{
if ( ply > 1 && ! ( (ply-1) % 5 ) )
for ( i = 1; i < ply; i++ )
if ( ptree->pv[0].a[i] == ptree->pv[0].a[ply] ) { goto rep_esc; }
+#ifdef XBOARD
+ if(xboard_mode && is_out) { // print PV move in WB format
+ int move = ptree->pv[0].a[ply], from = I2From(move), to = I2To(move);
+ char inPromoZone = tt > 0 ? from >= 6*9 || to >= 6*9 : to < 3*9|| from < 3*9;
+ if(from >= nsquare)
+ Out(" %c@%c%c", "PLNSGBR"[From2Drop(from)-1], 'a'+to%9, '9'-to/9);
+ else
+ Out(" %c%c%c%c%s", 'a'+from%9, '9'-from/9, 'a'+to%9, '9'-to/9,
+ inPromoZone ? I2IsPromote(move) ? "+" : "=" : "");
+ } else
+#endif
if ( is_out )
{
if ( ply > 1 && ! ( (ply-1) % 5 ) )
root_index = i;
#if ! ( defined(NO_STDOUT) && defined(NO_LOGGING) )
+#ifdef XBOARD
+ if(!xboard_mode)
+#endif
if ( iteration_depth > 5 )
{
const char *str_move;
}
OutCsaShogi( "info tt %03u:%02u\n", sec_total / 60U, sec_total % 60U );
+#ifdef XBOARD
+ { extern char xboard_mode;
+ if(xboard_mode) { // print move in WB format and defuse next line
+ if(str_move[0] < '0' || str_move[0] > '9') Out("\n%s\n# ", str_move); // only resign?
+ else if(str_move[0] == '0')
+ Out("\nmove %c@%c%c\n# ", // drop
+ "PLNSGBR"[(move>>7&127)-nsquare],
+ '9'+'a'-str_move[2], '1'+'9'-str_move[3]);
+ else Out("\n#t=%d tm=%d\nmove %c%c%c%c%s\n# ", time_limit, time_max_limit,
+ '9'+'a'-str_move[0], '1'+'9'-str_move[1],
+ '9'+'a'-str_move[2], '1'+'9'-str_move[3], (move & FLAG_PROMO ? "+" : "="));
+ }
+ }
+#endif
Out( "%s '(%d%s) %03u:%02u/%03u:%02u elapsed: b%u, w%u\n",
str_move, value,
( last_pv.type == pv_fail_high ) ? "!" : "",