X-Git-Url: http://winboard.nl/cgi-bin?p=bonanza.git;a=blobdiff_plain;f=proce.c;h=81707f9b4a67a397251c1e79d72ee43800feb9e5;hp=bb4187719cc342d2e34a0ba7e0aa3bc11b0a170b;hb=cygwin;hpb=18b507e1b20fc6c32ee50f00fb910a59110c1a1d diff --git a/proce.c b/proce.c index bb41877..81707f9 100644 --- a/proce.c +++ b/proce.c @@ -21,78 +21,316 @@ #if defined(MINIMUM) # define CmdBook(x,y) cmd_book(y); -static int cmd_book( char **lasts ); +static int CONV cmd_book( char **lasts ); #else # define CmdBook(x,y) cmd_book(x,y); -static int cmd_learn( tree_t * restrict ptree, char **lasts ); -static int cmd_book( tree_t * restrict ptree, char **lasts ); +static int CONV cmd_learn( tree_t * restrict ptree, char **lasts ); +static int CONV cmd_book( tree_t * restrict ptree, char **lasts ); #endif #if ! defined(NO_STDOUT) -static int cmd_stress( char **lasts ); -#endif - -#if defined(DEKUNOBOU) -static int cmd_dek( char **lasts ); +static int CONV cmd_stress( char **lasts ); #endif #if defined(CSA_LAN) -static int proce_csalan( tree_t * restrict ptree ); -static int cmd_connect( tree_t * restrict ptree, char **lasts ); +static int CONV proce_csalan( tree_t * restrict ptree ); +static int CONV cmd_connect( tree_t * restrict ptree, char **lasts ); +static int CONV cmd_sendpv( char **lasts ); #endif #if defined(MNJ_LAN) -static int proce_mnj( tree_t * restrict ptree ); -static int cmd_mnj( tree_t * restrict ptree, char **lasts ); -static int cmd_mnjmove( tree_t * restrict ptree, char **lasts, int is_alter ); +static int CONV proce_mnj( tree_t * restrict ptree ); +static int CONV cmd_mnjignore( tree_t *restrict ptree, char **lasts ); +static int CONV cmd_mnj( char **lasts ); +static int CONV cmd_mnjmove( tree_t * restrict ptree, char **lasts, + int num_alter ); +#endif + +#if defined(USI) +static int CONV proce_usi( tree_t * restrict ptree ); +static int CONV usi_posi( tree_t * restrict ptree, char **lasts ); +static int CONV usi_go( tree_t * restrict ptree, char **lasts ); +static int CONV usi_ignore( tree_t * restrict ptree, char **lasts ); #endif #if defined(TLP) -static int cmd_thread( char **lasts ); +static int CONV cmd_thread( char **lasts ); #endif #if defined(MPV) -static int cmd_mpv( char **lasts ); +static int CONV cmd_mpv( tree_t * restrict ptree, char **lasts ); #endif -static int proce_cui( tree_t * restrict ptree ); -static int cmd_usrmove( tree_t * restrict ptree, const char *str_move, - char **last ); -static int cmd_move_now( void ); -static int cmd_ponder( char **lasts ); -static int cmd_limit( char **lasts ); -static int cmd_quit( void ); -static int cmd_beep( char **lasts ); -static int cmd_peek( char **lasts ); -static int cmd_hash( char **lasts ); -static int cmd_ping( void ); -static int cmd_suspend( void ); -static int cmd_problem( tree_t * restrict ptree, char **lasts ); -static int cmd_display( tree_t * restrict ptree, char **lasts ); -static int cmd_move( tree_t * restrict ptree, char **lasts ); -static int cmd_new( tree_t * restrict ptree, char **lasts ); -static int cmd_read( tree_t * restrict ptree, char **lasts ); -static int cmd_resign( tree_t * restrict ptree, char **lasts ); -static int cmd_time( char **lasts ); -static int is_move( const char *str ); +#if defined(DFPN) +static int CONV cmd_dfpn( tree_t * restrict ptree, char **lasts ); +#endif +#if defined(DFPN_CLIENT) +static int CONV cmd_dfpn_client( tree_t * restrict ptree, char **lasts ); +#endif -int +static int CONV proce_cui( tree_t * restrict ptree ); +static int CONV cmd_usrmove( tree_t * restrict ptree, const char *str_move, + char **last ); +static int CONV cmd_outmove( tree_t * restrict ptree ); +static int CONV cmd_move_now( void ); +static int CONV cmd_ponder( char **lasts ); +static int CONV cmd_limit( char **lasts ); +static int CONV cmd_quit( void ); +static int CONV cmd_beep( char **lasts ); +static int CONV cmd_peek( char **lasts ); +static int CONV cmd_stdout( char **lasts ); +static int CONV cmd_newlog( char **lasts ); +static int CONV cmd_hash( char **lasts ); +static int CONV cmd_ping( void ); +static int CONV cmd_suspend( void ); +static int CONV cmd_problem( tree_t * restrict ptree, char **lasts ); +static int CONV cmd_display( tree_t * restrict ptree, char **lasts ); +static int CONV cmd_move( tree_t * restrict ptree, char **lasts ); +static int CONV cmd_new( tree_t * restrict ptree, char **lasts ); +static int CONV cmd_read( tree_t * restrict ptree, char **lasts ); +static int CONV cmd_resign( tree_t * restrict ptree, char **lasts ); +static int CONV cmd_undo( tree_t * restrict ptree ); // [HGM] undo +static int CONV cmd_time( char **lasts ); +static int CONV cmd_undo( tree_t * restrict ptree ); // [HGM] undo +static int CONV cmd_analyze( tree_t * restrict ptree ); // [HGM] analyze +static int CONV cmd_inex( tree_t * restrict ptree, int inex, char **last ); // [HGM] exclude +static int CONV cmd_exit( void ); + + +int CONV is_move( const char *str ) +{ + if ( isdigit( (int)str[0] ) && isdigit( (int)str[1] ) + && isdigit( (int)str[2] ) && isdigit( (int)str[3] ) + && isupper( (int)str[4] ) && isupper( (int)str[5] ) + && str[6] == '\0' ) { return 1; } + + return 0; +} + + +int CONV procedure( tree_t * restrict ptree ) { #if defined(CSA_LAN) if ( sckt_csa != SCKT_NULL ) { return proce_csalan( ptree ); } #endif + #if defined(MNJ_LAN) if ( sckt_mnj != SCKT_NULL ) { return proce_mnj( ptree ); } #endif +#if defined(USI) + if ( usi_mode != usi_off ) { return proce_usi( ptree ); } +#endif + return proce_cui( ptree ); } +char *start_pos, start_data[512]; // [HGM] undo: for remembering start position +int move_list[1024], move_ptr; +char analyze_mode; +int all_moves[MAX_LEGAL_MOVES]; + +#ifdef XBOARD +#define IF(X) else if(!strcmp(command, X)) + +int myTime, hisTime, movesPerSession, inc, plyNr; +char xboard_mode; +int root_pos[nsquare]; + +int +bonanza_piece( char p ) +{ + int piece = 0; + if(p >= 'a') p += 'A' - 'a'; + switch(p) { // encode piece + case 'P': piece = pawn; break; + case 'L': piece = lance; break; + case 'N': piece = knight; break; + case 'S': piece = silver; break; + case 'G': piece = gold; break; + case 'B': piece = bishop; break; + case 'R': piece = rook; break; + case 'K': piece = king; break; + } + return piece; +} + +void +read_fen( char *p ) +{ + static char fen[128]; + int r, f, gote = 1; + char *q = fen, *start = p; + strncpy( fen, p+9 , 127); + strcpy( p, "new SU" ); p += 6; + for ( r = 1; r <= 9; r++) { + for ( f = 0; *q; q++ ) { + int promoted = 0; + if( *q == '+' ) promoted = promote, q++; + if( isdigit( *q ) ) f += atoi( q ); else + if( isalpha( *q ) ) { + int piece = bonanza_piece( *q ); + if( ( *q >= 'a' && *q <= 'z' ) != gote ) { + gote = !gote; // switch color + *p++ = ( gote ? '-' : '+' ); + } + sprintf( p, "%d%d%s", 9-f, r, astr_table_piece[piece + promoted] ); + p += 4; f++; + } else { q++; break; } + } + } + while( q[-1] == ' ' ) q++; + if( q[-1] == '[' ) { // holdings + while( isalpha( *q ) ) { + int piece = bonanza_piece( *q ); + if( ( *q >= 'a' && *q <= 'z' ) != gote ) { + gote = !gote; // switch color + *p++ = ( gote ? '-' : '+' ); + } + sprintf( p, "00%s", astr_table_piece[piece] ); + p += 4; q++; + } + if( *q == '-' ) q++; + if( *q == ']' ) q++; + while( *q == ' ' ) q++; + } else q--; + sprintf(p, " %c", *q == 'w' ? '+' : '-' ); // side to move +} + +void +xboard_to_CSA( tree_t * restrict ptree, char *in, char *out ) +{ + char fromX=in[0], fromY=in[1], toX=in[2], toY=in[3], promo=in[4]; + int piece=0; + if(fromY == '@') { // drop (contains all info needed to convert it) + piece = bonanza_piece( fromX ); + sprintf(out, "00%c%c%s", 'a'+'9'-toX, '1'+'9'-toY, astr_table_piece[piece]); + } else { // board move (need to figure out moved piece) + int from = ('9' - fromY)*9 + (fromX - 'a'); + int flag = (promo == '+' ? FLAG_PROMO : 0); + piece = abs( BOARD[from] ); // this only works when no search in progress! +printf("# piece from board: %d\n", piece);fflush(stdout); + if( game_status & flag_thinking ) { + int i, to = ('9' - toY)*9 + (toX - 'a'); + piece = 0; // kludge to force illegal CSA move + for( i = 0; i < root_nmove; i++ ) { // determine the piece from the move list + int move = root_move_list[i].move; + if( I2To(move) != to ) continue; + if( I2From(move) != from ) continue; + if( (move & FLAG_PROMO) != flag ) continue; + piece = I2PieceMove( move ); // we found the move; take the piece from it + break; + } + } else if( game_status & ( flag_pondering | flag_puzzling ) ) piece = abs( root_pos[from] ); // we have valid copy! +printf("# piece corrected to %d\n", piece);fflush(stdout); + if( promo == '+') piece += promote; + sprintf(out, "%c%c%c%c%s", 'a'+'9'-fromX, '1'+'9'-fromY, 'a'+'9'-toX, '1'+'9'-toY, astr_table_piece[piece]); + } +} + +static void +update_exclude_list( tree_t * restrict ptree, int add, unsigned int move ) +{ // [HGM] exclude: manage list of excluded moves + int i; + if( moves_ignore[0] == MOVE_NA ) { // nothing is excluded yet; make a copy of root move list; + for( i = 0; i < root_nmove; i++) all_moves[i] = root_move_list[i].move; + all_moves[i] = MOVE_NA; + } + if ( move == MOVE_NA ) { // all moves + if( add ) { // copy entire list of legal moves + for( i = 0; i < root_nmove; i++ ) moves_ignore[i] = all_moves[i]; + } else moves_ignore[0] = MOVE_NA; // clear list + } else { // single move + for( i = 0; moves_ignore[i] != MOVE_NA; i++ ) if( move == moves_ignore[i] ) break; + if( add ) { // we must add the move + if( moves_ignore[i] != MOVE_NA ) return; // but it was already in list + if( i >= MAX_LEGAL_MOVES - 2 ) return; // overflow + moves_ignore[i] = move; moves_ignore[i+1] = MOVE_NA; // append move + } else { // we must delete the move + if( moves_ignore[i] == MOVE_NA ) return; // but it was not there + while( (moves_ignore[i] = moves_ignore[i+1]) ) i++; // squeeze it out + } + } +} + +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_cui( tree_t * restrict ptree ) +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") { +#if defined(MPV) + Out("feature option=\"MultiPV -spin 1 1 100\"\n"); + Out("feature option=\"centi-Pawn margin -spin 200 0 25000\"\n"); +#endif + Out("feature variants=\"shogi\" usermove=1 myname=\"Bonanza " BNZ_VER + "\" memory=1 smp=1 debug=1 colors=0 setboard=1 ping=1 sigint=0 exclude=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") { sprintf(line, "hash %d", value); return 0; } + 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") { return 0; } + IF("exit") { return 0; } + IF("variant") { /* ignore, since it must be Shogi */; } + IF("setboard") { forceMode = 1; plyNr = 0; read_fen( line ); return 0; } + IF("option") { + if(sscanf(line+7, "MultiPV=%d", &value) == 1) { sprintf(line, "mpv num %d", value); return 0; } + if(sscanf(line+7, "centi-Pawn margin=%d", &value) == 1) { sprintf(line, "mpv width %d", value); return 0; } + } + 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 buf[20]; + xboard_to_CSA( ptree, line+9, buf ); + if(forceMode || analyze_mode) strcpy(line, "move "), line += 5; else plyNr++, SetTimes(); + strcpy( line, buf ); + plyNr++; + return 0; + } + IF("undo") { return 0; } + IF("remove") { ; } + IF("ping") { Out("pong %d\n", value); } + IF("exclude") { xboard_to_CSA( ptree, line+8, line+8 ); line[7] = ' '; return 0; } + IF("include") { xboard_to_CSA( ptree, line+8, line+8 ); line[7] = ' '; return 0; } + return 1; +} +#endif + +static int CONV proce_cui( tree_t * restrict ptree ) { const char *token; char *last; @@ -100,6 +338,26 @@ 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 ( ! strcmp( token, "analyze" ) ) { return cmd_analyze( ptree ); } // [HGM] analyze + if ( ! strcmp( token, "exit" ) ) { return cmd_exit(); } // [HGM] analyze + if ( ! strcmp( token, "move" ) ) { return cmd_move( ptree, &last ); } + if ( ! strcmp( token, "undo" ) ) { return cmd_undo( ptree ); } // [HGM] undo + if ( ! strcmp( token, "include" ) ) { return cmd_inex( ptree , 0, &last); } // [HGM] exclude + if ( ! strcmp( token, "exclude" ) ) { return cmd_inex( ptree , 1, &last); } // [HGM] exclude +#if defined(MPV) + if ( ! strcmp( token, "mpv" ) ) { return cmd_mpv( ptree, &last ); } +#endif + analyze_mode = 0; // [HGM] analyze: all other commands terminate analysis 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); } @@ -107,9 +365,10 @@ proce_cui( tree_t * restrict ptree ) if ( ! strcmp( token, "display" ) ) { return cmd_display( ptree, &last ); } if ( ! strcmp( token, "hash" ) ) { return cmd_hash( &last ); } if ( ! strcmp( token, "limit" ) ) { return cmd_limit( &last ); } - if ( ! strcmp( token, "move" ) ) { return cmd_move( ptree, &last ); } if ( ! strcmp( token, "new" ) ) { return cmd_new( ptree, &last ); } + if ( ! strcmp( token, "outmove" ) ) { return cmd_outmove( ptree ); } if ( ! strcmp( token, "peek" ) ) { return cmd_peek( &last ); } + if ( ! strcmp( token, "stdout" ) ) { return cmd_stdout( &last ); } if ( ! strcmp( token, "ping" ) ) { return cmd_ping(); } if ( ! strcmp( token, "ponder" ) ) { return cmd_ponder( &last ); } if ( ! strcmp( token, "problem" ) ) { return cmd_problem( ptree, &last ); } @@ -118,17 +377,20 @@ proce_cui( tree_t * restrict ptree ) if ( ! strcmp( token, "resign" ) ) { return cmd_resign( ptree, &last ); } if ( ! strcmp( token, "suspend" ) ) { return cmd_suspend(); } if ( ! strcmp( token, "time" ) ) { return cmd_time( &last ); } + if ( ! strcmp( token, "newlog" ) ) { return cmd_newlog( &last ); } #if defined(CSA_LAN) if ( ! strcmp( token, "connect" ) ) { return cmd_connect( ptree, &last ); } + if ( ! strcmp( token, "sendpv" ) ) { return cmd_sendpv( &last ); } #endif #if defined(MNJ_LAN) - if ( ! strcmp( token, "mnj" ) ) { return cmd_mnj( ptree, &last ); } + if ( ! strcmp( token, "mnj" ) ) { return cmd_mnj( &last ); } #endif -#if defined(DEKUNOBOU) - if ( ! strcmp( token, "dekunobou" ) ) { return cmd_dek( &last ); } +#if defined(DFPN) + if ( ! strcmp( token, "dfpn" ) ) { return cmd_dfpn( ptree, &last ); } #endif -#if defined(MPV) - if ( ! strcmp( token, "mpv" ) ) { return cmd_mpv( &last ); } +#if defined(DFPN_CLIENT) + if ( ! strcmp( token, "dfpn_client")) { return cmd_dfpn_client( ptree, + &last ); } #endif #if defined(TLP) if ( ! strcmp( token, "tlp" ) ) { return cmd_thread( &last ); } @@ -146,8 +408,7 @@ proce_cui( tree_t * restrict ptree ) #if defined(CSA_LAN) -static int -proce_csalan( tree_t * restrict ptree ) +static int CONV proce_csalan( tree_t * restrict ptree ) { const char *token; char *last; @@ -193,8 +454,11 @@ proce_csalan( tree_t * restrict ptree ) game_status |= flag_suspend; return 2; } - - ShutdownClient; + + if ( sckt_out( sckt_csa, "LOGOUT\n" ) < 0 ) { return -1; } + if ( sckt_recv_all( sckt_csa ) < 0 ) { return -1; } + + ShutdownAll(); if ( client_ngame == client_max_game ) { return cmd_quit(); } @@ -207,8 +471,7 @@ proce_csalan( tree_t * restrict ptree ) #if defined(MNJ_LAN) -static int -proce_mnj( tree_t * restrict ptree ) +static int CONV proce_mnj( tree_t * restrict ptree ) { const char *token; char *last; @@ -226,10 +489,31 @@ proce_mnj( tree_t * restrict ptree ) iret = cmd_new( ptree, &last ); if ( iret < 0 ) { return iret; } + moves_ignore[0] = MOVE_NA; return analyze( ptree ); } - if ( ! strcmp( token, "idle" ) ) { return cmd_suspend(); } - if ( ! strcmp( token, "alter" ) ) { return cmd_mnjmove( ptree, &last, 1 ); } + if ( ! strcmp( token, "ignore" ) ) { return cmd_mnjignore( ptree, &last ); } + if ( ! strcmp( token, "idle" ) ) { return cmd_suspend(); } + if ( ! strcmp( token, "alter" ) ) { return cmd_mnjmove( ptree, &last, 1 ); } + if ( ! strcmp( token, "retract" ) ) + { + long l; + char *ptr; + const char *str = strtok_r( NULL, str_delimiters, &last ); + if ( str == NULL ) + { + str_error = str_bad_cmdline; + return -1; + } + l = strtol( str, &ptr, 0 ); + if ( ptr == str || (long)NUM_UNMAKE < l ) + { + str_error = str_bad_cmdline; + return -1; + } + + return cmd_mnjmove( ptree, &last, (int)l ); + } if ( ! strcmp( token, "move" ) ) { return cmd_mnjmove( ptree, &last, 0 ); } str_error = str_bad_cmdline; @@ -237,8 +521,54 @@ proce_mnj( tree_t * restrict ptree ) } -static int -cmd_mnjmove( tree_t * restrict ptree, char **lasts, int is_alter ) +static int CONV +cmd_mnjignore( tree_t *restrict ptree, char **lasts ) +{ + const char *token; + char *ptr; + int i; + unsigned int move; + long lid; + + + token = strtok_r( NULL, str_delimiters, lasts ); + if ( token == NULL ) + { + str_error = str_bad_cmdline; + return -1; + } + lid = strtol( token, &ptr, 0 ); + if ( ptr == token || lid == LONG_MAX || lid < 1 ) + { + str_error = str_bad_cmdline; + return -1; + } + + AbortDifficultCommand; + + for ( i = 0; ; i += 1 ) + { + token = strtok_r( NULL, str_delimiters, lasts ); + if ( token == NULL ) { break; } + + if ( interpret_CSA_move( ptree, &move, token ) < 0 ) { return -1; } + + moves_ignore[i] = move; + } + if ( i == 0 ) + { + str_error = str_bad_cmdline; + return -1; + } + mnj_posi_id = (int)lid; + moves_ignore[i] = MOVE_NA; + + return analyze( ptree ); +} + + +static int CONV +cmd_mnjmove( tree_t * restrict ptree, char **lasts, int num_alter ) { const char *str1 = strtok_r( NULL, str_delimiters, lasts ); const char *str2 = strtok_r( NULL, str_delimiters, lasts ); @@ -262,7 +592,13 @@ cmd_mnjmove( tree_t * restrict ptree, char **lasts, int is_alter ) AbortDifficultCommand; - if ( is_alter ) { unmake_move_root( ptree, mnj_move_last ); }; + while ( num_alter ) + { + iret = unmake_move_root( ptree ); + if ( iret < 0 ) { return iret; } + + num_alter -= 1; + } iret = interpret_CSA_move( ptree, &move, str1 ); if ( iret < 0 ) { return iret; } @@ -270,12 +606,10 @@ cmd_mnjmove( tree_t * restrict ptree, char **lasts, int is_alter ) iret = get_elapsed( &time_turn_start ); if ( iret < 0 ) { return iret; } - mnj_posi_id = (int)lid; - mnj_move_last = move; + mnj_posi_id = (int)lid; - iret = make_move_root( ptree, move, ( flag_history | flag_time | flag_rep - | flag_detect_hang - | flag_rejections ) ); + iret = make_move_root( ptree, move, ( flag_time | flag_rep + | flag_detect_hang ) ); if ( iret < 0 ) { return iret; } # if ! defined(NO_STDOUT) @@ -283,25 +617,313 @@ cmd_mnjmove( tree_t * restrict ptree, char **lasts, int is_alter ) if ( iret < 0 ) { return iret; } # endif + moves_ignore[0] = MOVE_NA; return analyze( ptree ); } #endif -static int -is_move( const char *str ) +static int CONV +do_analyze( tree_t * restrict ptree ) +{ // [HGM] analyze: do a ponder search on the current position + int iret; + if ( get_elapsed( &time_start ) < 0 ) { return -1; } + time_limit = time_max_limit = 1e9; // kludge: use huge time to mimic infinity +#ifdef XBOARD + if(xboard_mode) Out("1 0 0 0 New Search\n"); // make sure lower depth is emitted, so XBoard undestand new search started + for( iret = 0; iret < nsquare; iret++ ) root_pos[iret] = BOARD[iret]; +#endif + game_status |= flag_pondering; + iret = iterate( ptree ); + game_status &= ~flag_pondering; + return iret; +} + + +static int CONV +cmd_undo( tree_t * restrict ptree ) +{ // [HGM] undo: restart the game, and feed all moves except the last + int i, last = move_ptr; + char *p = start_data; + if( move_ptr <= 0 ) { + str_error = "undo past start of game ignored"; + return -2; + } + + AbortDifficultCommand; + + last--; + cmd_new( ptree, &p ); + for(i=0; i UINT_MAX || l < 1 ) + { + str_error = str_bad_cmdline; + return -1; + } + + usi_byoyomi = (unsigned int)l; + depth_limit = PLY_MAX; + node_limit = UINT64_MAX; + sec_limit_depth = UINT_MAX; + } + else { + str_error = str_bad_cmdline; + return -1; + } + + + if ( get_elapsed( &time_turn_start ) < 0 ) { return -1; } + + iret = com_turn_start( ptree, 0 ); + if ( iret < 0 ) { + if ( str_error == str_no_legal_move ) { USIOut( "bestmove resign\n" ); } + else { return -1; } + } + + return 1; +} + + +static int CONV +usi_posi( tree_t * restrict ptree, char **lasts ) +{ + const char *token; + char str_buf[7]; + unsigned int move; + + AbortDifficultCommand; + + moves_ignore[0] = MOVE_NA; + + token = strtok_r( NULL, str_delimiters, lasts ); + if ( strcmp( token, "startpos" ) ) + { + str_error = str_bad_cmdline; + return -1; + } + + if ( ini_game( ptree, &min_posi_no_handicap, + flag_history, NULL, NULL ) < 0 ) { return -1; } + + token = strtok_r( NULL, str_delimiters, lasts ); + if ( token == NULL ) { return 1; } + + if ( strcmp( token, "moves" ) ) + { + str_error = str_bad_cmdline; + return -1; + } + + for ( ;; ) { + + token = strtok_r( NULL, str_delimiters, lasts ); + if ( token == NULL ) { break; } + + if ( usi2csa( ptree, token, str_buf ) < 0 ) { return -1; } + if ( interpret_CSA_move( ptree, &move, str_buf ) < 0 ) { return -1; } + if ( make_move_root( ptree, move, ( flag_history | flag_time + | flag_rep + | flag_detect_hang ) ) < 0 ) + { + return -1; + } + } + + if ( get_elapsed( &time_turn_start ) < 0 ) { return -1; } + return 1; +} + +#endif + + +static int CONV cmd_move_now( void ) { if ( game_status & flag_thinking ) { game_status |= flag_move_now; } @@ -309,7 +931,7 @@ cmd_move_now( void ) } -static int +static int CONV cmd_usrmove( tree_t * restrict ptree, const char *str_move, char **lasts ) { const char *str; @@ -364,10 +986,6 @@ cmd_usrmove( tree_t * restrict ptree, const char *str_move, char **lasts ) if ( sckt_csa != SCKT_NULL ) { AbortDifficultCommand; } #endif -#if defined(DEKUNOBOU) - if ( dek_ngame ) { AbortDifficultCommand; } -#endif - #if defined(CSASHOGI) AbortDifficultCommand; #else @@ -384,24 +1002,20 @@ cmd_usrmove( tree_t * restrict ptree, const char *str_move, char **lasts ) return 2; } else { - iret = renovate_time( Flip(root_turn) ); + iret = update_time( Flip(root_turn) ); if ( iret < 0 ) { return iret; } if ( lelapsed ) { adjust_time( (unsigned int)lelapsed, Flip(root_turn) ); } - history_book_learn[ record_game.moves ].move_played = ponder_move; - history_book_learn[ record_game.moves ].hand_played - = ptree->rep_hand_list[ root_nrep-1 ]; - history_book_learn[ record_game.moves ].key_played - = (unsigned int)ptree->rep_board_list[ root_nrep-1 ]; - out_CSA( ptree, &record_game, ponder_move ); game_status &= ~flag_pondering; game_status |= flag_thinking; - n_nobook_move += 1; +#ifdef XBOARD + if(!xboard_mode) +#endif set_search_limit_time( root_turn ); OutCsaShogi( "info ponder end\n" ); @@ -417,7 +1031,6 @@ cmd_usrmove( tree_t * restrict ptree, const char *str_move, char **lasts ) if ( iret < 0 ) { return iret; } move_evasion_pchk = 0; iret = make_move_root( ptree, move, ( flag_rep | flag_history | flag_time - | flag_rejections | flag_detect_hang ) ); if ( iret < 0 ) { @@ -436,18 +1049,6 @@ cmd_usrmove( tree_t * restrict ptree, const char *str_move, char **lasts ) } #endif -#if defined(DEKUNOBOU) - if ( dek_ngame ) - { - if ( move_evasion_pchk ) - { - dek_win += 1; - OutDek( "%%TORYO\n" ); - } - return cmd_suspend(); - } -#endif - if ( move_evasion_pchk ) { str = str_CSA_move( move_evasion_pchk ); @@ -476,10 +1077,6 @@ cmd_usrmove( tree_t * restrict ptree, const char *str_move, char **lasts ) } #endif -#if defined(DEKUNOBOU) - if ( dek_ngame && ( game_status & flag_drawn ) ) { OutDek( "%%TORYO\n" ); } -#endif - if ( ! ( game_status & mask_game_end ) ) { iret = com_turn_start( ptree, 0 ); @@ -490,8 +1087,7 @@ cmd_usrmove( tree_t * restrict ptree, const char *str_move, char **lasts ) } -static int -cmd_beep( char **lasts ) +static int CONV cmd_beep( char **lasts ) { const char *str = strtok_r( NULL, str_delimiters, lasts ); if ( str == NULL ) @@ -511,8 +1107,7 @@ cmd_beep( char **lasts ) } -static int -cmd_peek( char **lasts ) +static int CONV cmd_peek( char **lasts ) { const char *str = strtok_r( NULL, str_delimiters, lasts ); @@ -533,8 +1128,49 @@ cmd_peek( char **lasts ) } -static int -cmd_ponder( char **lasts ) +static int CONV cmd_stdout( char **lasts ) +{ + const char *str = strtok_r( NULL, str_delimiters, lasts ); + + if ( str == NULL ) + { + str_error = str_bad_cmdline; + return -2; + } + + if ( ! strcmp( str, str_on ) ) { game_status &= ~flag_nostdout; } + else if ( ! strcmp( str, str_off ) ) { game_status |= flag_nostdout; } + else { + str_error = str_bad_cmdline; + return -2; + } + + return 1; +} + + +static int CONV cmd_newlog( char **lasts ) +{ + const char *str = strtok_r( NULL, str_delimiters, lasts ); + + if ( str == NULL ) + { + str_error = str_bad_cmdline; + return -2; + } + + if ( ! strcmp( str, str_on ) ) { game_status &= ~flag_nonewlog; } + else if ( ! strcmp( str, str_off ) ) { game_status |= flag_nonewlog; } + else { + str_error = str_bad_cmdline; + return -2; + } + + return 1; +} + + +static int CONV cmd_ponder( char **lasts ) { const char *str = strtok_r( NULL, str_delimiters, lasts ); @@ -544,7 +1180,7 @@ cmd_ponder( char **lasts ) return -2; } - if ( ! strcmp( str, str_on ) ) { game_status &= ~flag_noponder; } + if ( ! strcmp( str, str_on ) ) { game_status &= ~flag_noponder; } else if ( ! strcmp( str, str_off ) ) { if ( game_status & ( flag_pondering | flag_puzzling ) ) @@ -563,8 +1199,7 @@ cmd_ponder( char **lasts ) #if ! defined(NO_STDOUT) -static int -cmd_stress( char **lasts ) +static int CONV cmd_stress( char **lasts ) { const char *str = strtok_r( NULL, str_delimiters, lasts ); @@ -586,7 +1221,7 @@ cmd_stress( char **lasts ) #endif -static int +static int CONV #if defined(MINIMUM) cmd_book( char **lasts ) #else @@ -629,8 +1264,7 @@ cmd_book( tree_t * restrict ptree, char **lasts ) } -static int -cmd_display( tree_t * restrict ptree, char **lasts ) +static int CONV cmd_display( tree_t * restrict ptree, char **lasts ) { const char *str = strtok_r( NULL, str_delimiters, lasts ); char *ptr; @@ -666,8 +1300,7 @@ cmd_display( tree_t * restrict ptree, char **lasts ) } -static int -cmd_ping( void ) +static int CONV cmd_ping( void ) { OutCsaShogi( "pong\n" ); Out( "pong\n" ); @@ -675,8 +1308,7 @@ cmd_ping( void ) } -static int -cmd_hash( char **lasts ) +static int CONV cmd_hash( char **lasts ) { const char *str = strtok_r( NULL, str_delimiters, lasts ); char *ptr; @@ -688,29 +1320,6 @@ cmd_hash( char **lasts ) return -2; } - if ( ! strcmp( str, "learn" ) ) - { - str = strtok_r( NULL, str_delimiters, lasts ); - if ( str != NULL && ! strcmp( str, str_on ) ) - { - return hash_learn_on(); - } - else if ( str != NULL && ! strcmp( str, str_off ) ) - { - return hash_learn_off(); - } -#if ! defined(MINIMUM) - else if ( str != NULL && ! strcmp( str, "create" ) ) - { - return hash_learn_create(); - } -#endif - else { - str_error = str_bad_cmdline; - return -2; - } - } - l = strtol( str, &ptr, 0 ); if ( ptr == str || l == LONG_MAX || l < 1 || l > 31 ) { @@ -726,8 +1335,7 @@ cmd_hash( char **lasts ) } -static int -cmd_limit( char **lasts ) +static int CONV cmd_limit( char **lasts ) { const char *str = strtok_r( NULL, str_delimiters, lasts ); char *ptr; @@ -845,7 +1453,7 @@ cmd_limit( char **lasts ) } -static int +static int CONV cmd_read( tree_t * restrict ptree, char **lasts ) { const char *str1 = strtok_r( NULL, str_delimiters, lasts ); @@ -859,7 +1467,7 @@ cmd_read( tree_t * restrict ptree, char **lasts ) long l; int iret, flag, c; - flag = flag_history | flag_rep | flag_detect_hang | flag_rejections; + flag = flag_history | flag_rep | flag_detect_hang; moves = UINT_MAX; str_tmp = NULL; @@ -900,7 +1508,7 @@ cmd_read( tree_t * restrict ptree, char **lasts ) strncpy( str_file, "game.csa", SIZE_FILENAME-1 ); #else snprintf( str_file, SIZE_FILENAME, "%s/game%03d.csa", - str_dir_logs, irecord_game ); + str_dir_logs, record_num ); #endif pf_dest = file_open( str_tmp, "w" ); if ( pf_dest == NULL ) { return -2; } @@ -944,8 +1552,7 @@ cmd_read( tree_t * restrict ptree, char **lasts ) } -static int -cmd_resign( tree_t * restrict ptree, char **lasts ) +static int CONV cmd_resign( tree_t * restrict ptree, char **lasts ) { const char *str = strtok_r( NULL, str_delimiters, lasts ); char *ptr; @@ -957,16 +1564,8 @@ cmd_resign( tree_t * restrict ptree, char **lasts ) if ( game_status & mask_game_end ) { return 1; } -#if defined(DEKUNOBOU) - if ( dek_ngame && record_game.moves < 2 ) - { - str_error = "ignore resignation"; - return -2; - } -#endif - game_status |= flag_resigned; - renovate_time( root_turn ); + update_time( root_turn ); out_CSA( ptree, &record_game, MOVE_RESIGN ); } else { @@ -983,12 +1582,13 @@ cmd_resign( tree_t * restrict ptree, char **lasts ) } -static int -cmd_move( tree_t * restrict ptree, char **lasts ) +static int CONV cmd_move( tree_t * restrict ptree, char **lasts ) { const char *str = strtok_r( NULL, str_delimiters, lasts ); + char *ptr; + long l; unsigned int move; - int iret; + int iret, i; if ( game_status & mask_game_end ) { @@ -1000,57 +1600,65 @@ cmd_move( tree_t * restrict ptree, char **lasts ) if ( str == NULL ) { + if ( analyze_mode ) // [HGM] analyze: in analysis mode we cannot set the engine thinking (but perhaps play PV move?) + { + str_error = str_bad_cmdline; + return -2; + } + iret = get_elapsed( &time_turn_start ); if ( iret < 0 ) { return iret; } - iret = com_turn_start( ptree, 0 ); - if ( iret < 0 ) { return iret; } + return com_turn_start( ptree, 0 ); } - else if ( ! strcmp( str, "restraint" ) ) + + l = strtol( str, &ptr, 0 ); + if ( str != ptr && l != LONG_MAX && l >= 1 && *ptr == '\0' ) { - iret = get_elapsed( &time_turn_start ); - if ( iret < 0 ) { return iret; } - - iret = com_turn_start( ptree, flag_refer_rest ); - if ( iret < 0 ) { return iret; } + if ( analyze_mode ) // [HGM] analyze: in analysis mode we cannot set the engine thinking + { + str_error = str_bad_cmdline; + return -2; + } + + for ( i = 0; i < l; i += 1 ) + { + if ( game_status & ( flag_move_now | mask_game_end ) ) { break; } + + iret = get_elapsed( &time_turn_start ); + if ( iret < 0 ) { return iret; } + + iret = com_turn_start( ptree, 0 ); + if ( iret < 0 ) { return iret; } + } + + return 1; } - else { + do { iret = interpret_CSA_move( ptree, &move, str ); if ( iret < 0 ) { return iret; } iret = get_elapsed( &time_turn_start ); if ( iret < 0 ) { return iret; } -#if defined(MNJ_LAN) - if ( sckt_mnj != SCKT_NULL ) - { - const char *str2 = strtok_r( NULL, str_delimiters, lasts ); - char *ptr; - long l; - if ( str2 ) { l = strtol( str2, &ptr, 0 ); } - if ( ! str2 || ptr == str || l == LONG_MAX || l < 1 ) - { - str_error = str_bad_cmdline; - return -2; - } - mnj_posi_id = (int)l; - mnj_move_last = move; - } -#endif - - iret = make_move_root( ptree, move, ( flag_history | flag_time | flag_rep - | flag_detect_hang - | flag_rejections ) ); + iret = make_move_root( ptree, move, + ( flag_history | flag_time | flag_rep + | flag_detect_hang ) ); if ( iret < 0 ) { return iret; } - } + + str = strtok_r( NULL, str_delimiters, lasts ); + + } while ( str != NULL ); + + moves_ignore[0] = MOVE_NA; // [HGM] exclude: exclude list cleared for new position + if ( analyze_mode ) return do_analyze ( ptree ); // [HGM] analyze: analysis should continue after feeding moves return 1; } -static int -cmd_new( tree_t * restrict ptree, char **lasts ) +static int CONV cmd_new( tree_t * restrict ptree, char **lasts ) { const char *str1 = strtok_r( NULL, str_delimiters, lasts ); const char *str2 = strtok_r( NULL, str_delimiters, lasts ); @@ -1060,8 +1668,12 @@ cmd_new( tree_t * restrict ptree, char **lasts ) AbortDifficultCommand; + start_pos = *lasts; move_ptr = 0; // [HGM] undo: remember start position + moves_ignore[0] = MOVE_NA; // [HGM] exclude: exclude list cleared for new position + if ( str1 != NULL ) { + strncpy(start_data, str1, 511); // [HGM] undo: remember start position memset( &min_posi.asquare, empty, nsquare ); min_posi.hand_black = min_posi.hand_white = 0; iret = read_board_rep1( str1, &min_posi ); @@ -1089,14 +1701,77 @@ cmd_new( tree_t * restrict ptree, char **lasts ) } -static int -cmd_problem( tree_t * restrict ptree, char **lasts ) +static int CONV cmd_outmove( tree_t * restrict ptree ) +{ + const char *str_move; + char buffer[256]; + unsigned int move_list[ MAX_LEGAL_MOVES ]; + int i, c, n; + + AbortDifficultCommand; + + if ( game_status & mask_game_end ) + { + Out( "NO LEGAL MOVE\n" ); + DFPNOut( "NO LEGAL MOVE\n" ); + return 1; + } + + n = gen_legal_moves( ptree, move_list, 0 ); + + buffer[0]='\0'; + for ( c = i = 0; i < n; i += 1 ) + { + str_move = str_CSA_move(move_list[i]); + + if ( i && ( i % 10 ) == 0 ) + { + Out( "%s\n", buffer ); + DFPNOut( "%s ", buffer ); + memcpy( buffer, str_move, 6 ); + c = 6; + } + else if ( i ) + { + buffer[c] = ' '; + memcpy( buffer + c + 1, str_move, 6 ); + c += 7; + } + else { + memcpy( buffer + c, str_move, 6 ); + c += 6; + } + buffer[c] = '\0'; + } + Out( "%s\n", buffer ); + DFPNOut( "%s\n", buffer ); + + return 1; +} + + +static int CONV cmd_problem( tree_t * restrict ptree, char **lasts ) { const char *str = strtok_r( NULL, str_delimiters, lasts ); char *ptr; long l; unsigned int nposition; int iret; +#if defined(DFPN) + int is_mate; +#endif + + AbortDifficultCommand; + + +#if defined(DFPN) + is_mate = 0; + if ( str != NULL && ! strcmp( str, "mate" ) ) + { + is_mate = 1; + str = strtok_r( NULL, str_delimiters, lasts ); + } +#endif if ( str != NULL ) { @@ -1110,12 +1785,17 @@ cmd_problem( tree_t * restrict ptree, char **lasts ) } else { nposition = UINT_MAX; } - AbortDifficultCommand; - + iret = record_open( &record_problems, "problem.csa", mode_read, NULL, NULL ); if ( iret < 0 ) { return iret; } +#if defined(DFPN) + iret = is_mate ? solve_mate_problems( ptree, nposition ) + : solve_problems( ptree, nposition ); +#else iret = solve_problems( ptree, nposition ); +#endif + if ( iret < 0 ) { record_close( &record_problems ); @@ -1125,23 +1805,18 @@ cmd_problem( tree_t * restrict ptree, char **lasts ) iret = record_close( &record_problems ); if ( iret < 0 ) { return iret; } - iret = ini_game( ptree, &min_posi_no_handicap, flag_history, NULL, NULL ); - if ( iret < 0 ) { return iret; } - return get_elapsed( &time_turn_start ); } -static int -cmd_quit( void ) +static int CONV cmd_quit( void ) { game_status |= flag_quit; return 1; } -static int -cmd_suspend( void ) +static int CONV cmd_suspend( void ) { if ( game_status & ( flag_pondering | flag_puzzling ) ) { @@ -1154,8 +1829,7 @@ cmd_suspend( void ) } -static int -cmd_time( char **lasts ) +static int CONV cmd_time( char **lasts ) { const char *str = strtok_r( NULL, str_delimiters, lasts ); char *ptr; @@ -1229,8 +1903,7 @@ cmd_time( char **lasts ) #if !defined(MINIMUM) /* learn (ini|no-ini) steps games iterations tlp1 tlp2 */ -static int -cmd_learn( tree_t * restrict ptree, char **lasts ) +static int CONV cmd_learn( tree_t * restrict ptree, char **lasts ) { const char *str1 = strtok_r( NULL, str_delimiters, lasts ); const char *str2 = strtok_r( NULL, str_delimiters, lasts ); @@ -1343,8 +2016,7 @@ cmd_learn( tree_t * restrict ptree, char **lasts ) #if defined(MPV) -static int -cmd_mpv( char **lasts ) +static int CONV cmd_mpv( tree_t * restrict ptree, char **lasts ) { const char *str = strtok_r( NULL, str_delimiters, lasts ); char *ptr; @@ -1374,6 +2046,8 @@ cmd_mpv( char **lasts ) mpv_num = (int)l; + if ( analyze_mode ) return do_analyze ( ptree ); // [HGM] analyze: analysis should continue changing num + return 1; } else if ( ! strcmp( str, "width" ) ) @@ -1395,6 +2069,92 @@ cmd_mpv( char **lasts ) mpv_width = (int)l; + if ( analyze_mode ) return do_analyze ( ptree ); // [HGM] analyze: analysis should continue after changing width + + return 1; + } + + str_error = str_bad_cmdline; + return -2; +} +#endif + + +#if defined(DFPN) +static int CONV cmd_dfpn( tree_t * restrict ptree, char **lasts ) +{ + const char *str = strtok_r( NULL, str_delimiters, lasts ); + + if ( str == NULL ) + { + str_error = str_bad_cmdline; + return -2; + } + else if ( ! strcmp( str, "hash" ) ) + { + char *ptr; + long l; + + str = strtok_r( NULL, str_delimiters, lasts ); + if ( str == NULL ) + { + str_error = str_bad_cmdline; + return -2; + } + l = strtol( str, &ptr, 0 ); + if ( ptr == str || l == LONG_MAX || l < 1 ) + { + str_error = str_bad_cmdline; + return -2; + } + + AbortDifficultCommand; + + dfpn_hash_log2 = (unsigned int)l; + return dfpn_ini_hash(); + } + else if ( ! strcmp( str, "go" ) ) + { + AbortDifficultCommand; + + return dfpn( ptree, root_turn, 1 ); + } + else if ( ! strcmp( str, "connect" ) ) + { + char str_addr[256]; + char str_id[256]; + char *ptr; + long l; + int port; + + str = strtok_r( NULL, str_delimiters, lasts ); + if ( ! str || ! strcmp( str, "." ) ) { str = "127.0.0.1"; } + strncpy( str_addr, str, 255 ); + str_addr[255] = '\0'; + + str = strtok_r( NULL, str_delimiters, lasts ); + if ( ! str || ! strcmp( str, "." ) ) { str = "4083"; } + l = strtol( str, &ptr, 0 ); + if ( ptr == str || l == LONG_MAX || l < 0 || l > USHRT_MAX ) + { + str_error = str_bad_cmdline; + return -2; + } + port = (int)l; + + str = strtok_r( NULL, str_delimiters, lasts ); + if ( ! str || ! strcmp( str, "." ) ) { str = "bonanza1"; } + strncpy( str_id, str, 255 ); + str_id[255] = '\0'; + + AbortDifficultCommand; + + dfpn_sckt = sckt_connect( str_addr, port ); + if ( dfpn_sckt == SCKT_NULL ) { return -2; } + + str_buffer_cmdline[0] = '\0'; + DFPNOut( "Worker: %s\n", str_id ); + return 1; } @@ -1405,8 +2165,7 @@ cmd_mpv( char **lasts ) #if defined(TLP) -static int -cmd_thread( char **lasts ) +static int CONV cmd_thread( char **lasts ) { const char *str = strtok_r( NULL, str_delimiters, lasts ); @@ -1450,9 +2209,48 @@ cmd_thread( char **lasts ) #endif +#if defined(DFPN_CLIENT) +static int CONV cmd_dfpn_client( tree_t * restrict ptree, char **lasts ) +{ + const char *str; + char *ptr; + int iret; + + AbortDifficultCommand; + + str = strtok_r( NULL, str_delimiters, lasts ); + if ( ! str || ! strcmp( str, "." ) ) { str = "127.0.0.1"; } + strncpy( dfpn_client_str_addr, str, 255 ); + dfpn_client_str_addr[255] = '\0'; + + str = strtok_r( NULL, str_delimiters, lasts ); + if ( ! str || ! strcmp( str, "." ) ) { str = "4083"; } + dfpn_client_port = strtol( str, &ptr, 0 ); + if ( ptr == str || dfpn_client_port == LONG_MAX || dfpn_client_port < 0 + || dfpn_client_port > USHRT_MAX ) + { + str_error = str_bad_cmdline; + return -2; + } + + Out( "DFPN Server: %s %d\n", dfpn_client_str_addr, dfpn_client_port ); + + iret = ini_game( ptree, &min_posi_no_handicap, flag_history, NULL, NULL ); + if ( iret < 0 ) { return iret; } + + if ( dfpn_client_sckt == SCKT_NULL ) + { + str_error = "Check network status."; + return -1; + } + + return get_elapsed( &time_turn_start ); +} +#endif + + #if defined(CSA_LAN) -static int -cmd_connect( tree_t * restrict ptree, char **lasts ) +static int CONV cmd_connect( tree_t * restrict ptree, char **lasts ) { const char *str; char *ptr; @@ -1501,21 +2299,42 @@ cmd_connect( tree_t * restrict ptree, char **lasts ) return client_next_game( ptree, client_str_addr, (int)client_port ); } + + +static int CONV cmd_sendpv( char **lasts ) +{ + const char *str = strtok_r( NULL, str_delimiters, lasts ); + + if ( str == NULL ) + { + str_error = str_bad_cmdline; + return -2; + } + + if ( ! strcmp( str, str_off ) ) { game_status &= ~flag_sendpv; } + else if ( ! strcmp( str, str_on ) ) { game_status |= flag_sendpv; } + else { + str_error = str_bad_cmdline; + return -2; + } + + return 1; +} #endif #if defined(MNJ_LAN) -static int -cmd_mnj( tree_t * restrict ptree, char **lasts ) +/* mnj sd seed addr port name factor stable_depth */ +static int CONV cmd_mnj( char **lasts ) { char client_str_addr[256]; char client_str_id[256]; const char *str; char *ptr; unsigned int seed; - int sd; long l; - int client_port; + int client_port, sd; + double factor; str = strtok_r( NULL, str_delimiters, lasts ); if ( ! str ) @@ -1569,6 +2388,28 @@ cmd_mnj( tree_t * restrict ptree, char **lasts ) strncpy( client_str_id, str, 255 ); client_str_id[255] = '\0'; + str = strtok_r( NULL, str_delimiters, lasts ); + if ( ! str || ! strcmp( str, "." ) ) { str = "1.0"; } + factor = strtod( str, &ptr ); + if ( ptr == str || factor < 0.0 ) + { + str_error = str_bad_cmdline; + return -2; + } + + str = strtok_r( NULL, str_delimiters, lasts ); + if ( ! str || ! strcmp( str, "." ) ) { l = -1; } + else { + l = strtol( str, &ptr, 0 ); + if ( ptr == str || l == LONG_MAX ) + { + str_error = str_bad_cmdline; + return -2; + } + } + if ( l <= 0 ) { mnj_depth_stable = INT_MAX; } + else { mnj_depth_stable = (int)l; } + AbortDifficultCommand; resign_threshold = 65535; @@ -1581,74 +2422,11 @@ cmd_mnj( tree_t * restrict ptree, char **lasts ) str_buffer_cmdline[0] = '\0'; Out( "Sending my name %s", client_str_id ); - sckt_out( sckt_mnj, "%s\n", client_str_id ); + MnjOut( "%s %g final%s\n", client_str_id, factor, + ( mnj_depth_stable == INT_MAX ) ? "" : " stable" ); - return analyze( ptree ); + return cmd_suspend(); } #endif -#if defined(DEKUNOBOU) - -static int -cmd_dek( char **lasts ) -{ - const char *str = strtok_r( NULL, str_delimiters, lasts ); - char *ptr; - long l1, l2; - int iret; - - if ( str == NULL ) - { - str_error = str_bad_cmdline; - return -2; - } - strncpy( str_message, str, SIZE_MESSAGE-1 ); - str_message[SIZE_MESSAGE-1] = '\0'; - dek_ul_addr = inet_addr( str ); - - str = strtok_r( NULL, str_delimiters, lasts ); - if ( str == NULL ) - { - str_error = str_bad_cmdline; - return -2; - } - l1 = strtol( str, &ptr, 0 ); - if ( ptr == str || l1 == LONG_MAX || l1 < 0 || l1 > USHRT_MAX ) - { - str_error = str_bad_cmdline; - return -2; - } - - str = strtok_r( NULL, str_delimiters, lasts ); - if ( str == NULL ) - { - str_error = str_bad_cmdline; - return -2; - } - l2 = strtol( str, &ptr, 0 ); - if ( ptr == str || l2 == LONG_MAX || l2 < 0 || l2 > USHRT_MAX ) - { - str_error = str_bad_cmdline; - return -2; - } - - AbortDifficultCommand; - - iret = dek_start( str_message, (int)l1, (int)l2 ); - if ( iret < 0 ) { return iret; } - - Out( "\n- in communication with Dekunobou...\n" ); - - str_buffer_cmdline[0] = '\0'; - dek_ngame = 1; - dek_lost = 0; - dek_win = 0; - dek_turn = 1; - game_status |= flag_resigned; - - return 1; -} - -#endif -