static void uci_set_position(char *str) { char *c=str, *m; char movestr[10]; move_t move; undo_info_t u[1]; while(isspace(*c)) c++; if(strncasecmp(c, "startpos", 8)==0) { c+=8; while(isspace(*c)) c++; set_position(RootPosition, STARTPOS); } else set_position(RootPosition, c);/*if(strncasecmp(c, "fen", 3)==0) { c+=3; while(isspace(*c)) c++; set_position(RootPosition, (unsigned char*)c); while(*c != '\0' && strncasecmp(c, "moves", 5) != 0) c++; }*/ while(isspace(*c)) c++; if(strncasecmp(c, "moves", 5)==0) { c+=5; while(isspace(*c)) c++; while(*c!='\0') { m=movestr; while(*c!='\0' && !isspace(*c)) *m++ = *c++; *m = '\0'; move = parse_move(RootPosition, movestr); if(move) make_move(RootPosition, move, u); else printf("Illegal move: %s\n", movestr); while(isspace(*c)) c++; } } }
moveseq cubepos::parse_moveseq(const char*&p){ moveseq r; int mv; while((mv= parse_move(p))>=0) r.push_back(mv); return r; }
int read_movelines (char txt[128], int verbose) { char *movement = strtok(txt, " "); struct move move; int x=0; //movement = strtok(NULL, " "); while ( movement != NULL) { if (parse_move(&move, movement, 1-machineplays)) { Vb printf("moving from input: %i%i %i%i\n",move.from[0],move.from[1],move.to[0],move.to[1]); move.casualty = board.squares[move.to[0]][move.to[1]]; move_pc(&board, &move); history_append(&move); x++; } movement = strtok(NULL, " "); } Vb printf("%i moves read.\n",x); return x; }
bool Protocol::play_move(std::string move) { // Parse move Move m = parse_move(move); // Test legality if (!game.is_legal(m)) { return false; } // Play move game.make_move(m); // Put move to history history.push(m); return true; }
int parse_pgn(Board *board, const char *pgn) { board_reset(board); char *temp = calloc(strlen(pgn) + 1, sizeof(char)); strcpy(temp, pgn); char *key; char *token = tokenize(temp, " ", &key); while (token) { Move move; if (parse_move(board, token, &move)) { make_move(board, &move); } else { return 0; } token = tokenize(NULL, " ", &key); } free(temp); return 1; }
static void uci_parse_searchmoves(char *str, move_t moves[]) { char *c, movestr[10]; int i; move_t *move = moves; c = str; while(isspace(*c)) c++; while(*c != '\0') { i = 0; while(*c != '\0' && !isspace(*c) && i < 9) movestr[i++] = *c++; if(i >= 4 && 'a' <= movestr[0] && movestr[0] <= 'h' && '1' <= movestr[1] && movestr[1] <= '8' && 'a' <= movestr[2] && movestr[2] <= 'h' && '1' <= movestr[3] && movestr[3] <= '8') *move++ = parse_move(RootPosition, movestr); else break; while(isspace(*c)) c++; } *move = 0; }
GTPResponse HavannahGTP::play(const string & pos, int toplay){ if(toplay != game.toplay()) return GTPResponse(false, "It is the other player's turn!"); if(game.getboard().won() >= 0) return GTPResponse(false, "The game is already over."); Move m = parse_move(pos); if(!game.valid(m)) return GTPResponse(false, "Invalid move"); move(m); log(string("play ") + (toplay == 1 ? 'w' : 'b') + ' ' + move_str(m, false)); if(verbose >= 2) logerr("Placement: " + move_str(m) + ", outcome: " + game.getboard().won_str() + "\n" + game.getboard().to_s(colorboard)); return GTPResponse(true); }
void loop_xboard(void) { position_t* pos = position_new(); color_t engineColor = C_BLACK; IF.info_depth = info_depth; IF.info_pv = info_pv; IF.info_curmove = info_curmove; IF.search_done = search_done; log_set_mode(MODE_GUI); log_line("xboard mode"); threads_init(pos); while (1) { char* line = get_line(); char* token = arg_start(line); if (!strcmp(token, "new")) { position_reset(pos); TT_clear(); engineColor = C_BLACK; InGame = 1; } else if (!strcmp(token, "quit")) { InGame = 0; threads_search_stop(); break; } else if (!strcmp(token, "protover")) { char* v = arg_next(); if (v && atoi(v) == 2) { send_line("feature myname=\"Walce\""); send_line("feature setboard=1 usermove=1 sigint=0 sigterm=0"); send_line("feature playother=1 ping=1 time=1 colors=0 name=1"); send_line("feature ics=1 analyze=1"); send_line("feature option=\"Search Depth -spin %d 0 20\"", 0); send_line("feature option=\"Thinking Time -spin %d 0 600000\"", 0); send_line("feature done=1"); } } else if (!strcmp(token, "random") || !strcmp(token, "bk") || !strcmp(token, "ics") || !strcmp(token, "name") || !strcmp(token, "accepted") || !strcmp(token, "computer") ) { ; // IGNORE } else if (!strcmp(token, "variant") || !strcmp(token, "rejected") || !strcmp(token, "draw") || !strcmp(token, "hint") || !strcmp(token, "hard") || !strcmp(token, "easy") || !strcmp(token, "rating") || !strcmp(token, "pause") || !strcmp(token, "resume") || !strcmp(token, "memory") || !strcmp(token, "cores") || !strcmp(token, "egtpath") ) { send_line("Error (not implemented yet): %s", token); } else if (!strcmp(token, "?")) { threads_search_stop(); } else if (!strcmp(token, "st")) { token = arg_next(); if (token) TC.l_time = atoi(token) * 1000; } else if (!strcmp(token, "level")) { char* moves = arg_next(); char* min = arg_next(); char* inc = arg_next(); char* sec = min ? strchr(min, ':') : NULL; if (sec) *sec++ = 0; if (inc) { int t = atoi(min) * 60 + (sec ? atoi(sec) : 0); TC.togo = atoi(moves); TC.ctime[0] = TC.otime[0] = t * 1000; TC.ctime[1] = TC.otime[1] = atoi(inc) * 1000; } } else if (!strcmp(token, "time")) { token = arg_next(); if (token) TC.ctime[0] = atoi(token) * 10; } else if (!strcmp(token, "otim")) { token = arg_next(); if (token) TC.otime[0] = atoi(token) * 10; } else if (!strcmp(token, "analyze")) { ModeAnalyze = 1; TC.infinite = 1; engineColor = pos->to_move; threads_search(); } else if (ModeAnalyze && !strcmp(token, "exit")) { threads_search_stop(); ModeAnalyze = 0; TC.infinite = 0; } else if (ModeAnalyze && !strcmp(token, ".")) { //send_line("Error (not implemented yet): %s", token); } else if (!strncmp(line, "result", 6)) { InGame = 0; threads_search_stop(); } else if (!strncmp(line, "force", 5)) { engineColor = C_NONE; } else if (!strcmp(token, "go")) { engineColor = pos->to_move; threads_search(); } else if (!strcmp(token, "playother")) { engineColor = 1 ^ pos->to_move; } else if (!strcmp(token, "white")) { pos->to_move = C_WHITE; engineColor = C_BLACK; } else if (!strcmp(token, "black")) { pos->to_move = C_BLACK; engineColor = C_WHITE; } else if (!strcmp(token, "sd")) { char* d = arg_next(); if (d) TC.l_depth = atoi(d); } else if (!strcmp(token, "ping")) { char* a = arg_rest(); if (a) send_line("pong %s", a); else send_line("pong"); } else if (!strcmp(token, "edit")) { send_line("Error (command not implemented): %s", token); } else if (!strcmp(token, "undo")) { if (!position_unmove(pos)) send_line("Error (command not legal now): %s", token); } else if (!strcmp(token, "remove")) { if (!position_unmove(pos) || !position_unmove(pos)) send_line("Error (command not legal now): %s", token); } else if (!strcmp(token, "setboard")) { char* b = arg_rest(); if (!b) send_line("Error (missing argument): %s", token); else position_set(pos, b); } else if (!strcmp(token, "post")) { ModePost = 1; } else if (!strcmp(token, "nopost")) { ModePost = 1; } else if (!strcmp(token, "option")) { char* o = arg_next_sep('='); char* v = arg_next(); if (!o) log_line("missing option"); else if (!strcmp(o, "Thinking Time")) { if (v) TC.l_time = atoi(v); } else if (!strcmp(o, "Search Depth")) { if (v) TC.l_depth = atoi(v); } else log_line("unknown option: %s", o); } else { if (!strcmp(token, "usermove")) token = arg_next(); threads_search_stop(); move_t move = parse_move(pos, token); if (!move) { send_line("Illegal move: %s", token); } else { position_move(pos, move); position_print(pos, C_WHITE); if (ModeAnalyze || engineColor == pos->to_move) threads_search(); } } } threads_exit(); position_destroy(pos); }
int main(void) { Color computer_player = -1; // not WHITE or BLACK if we don't play either (e.g. -1) int game_on = 0; Bitboard *board = malloc(sizeof(Bitboard)); Undo *u = NULL; char* input = malloc(sizeof(char) * max_input_length); Move last_move = 0; int got_move = 0; freopen("/dev/tty", "w", stderr); setbuf(stderr, NULL); setbuf(stdout, NULL); srandom(time(NULL)); while (1) { if (game_on && got_move) { u = malloc(sizeof(Undo)); board_do_move(board, last_move, u); got_move = 0; } if (game_on && computer_player == board->to_move) { last_move = search_find_move(board); move_srcdest_form(last_move, input); printf("move %s\n", input); u = malloc(sizeof(Undo)); board_do_move(board, last_move, u); } fgets(input, max_input_length, stdin); fprintf(stderr, "%s", input); if (!strcmp("xboard\n", input)) printf("feature colors=0 setboard=1 time=0 sigint=0 sigterm=0 variants=\"normal\" done=1\n"); else if (!strcmp("new\n", input)) { board_free_undos(u); board_init(board); computer_player = BLACK; game_on = 1; } else if (!strcmp("quit\n", input)) break; else if (!strcmp("force\n", input)) computer_player = -1; else if (!strcmp("go\n", input)) computer_player = board->to_move; else if (!strncmp("setboard ", input, 9)) board_init_with_fen(board, input + 9); else if (!strncmp("result", input, 6)) { computer_player = -1; game_on = 0; } else if (!strncmp("level ", input, 6)) timer_init(input); else if (!strcmp("_print\n", input)) { board_print(board); printf("Evaluation: %i\n", evaluate_board(board)); puts("Pseudolegal moves: "); Movelist all_moves; move_generate_movelist(board, &all_moves); Moveiter it; moveiter_init(&it, &all_moves, MOVEITER_SORT_NONE, MOVE_NULL); char srcdest_form[6]; while (moveiter_has_next(&it)) { Move m = moveiter_next(&it); move_srcdest_form(m, srcdest_form); printf("%s ", srcdest_form); } puts("\n"); } else if (input[0] >= 'a' && input[0] <= 'h' && input[1] >= '1' && input[1] <= '8' && input[2] >= 'a' && input[2] <= 'h' && input[3] >= '1' && input[3] <= '8') { last_move = parse_move(board, input); if (!last_move) printf("Illegal move: %s", input); else got_move = 1; } else printf("Error (unknown command): %s", input); } free(board); free(input); return 0; }
int main(int argc, char* argv[]) { ChessBoard c; Player *w_player=NULL, *b_player=NULL, *this_player; string cmd, log; game_status status=Normal; chessmove *m = NULL; int turn=0; // Process command-line parameters while (argc-- > 1) { argv++; if (strcmp(*argv, "--help") == 0) { show_help(); exit(0); } else if (strcmp(*argv, "--version") == 0) { show_version(); exit(0); } else { cerr << "cheops: unrecognized option `" << argv[0] << "'\n"; show_help(); exit(1); } } // Print title screen show_version(); cout << "\t\t\t__ __\n" "\t\t\t\\ \\ / /\n" "\t\t\t \\ v / ___ ___ _ _ _\n" "\t\t\t > < / __) _ \\| || || |\n" "\t\t\t / ^ \\> _| (_) ) \\| |/ |\n" "\t\t\t/_/ \\_\\___)___/ \\_ _/\n" "\t\t\t _________________| |__\n" "\t\t\t(_________________|_|__)\n\n" ; who_plays(w_player, b_player); cout << "\nEnter \"help\" or \"?\" for the menu.\n" << c; // Main loop while (1) { cout.flush(); this_player=c.white_moves()?w_player:b_player; cmd=this_player->get_command(c); if (cmd=="board" || cmd=="bd") cout << c; else if (cmd=="reverse") c.show_reverse=!c.show_reverse; else if (cmd=="coords") c.show_coordinates=!c.show_coordinates; else if (cmd=="think") ComputerPlayer::show_thinking=!ComputerPlayer::show_thinking; else if (cmd=="help" || cmd=="?") show_menu(); else if (cmd=="who") who_plays(w_player, b_player); else if (cmd=="save") { ofstream logfile("cheops.log"); logfile << log << endl; logfile.close(); } else if (cmd=="new") { c=ChessBoard(); turn=0; log=string(); } else if (cmd=="quit" || cmd=="exit") break; else if (cmd=="log") cout << log << endl; else if (cmd=="resign") { cout << "You resign. " << (c.white_moves()?"Black":"White") << " wins!\n"; c.in_progress=false; } else { delete m; // Kingside castling if (cmd=="o-o") { m = new chessmove; m->promotion=Empty; m->from=this_player==w_player?e1:e8; m->to=this_player==w_player?g1:g8; } // Queenside castling else if (cmd=="o-o-o") { m = new chessmove; m->promotion=Empty; m->from=this_player==w_player?e1:e8; m->to=this_player==w_player?c1:c8; } // Regular move else m=parse_move(cmd); if (c.in_progress && (!this_player->human || m && c.can_move(*m))) { status=c.do_move(*m); cout << c; // Update board log if (turn%2==0) { char tmp[6]; sprintf(tmp,"%2d. ",turn/2+1); log+=tmp; log+=*m; } else { log+='\t'; log+=*m; log+='\n'; } turn++; // Display board status switch (status) { case Checkmate: cout << "Checkmate!\n"; break; case Stalemate: cout << "Stalemate!\n"; break; case TripleOccurrence: cout << "Triple occurrence -- game is drawn.\n"; break; case FiftyMoves: cout << "Fifty move rule -- game is drawn.\n"; case Check: cout << "Check!\n"; break; } } else cout << "Illegal move\n"; } } return 0; }
int mainConsoleChess(int pick_side) { int computer_side; char s[256]; int m; printf("\n"); printf("Phung Nhat Huy and Pham Duy Hung's Console Chess\n"); printf("\n"); printf("Type \"help\" to displays a list of commands.\n"); printf("\n"); init_hash(); init_board(); gen(); computer_side = EMPTY; max_time = 1 << 25; max_depth = 4; for (;;) { if (side == computer_side) { /* computer's turn */ /* think about the move and make it */ //think(1); if (!pv[0][0].u) { printf("(no legal moves)\n"); computer_side = EMPTY; continue; } printf("Your enermy's move: %s\n", move_str(pv[0][0].b)); makemove(pv[0][0].b); ply = 0; gen(); print_result(); continue; } /* get user input */ printf("ConsoleChess > "); if (scanf("%s", s) == EOF) return 0; if (!strcmp(s, "on")) { computer_side = side; continue; } if (!strcmp(s, "off")) { computer_side = EMPTY; continue; } if (!strcmp(s, "undo")) { if (!hply) continue; computer_side = EMPTY; takeback(); ply = 0; gen(); continue; } if (!strcmp(s, "new")) { computer_side = EMPTY; init_board(); gen(); continue; } if (!strcmp(s, "d")) { print_board(); continue; } /*if (!strcmp(s, "bench")) { computer_side = EMPTY; bench(); continue; }*/ if (!strcmp(s, "bye")) { printf("Thanks for playing. Enjoy!\n"); break; } if (!strcmp(s, "help")) { printf("on - computer plays for the side to move\n"); printf("off - computer stops playing\n"); printf("undo - takes back a move\n"); printf("new - starts a new game\n"); printf("d - display the board\n"); printf("bye - exit the program\n"); printf("Enter moves in coordinate notation, e.g., e2e4, e7e8Q (for promote moving)\n"); continue; } /* maybe the user entered a move? */ m = parse_move(s); if (m == -1 || !makemove(gen_dat[m].m.b)) printf("Illegal move.\n"); else { ply = 0; gen(); print_result(); } } //close_book(); return 0; }
int book_move() { char line[256]; char book_line[256]; int i, j, m; int move[50]; /* the possible book moves */ int count[50]; /* the number of occurrences of each move */ int moves = 0; int total_count = 0; if (!book_file || hply > 25) return -1; /* line is a string with the current line, e.g., "e2e4 e7e5 g1f3 " */ line[0] = '\0'; j = 0; for (i = 0; i < hply; ++i) j += sprintf(line + j, "%s ", move_str(hist_dat[i].m.b)); /* compare line to each line in the opening book */ fseek(book_file, 0, SEEK_SET); while (fgets(book_line, 256, book_file)) { if (book_match(line, book_line)) { /* parse the book move that continues the line */ m = parse_move(&book_line[strlen(line)]); if (m == -1) continue; m = gen_dat[m].m.u; /* add the book move to the move list, or update the move's count */ for (j = 0; j < moves; ++j) if (move[j] == m) { ++count[j]; break; } if (j == moves) { move[moves] = m; count[moves] = 1; ++moves; } ++total_count; } } /* no book moves? */ if (moves == 0) return -1; /* Think of total_count as the set of matching book lines. Randomly pick one of those lines (j) and figure out which move j "corresponds" to. */ j = rand() % total_count; for (i = 0; i < moves; ++i) { j -= count[i]; if (j < 0) return move[i]; } return -1; /* shouldn't get here */ }
/** * @brief Loop event. * @param ui user interface. */ void ui_loop_edax(UI *ui) { char *cmd = NULL, *param = NULL; Play *play = ui->play; char book_file[FILENAME_MAX]; unsigned long long histogram[129][65]; int repeat = options.repeat; histogram_init(histogram); // loop forever for (;;) { errno = 0; if (options.verbosity) { putchar('\n'); play_print(play, stdout); if (play_is_game_over(play)) printf("\n*** Game Over ***\n"); putchar('\n'); } if (log_is_open(edax_log)) { putc('\n', edax_log->f); play_print(play, edax_log->f); if (play_is_game_over(play)) fputs("\n*** Game Over ***\n", edax_log->f); putc('\n', edax_log->f); } // edax turn ? (automatic play mode) if (!ui_event_exist(ui) && !play_is_game_over(play) && (ui->mode == !play->player || ui->mode == 2)) { putchar('\n'); play_go(play, true); printf("\nEdax plays "); move_print(play_get_last_move(play)->x, 0, stdout); putchar('\n'); if (ui->mode != 2) play_ponder(play); // proceed by reading a command } else { /* automatic rules after a game over*/ if (play_is_game_over(play)) { if (options.auto_store) play_store(play); if (options.auto_swap && ui->mode < 2) ui->mode = !ui->mode; if (options.repeat && repeat > 1) { --repeat; play_new(play); continue; } if (options.auto_quit) { return; } if (options.auto_start) { play_new(play); continue; } } putchar('>'); fflush(stdout); ui_event_wait(ui, &cmd, ¶m); log_print(edax_log, "cmd=\"%s\" ; param=\"%s\"\n", cmd, param); putchar('\n'); if (cmd == NULL) { warn("unexpected null command?\n"); continue; } // skip empty lines or commented lines if (*cmd == '\0' || *cmd == '#') { // help } else if (strcmp(cmd, "help") == 0 || strcmp(cmd, "?") == 0) { if (*param == '\0' || strcmp(param, "options") == 0) help_options(); if (*param == '\0' || strcmp(param, "commands") == 0) help_commands(); if (*param == '\0' || strcmp(param, "book") == 0) help_book(); if (*param == '\0' || strcmp(param, "base") == 0) help_base(); if (*param == '\0' || strcmp(param, "test") == 0) help_test(); // new game from standard position } else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "init") == 0) { board_init(play->initial_board); play_new(play); // new game from personnalized position } else if ((strcmp(cmd, "n") == 0 || strcmp(cmd, "new") == 0) && *param == '\0') { play_new(play); // open a saved game } else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "open") == 0 || strcmp(cmd, "load") == 0) { play_load(play, param); // save a game } else if (strcmp(cmd, "s") == 0 || strcmp(cmd, "save") == 0) { play_save(play, param); // quit } else if (strcmp(cmd, "quit") == 0 || strcmp(cmd, "q") == 0 || strcmp(cmd, "exit") == 0) { free(cmd); free(param); return; } else if (!options.auto_quit && (strcmp(cmd, "eof") == 0 && (ui->mode != 2 || play_is_game_over(play)))){ free(cmd); free(param); return; // undo last move } else if (strcmp(cmd, "u") == 0 || strcmp(cmd, "undo") == 0) { play_undo(play); if (ui->mode == 0 || ui->mode == 1) play_undo(play); // redo last move } else if (strcmp(cmd, "r") == 0 || strcmp(cmd, "redo") == 0) { play_redo(play); if (ui->mode == 0 || ui->mode == 1) play_undo(play); // mode } else if (strcmp(cmd, "m") == 0 || strcmp(cmd, "mode") == 0) { ui->mode = string_to_int(param, 3); // analyze a game } else if (strcmp(cmd, "a") == 0 || strcmp(cmd, "analyze") == 0 || strcmp(cmd, "analyse") == 0) { play_analyze(play, string_to_int(param, play->n_game)); // set a new initial position } else if (strcmp(cmd, "setboard") == 0) { play_set_board(play, param); // vertical mirror } else if (strcmp(cmd, "vmirror") == 0) { play_symetry(play, 2); // horizontal mirror } else if (strcmp(cmd, "hmirror") == 0) { play_symetry(play, 1); // rotate } else if (strcmp(cmd, "rotate") == 0) { int angle = string_to_int(param, 90) % 360; if (angle < 0) angle += 360; switch (angle) { case 90: play_symetry(play, 5); break; case 180: play_symetry(play, 3); break; case 270: play_symetry(play, 6); break; default: warn("Rotate angle should be 90°, 180° or 270°"); break; } // direct symetry... } else if (strcmp(cmd, "symetry") == 0) { int sym = string_to_int(param, 1); if (sym < 0 || sym >= 16) warn("symetry parameter should be a number between 0 and 15\n"); else { if (sym & 8) play->player ^= 1; play_symetry(play, sym & 7); } // play a serie of moves } else if (strcmp(cmd, "play") == 0) { string_to_lowercase(param); play_game(play, param); // force edax to play an opening } else if (strcmp(cmd, "force") == 0) { string_to_lowercase(param); play_force_init(play, param); // solve a set of problems } else if (strcmp(cmd, "solve") == 0) { char problem_file[FILENAME_MAX + 1], *hard_file; hard_file = parse_word(param, problem_file, FILENAME_MAX); parse_word(hard_file, hard_file, FILENAME_MAX); obf_test(play->search, problem_file, hard_file); search_set_observer(play->search, edax_observer); // convert a set of problems in a .script file to a .obf file } else if (strcmp(cmd, "script-to-obf") == 0) { char script_file[FILENAME_MAX + 1], *obf_file; obf_file = parse_word(param, script_file, FILENAME_MAX); parse_word(obf_file, obf_file, FILENAME_MAX); script_to_obf(play->search, script_file, obf_file); search_set_observer(play->search, edax_observer); } else if (strcmp(cmd, "select-hard") == 0) { char full_file[FILENAME_MAX + 1], *hard_file; hard_file = parse_word(param, full_file, FILENAME_MAX); parse_word(hard_file, hard_file, FILENAME_MAX); obf_filter(full_file, hard_file); // game/position enumeration } else if (strcmp(cmd, "count") == 0) { char count_cmd[16], *count_param; int depth = 10, size = 8; count_param = parse_word(param, count_cmd, 15); count_param = parse_int(count_param, &depth); BOUND(depth, 1, 90, "max-ply"); if (count_param) parse_int(count_param, &size); BOUND(size, 6, 8, "board-size"); if (strcmp(count_cmd, "games") == 0) { // game enumeration quick_count_games(play->board, depth, size); } else if (strcmp(count_cmd, "positions") == 0) { // position enumeration count_positions(play->board, depth, size); } else if (strcmp(count_cmd, "shapes") == 0) { // shape enumeration count_shapes(play->board, depth, size); } else { warn("Unknown count command: \"%s %s\"\n", cmd, param); } } else if (strcmp(cmd, "perft") == 0) { int depth = 14; depth = string_to_int(param, 10); BOUND(depth, 1, 90, "max-ply"); count_games(play->board, depth); // game/position enumeration } else if (strcmp(cmd, "estimate") == 0) { int n = 1000; n = string_to_int(param, 10); BOUND(n, 1, 2000000000, "max-trials"); estimate_games(play->board, n); // seek highest mobility } else if (strcmp(cmd, "mobility") == 0) { int t = 3600; // 1 hour t = string_to_int(param, 10); BOUND(t, 1, 3600*24*365*10, "max time"); seek_highest_mobility(play->board, t); // seek a position } else if (strcmp(cmd, "seek") == 0) { Board target; Line solution; board_set(&target, param); line_init(&solution, play->player); if (seek_position(&target, play->board, &solution)) { printf("Solution found:\n"); line_print(&solution, 200, " ", stdout); putchar('\n'); } // bench (a serie of low level tests). } else if (strcmp(cmd, "bench") == 0) { bench(); // wtest test the engine against wthor theoretical scores } else if (strcmp(cmd, "wtest") == 0) { wthor_test(param, play->search); // make wthor games played by "Edax (Delorme)" as "Etudes" tournament. } else if (strcmp(cmd, "edaxify") == 0) { wthor_edaxify(param); // wtest test the engine against wthor theoretical scores } else if (strcmp(cmd, "weval") == 0) { wthor_eval(param, play->search, histogram); histogram_print(histogram); histogram_stats(histogram); histogram_to_ppm("weval.ppm", histogram); // go think! } else if (strcmp(cmd, "go") == 0) { if (play_is_game_over(play)) printf("\n*** Game Over ***\n"); else { play_go(play, true); printf("\nEdax plays "); move_print(play_get_last_move(play)->x, 0, stdout); putchar('\n'); } // hint for [n] moves } else if (strcmp(cmd, "hint") == 0) { int n = string_to_int(param, 1); BOUND(n, 1, 60, "n_moves"); play_hint(play, n); // stop thinking } else if (strcmp(cmd, "stop") == 0) { ui->mode = 3; // user move } else if (play_user_move(play, cmd)) { printf("\nYou play "); move_print(play_get_last_move(play)->x, 0, stdout); putchar('\n'); // debug pv } else if (strcmp(cmd, "debug-pv") == 0) { Move move[1]; if (parse_move(param, play->board, move) != param) { search_set_board(play->search, play->board, play->player); pv_debug(play->search, move, stdout); } } else if (strcmp(cmd, "options") == 0) { options_dump(stdout); #ifdef __unix__ } else if (strcmp(cmd, "resources") == 0) { struct rusage u; long long t; getrusage(RUSAGE_SELF, &u); t = 1000 * u.ru_utime.tv_sec + u.ru_utime.tv_usec / 1000; printf("user cpu time: "); time_print(t, false, stdout); printf("\n"); t = 1000 * u.ru_stime.tv_sec + u.ru_stime.tv_usec / 1000; printf("system cpu time: "); time_print(t, false, stdout); printf("\n"); printf("max resident memory: %ld\n", u.ru_maxrss); printf("page fault without I/O: %ld\n", u.ru_minflt); printf("page fault with I/O: %ld\n", u.ru_majflt); printf("number of input: %ld\n", u.ru_inblock); printf("number of output: %ld\n", u.ru_oublock); printf("number of voluntary context switch: %ld\n", u.ru_nvcsw); printf("number of unvoluntary context switch: %ld\n\n", u.ru_nivcsw); #endif // opening name } else if (strcmp(cmd, "opening") == 0) { const char *name; name = play_show_opening_name(play, opening_get_english_name); if (name == NULL) name = "?"; puts(name); // opening name in french } else if (strcmp(cmd, "ouverture") == 0) { const char *name; name = play_show_opening_name(play, opening_get_french_name); if (name == NULL) name = "?"; puts(name); // opening book commands } else if (strcmp(cmd, "book") == 0 || strcmp(cmd, "b") == 0) { char book_cmd[FILENAME_MAX + 1], *book_param; int val_1, val_2; Book *book = play->book; book->search = play->search; book->search->options.verbosity = book->options.verbosity; book_param = parse_word(param, book_cmd, FILENAME_MAX); // store the last played game if (strcmp(book_cmd, "store") == 0) { play_store(play); // turn book usage on } else if (strcmp(book_cmd, "on") == 0) { // learn options.book_allowed = true; // turn book usage off } else if (strcmp(book_cmd, "off") == 0) { // learn options.book_allowed = false; // set book randomness } else if (strcmp(book_cmd, "randomness") == 0) { // learn val_1 = 0; book_param = parse_int(book_param, &val_1); options.book_randomness = val_1; // set book depth (until which to learn) } else if (strcmp(book_cmd, "depth") == 0) { // learn val_1 = 36; book_param = parse_int(book_param, &val_1); book->options.n_empties = 61 - val_1; // create a new empty book } else if (strcmp(book_cmd, "new") == 0) { val_1 = 21; book_param = parse_int(book_param, &val_1); val_2 = 36; book_param = parse_int(book_param, &val_2); book_free(book) ; book_new(book, val_1, 61 - val_2); // load an opening book (binary format) from the disc } else if (strcmp(book_cmd, "load") == 0 || strcmp(book_cmd, "open") == 0) { book_free(book) ; parse_word(book_param, book_file, FILENAME_MAX); book_load(book, book_file); // save an opening book (binary format) to the disc } else if (strcmp(book_cmd, "save") == 0) { parse_word(book_param, book_file, FILENAME_MAX); book_save(book, book_file); // import an opening book (text format) } else if (strcmp(book_cmd, "import") == 0) { book_free(book); parse_word(book_param, book_file, FILENAME_MAX); book_import(book, book_file); book_link(book); book_fix(book); book_negamax(book); book_sort(book); // export an opening book (text format) } else if (strcmp(book_cmd, "export") == 0) { parse_word(book_param, book_file, FILENAME_MAX); book_export(book, book_file); // merge an opening book to the current one } else if (strcmp(book_cmd, "merge") == 0) { Book src[1]; parse_word(book_param, book_file, FILENAME_MAX); src->search = play->search; book_load(src, book_file); book_merge(book, src); book_free(src); warn("Book needs to be fixed before usage\n"); // fix an opening book } else if (strcmp(book_cmd, "fix") == 0) { book_fix(book); // do nothing (or edax is buggy) book_link(book); // links nodes book_negamax(book); // negamax nodes book_sort(book); // sort moves // negamax an opening book } else if (strcmp(book_cmd, "negamax") == 0) { book_negamax(book); // negamax nodes book_sort(book); // sort moves // check and correct solved positions of the book } else if (strcmp(book_cmd, "correct") == 0) { book_correct_solved(book); // do nothing (or edax is buggy) book_fix(book); // do nothing (or edax is buggy) book_link(book); // links nodes book_negamax(book); // negamax nodes book_sort(book); // sort moves // prune an opening book } else if (strcmp(book_cmd, "prune") == 0) { book_prune(book); // remove unreachable lines. book_fix(book); // do nothing (or edax is buggy) book_link(book); // links nodes book_negamax(book); // negamax nodes book_sort(book); // sort moves // show the current position as stored in the book } else if (strcmp(book_cmd, "show") == 0) { book_show(book, play->board); // show book general information } else if (strcmp(book_cmd, "info") == 0) { book_info(book); // show book general information } else if (strcmp(book_cmd, "stats") == 0) { book_stats(book); // set book verbosity } else if (strcmp(book_cmd, "verbose") == 0) { parse_int(book_param, &book->options.verbosity); book->search->options.verbosity = book->options.verbosity; // analyze a game from the opening book point of view } else if (strcmp(book_cmd, "a") == 0 || strcmp(book_cmd, "analyze") == 0 || strcmp(book_cmd, "analyse") == 0) { val_1 = string_to_int(book_param, play->n_game); BOUND(val_1, 1, play->n_game, "depth"); play_book_analyze(play, val_1); // add positions from a game database } else if (strcmp(book_cmd, "add") == 0) { Base base[1]; parse_word(book_param, book_file, FILENAME_MAX); base_init(base); base_load(base, book_file); book_add_base(book, base); base_free(base); // check positions from a game database } else if (strcmp(book_cmd, "check") == 0) { Base base[1]; parse_word(book_param, book_file, FILENAME_MAX); base_init(base); base_load(base, book_file); book_check_base(book, base); base_free(base); // extract positions } else if (strcmp(book_cmd, "problem") == 0) { val_1 = 24; book_param = parse_int(book_param, &val_1); BOUND(val_1, 0, 60, "number of empties"); val_2 = 10; book_param = parse_int(book_param, &val_2); BOUND(val_2, 1, 1000000, "number of positions"); book_extract_positions(book, val_1, val_2); // extract pv to a game database } else if (strcmp(book_cmd, "extract") == 0) { Base base[1]; parse_word(book_param, book_file, FILENAME_MAX); base_init(base); book_extract_skeleton(book, base); base_save(base, book_file); base_free(base); // add position using the "deviate algorithm" } else if (strcmp(book_cmd, "deviate") == 0) { val_1 = 2; book_param = parse_int(book_param, &val_1); BOUND(val_1, -129, 129, "relative error"); val_2 = 4; book_param = parse_int(book_param, &val_2); BOUND(val_2, 0, 65, "absolute error"); book_deviate(book, play->board, val_1, val_2); // add position using the "enhance algorithm" } else if (strcmp(book_cmd, "enhance") == 0) { val_1 = 2; book_param = parse_int(book_param, &val_1); BOUND(val_1, 0, 129, "midgame error"); val_2 = 4; book_param = parse_int(book_param, &val_2); BOUND(val_2, 0, 129, "endcut error"); book_enhance(book, play->board, val_1, val_2); // add position by filling hole in the book } else if (strcmp(book_cmd, "fill") == 0) { val_1 = 1; book_param = parse_int(book_param, &val_1); BOUND(val_1, 1, 61, "fill depth"); book_fill(book, val_1); // add positions by expanding positions with no-link } else if (strcmp(book_cmd, "play") == 0) { book_play(book); // add positions by expanding positions with no-link } else if (strcmp(book_cmd, "deepen") == 0) { book_deepen(book); // add book positions to the hash table } else if (strcmp(book_cmd, "feed-hash") == 0) { book_feed_hash(book, play->board, play->search); // wrong command ? } else { warn("Unknown book command: \"%s %s\"\n", cmd, param); } book->options.verbosity = book->search->options.verbosity; book->search->options.verbosity = options.verbosity; /* base TODO: add more actions... */ } else if (strcmp(cmd, "base") == 0) { char base_file[FILENAME_MAX + 1]; char base_cmd[512], *base_param; Base base[1]; base_init(base); base_param = parse_word(param, base_cmd, 511); base_param = parse_word(base_param, base_file, FILENAME_MAX); // extract problem from a game base if (strcmp(base_cmd, "problem") == 0) { char problem_file[FILENAME_MAX + 1]; int n_empties = 24; base_param = parse_int(base_param, &n_empties); base_param = parse_word(base_param, problem_file, FILENAME_MAX); base_load(base, base_file); base_to_problem(base, n_empties, problem_file); // extract FEN } else if (strcmp(base_cmd, "tofen") == 0) { char problem_file[FILENAME_MAX + 1]; int n_empties = 24; base_param = parse_int(base_param, &n_empties); base_param = parse_word(base_param, problem_file, FILENAME_MAX); base_load(base, base_file); base_to_FEN(base, n_empties, problem_file); // correct erroneous games } else if (strcmp(base_cmd, "correct") == 0) { int n_empties = 24; base_param = parse_int(base_param, &n_empties); base_load(base, base_file); base_analyze(base, play->search, n_empties, true); remove(base_file); base_save(base, base_file); // check erroneous games } else if (strcmp(base_cmd, "check") == 0) { int n_empties = 24; base_param = parse_int(base_param, &n_empties); base_load(base, base_file); base_analyze(base, play->search, n_empties, false); // terminate unfinished base } else if (strcmp(base_cmd, "complete") == 0) { base_load(base, base_file); base_complete(base, play->search); remove(base_file); base_save(base, base_file); // convert a base to another format } else if (strcmp(base_cmd, "convert") == 0) { base_load(base, base_file); base_param = parse_word(base_param, base_file, FILENAME_MAX); base_save(base, base_file); // make a base unique by removing identical games } else if (strcmp(base_cmd, "unique") == 0) { base_load(base, base_file); base_param = parse_word(base_param, base_file, FILENAME_MAX); base_unique(base); base_save(base, base_file); // compare two game bases } else if (strcmp(base_cmd, "compare") == 0) { char base_file_2[FILENAME_MAX + 1]; base_param = parse_word(base_param, base_file_2, FILENAME_MAX); base_compare(base_file, base_file_2); } else { warn("Unknown base command: \"%s %s\"\n", cmd, param); } base_free(base); /* edax options */ } else if (options_read(cmd, param)) { options_bound(); // parallel search changes: if (search_count_tasks(play->search) != options.n_task) { play_stop_pondering(play); search_set_task_number(play->search, options.n_task); } /* switch to another protocol */ } else if (strcmp(cmd, "nboard") == 0 && strcmp(param, "1") == 0) { free(cmd); free(param); play_stop_pondering(play); ui->free(ui); ui_switch(ui, "nboard"); ui->init(ui); ui->loop(ui); return; } else if (strcmp(cmd, "xboard") == 0) { free(cmd); free(param); play_stop_pondering(play); ui->free(ui); ui_switch(ui, "xboard"); ui->init(ui); ui->loop(ui); return; } else if (strcmp(cmd, "engine-protocol") == 0 && strcmp(param, "init") == 0) { free(cmd); free(param); play_stop_pondering(play); ui->free(ui); ui_switch(ui, "cassio"); engine_loop(); return; } else if (strcmp(cmd, "protocol_version") == 0) { free(cmd); free(param); play_stop_pondering(play); ui->free(ui); ui_switch(ui, "gtp"); ui->init(ui); puts("= 2\n"); fflush(stdout); ui->loop(ui); return; #ifdef TUNE_EDAX /* edax tuning */ } else if (strcmp(cmd, "tune") == 0) { char problem[FILENAME_MAX]; char *w_name; play_stop_pondering(play); w_name = parse_word(param, problem, FILENAME_MAX); tune_move_evaluate(play->search, problem, parse_skip_spaces(w_name)); search_set_observer(play->search, edax_observer); #endif /* illegal cmd/move */ } else { warn("Unknown command/Illegal move: \"%s %s\"\n", cmd, param); } } } }
int main() { int computer_side; char s[256]; int m; printf("\n"); printf("Tom Kerrigan's Simple Chess Program (TSCP)\n"); printf("version 1.81, 2/5/03\n"); printf("Copyright 1997 Tom Kerrigan\n"); printf("\n"); printf("\"help\" displays a list of commands.\n"); printf("\n"); init_hash(); init_board(); open_book(); gen(); computer_side = EMPTY; max_time = 1 << 25; max_depth = 4; for (;;) { if (side == computer_side) { /* computer's turn */ /* think about the move and make it */ think(1); if (!pv[0][0].u) { printf("(no legal moves)\n"); computer_side = EMPTY; continue; } printf("Computer's move: %s\n", move_str(pv[0][0].b)); makemove(pv[0][0].b); ply = 0; gen(); print_result(); continue; } /* get user input */ printf("tscp> "); if (scanf("%s", s) == EOF) return 0; if (!strcmp(s, "on")) { computer_side = side; continue; } if (!strcmp(s, "off")) { computer_side = EMPTY; continue; } if (!strcmp(s, "st")) { scanf("%d", &max_time); max_time *= 1000; max_depth = 32; continue; } if (!strcmp(s, "sd")) { scanf("%d", &max_depth); max_time = 1 << 25; continue; } if (!strcmp(s, "undo")) { if (!hply) continue; computer_side = EMPTY; takeback(); ply = 0; gen(); continue; } if (!strcmp(s, "new")) { computer_side = EMPTY; init_board(); gen(); continue; } if (!strcmp(s, "d")) { print_board(); continue; } if (!strcmp(s, "bench")) { computer_side = EMPTY; bench(); continue; } if (!strcmp(s, "bye")) { printf("Share and enjoy!\n"); break; } if (!strcmp(s, "xboard")) { xboard(); break; } if (!strcmp(s, "help")) { printf("on - computer plays for the side to move\n"); printf("off - computer stops playing\n"); printf("st n - search for n seconds per move\n"); printf("sd n - search n ply per move\n"); printf("undo - takes back a move\n"); printf("new - starts a new game\n"); printf("d - display the board\n"); printf("bench - run the built-in benchmark\n"); printf("bye - exit the program\n"); printf("xboard - switch to XBoard mode\n"); printf("Enter moves in coordinate notation, e.g., e2e4, e7e8Q\n"); continue; } /* maybe the user entered a move? */ m = parse_move(s); if (m == -1 || !makemove(gen_dat[m].m.b)) printf("Illegal move.\n"); else { ply = 0; gen(); print_result(); } } close_book(); return 0; }
void xboard() { int computer_side; char line[256], command[256]; int m; int post = 0; signal(SIGINT, SIG_IGN); printf("\n"); init_board(); gen(); computer_side = EMPTY; for (;;) { fflush(stdout); if (side == computer_side) { think(post); if (!pv[0][0].u) { computer_side = EMPTY; continue; } printf("move %s\n", move_str(pv[0][0].b)); makemove(pv[0][0].b); ply = 0; gen(); print_result(); continue; } if (!fgets(line, 256, stdin)) return; if (line[0] == '\n') continue; sscanf(line, "%s", command); if (!strcmp(command, "xboard")) continue; if (!strcmp(command, "new")) { init_board(); gen(); computer_side = DARK; continue; } if (!strcmp(command, "quit")) return; if (!strcmp(command, "force")) { computer_side = EMPTY; continue; } if (!strcmp(command, "white")) { side = LIGHT; xside = DARK; gen(); computer_side = DARK; continue; } if (!strcmp(command, "black")) { side = DARK; xside = LIGHT; gen(); computer_side = LIGHT; continue; } if (!strcmp(command, "st")) { sscanf(line, "st %d", &max_time); max_time *= 1000; max_depth = 32; continue; } if (!strcmp(command, "sd")) { sscanf(line, "sd %d", &max_depth); max_time = 1 << 25; continue; } if (!strcmp(command, "time")) { sscanf(line, "time %d", &max_time); max_time *= 10; max_time /= 30; max_depth = 32; continue; } if (!strcmp(command, "otim")) { continue; } if (!strcmp(command, "go")) { computer_side = side; continue; } if (!strcmp(command, "hint")) { think(0); if (!pv[0][0].u) continue; printf("Hint: %s\n", move_str(pv[0][0].b)); continue; } if (!strcmp(command, "undo")) { if (!hply) continue; takeback(); ply = 0; gen(); continue; } if (!strcmp(command, "remove")) { if (hply < 2) continue; takeback(); takeback(); ply = 0; gen(); continue; } if (!strcmp(command, "post")) { post = 2; continue; } if (!strcmp(command, "nopost")) { post = 0; continue; } m = parse_move(line); if (m == -1 || !makemove(gen_dat[m].m.b)) printf("Error (unknown command): %s\n", command); else { ply = 0; gen(); print_result(); } } }