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++;
    }
  }
}
示例#2
0
moveseq cubepos::parse_moveseq(const char*&p){
moveseq r;
int mv;
while((mv= parse_move(p))>=0)
r.push_back(mv);
return r;
}
示例#3
0
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;
}
示例#4
0
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;
}
示例#5
0
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;
}
示例#7
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);
}
示例#8
0
文件: proto_xboard.c 项目: Sgop/walce
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);
}
示例#9
0
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;
}
示例#10
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;
}
示例#11
0
文件: .c 项目: leaderwing/test_repo
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;
}
示例#12
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 */
}
示例#13
0
文件: edax.c 项目: markkings/reversi
/**
 * @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, &param);
			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);
			}
		}
	}
}
示例#14
0
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;
}
示例#15
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();
		}
	}
}