void displayInfo(int board[4][4], int move_score[4], MoveDirection move) { displayBoard(board); displayScore(move_score); displayMove(move); printf("-------------------------\n"); }
Move Board::think() { // =========================================================================== // This is the entry point for search, it is intended to drive iterative deepening // The search stops if (whatever comes first): // - there is no legal move (checkmate or stalemate) // - there is only one legal move (in this case we don't need to search) // **later** - time is up // - the search is interrupted by the user, or by winboard // - the search depth is reached // =========================================================================== int score, legalmoves, currentdepth; Move singlemove; // =========================================================================== // Check if the game has ended, or if there is only one legal move, // because then we don't need to search: // =========================================================================== if (isEndOfgame(legalmoves, singlemove)) return NOMOVE; if (legalmoves == 1) { std::cout << "forced move: "; displayMove(singlemove); std::cout << std::endl; return singlemove; } // =========================================================================== // There is more than legal 1 move, so prepare to search: // =========================================================================== lastPVLength = 0; memset(lastPV, 0 , sizeof(lastPV)); memset(whiteHeuristics, 0, sizeof(whiteHeuristics)); memset(blackHeuristics, 0, sizeof(blackHeuristics)); inodes = 0; // display console header displaySearchStats(1, 0, 0); timer.init(); msStart = timer.getms(); // iterative deepening: for (currentdepth = 1; currentdepth <= searchDepth; currentdepth++) { // clear the buffers: memset(moveBufLen, 0, sizeof(moveBufLen)); memset(moveBuffer, 0, sizeof(moveBuffer)); memset(triangularLength, 0, sizeof(triangularLength)); memset(triangularArray, 0, sizeof(triangularArray)); followpv = true; score = alphabetapvs(0, currentdepth, -LARGE_NUMBER, LARGE_NUMBER); msStop = timer.getms(); displaySearchStats(2, currentdepth, score); // stop searching if the current depth leads to a forced mate: if ((score > (CHECKMATESCORE-currentdepth)) || (score < -(CHECKMATESCORE-currentdepth))) currentdepth = searchDepth; } return (lastPV[0]); }
void commands() { // ================================================================ // commands is used to read console input and execute the commands // It also serves as winboard driver. // The code is based on H.G. Muller's model WinBoard protocol driver: // http://www.open-aurec.com/wbforum/viewtopic.php?f=24&t=51739 // ================================================================= int i, j, number; int fenhalfmoveclock; int fenfullmovenumber; char fen[100]; char fencolor[1]; char fencastling[4]; char fenenpassant[2]; char sanMove[12]; char command[80]; char userinput[80]; U64 msStart,msStop, perftcount; Timer timer; Move move, dummy; // ================================================================= // infinite loop: // ================================================================= while (1) { fflush(stdout); // ================================================================= // think & move // ================================================================= if (XB_MODE) { if (XB_COMPUTER_SIDE == board.nextMove) { #ifdef KENNY_DEBUG_WINBOARD std::cout << "#-KENNY : start think" << std::endl; #endif move = board.think(); #ifdef KENNY_DEBUG_WINBOARD std::cout << "#-KENNY : exit think" << std::endl; std::cout << "#<KENNY : move " << SQUARENAME[move.getFrom()] << SQUARENAME[move.getTosq()] << std::endl; #endif if (move.moveInt) { printf("move "); printf("%s",SQUARENAME[move.getFrom()]); printf("%s",SQUARENAME[move.getTosq()]); if (move.isPromotion()) printf("%s",PIECECHARS[move.getProm()]); printf("\n"); makeMove(move); board.endOfGame++; board.endOfSearch = board.endOfGame; } } fflush(stdout); // ================================================================= // ponder // ================================================================= if (XB_COMPUTER_SIDE != XB_NONE && XB_COMPUTER_SIDE != XB_ANALYZE && XB_PONDER && board.endOfGame) { XB_NO_TIME_LIMIT = true; #ifdef KENNY_DEBUG_WINBOARD std::cout << "#-KENNY : start ponder" << std::endl; #endif move = board.think(); #ifdef KENNY_DEBUG_WINBOARD std::cout << "#-KENNY : exit ponder" << std::endl; #endif XB_NO_TIME_LIMIT = false; } // ================================================================= // analyze // ================================================================= if (XB_COMPUTER_SIDE == XB_ANALYZE) { XB_NO_TIME_LIMIT = true; #ifdef KENNY_DEBUG_WINBOARD std::cout << "#-KENNY : start analyze" << std::endl; #endif move = board.think(); #ifdef KENNY_DEBUG_WINBOARD std::cout << "#-KENNY : exit analyze" << std::endl; #endif XB_NO_TIME_LIMIT = false; } } noPonder: // ================================================================= // display the command prompt // ================================================================= if (!XB_MODE) { if (board.nextMove == WHITE_MOVE) std::cout << "wt> "; else std::cout << "bl> "; fflush(stdout); } // ================================================================= // read input, but only after attending a pending command received during // search/ponder/analyze: // ================================================================= if (!XB_DO_PENDING) { #ifdef KENNY_DEBUG_WINBOARD if (XB_MODE) std::cout << "#-KENNY : COMPUTER_SIDE=" << (int)XB_COMPUTER_SIDE << " PONDER=" << XB_PONDER << " nextMove=" << (int)board.nextMove << std::endl; #endif for (CMD_BUFF_COUNT = 0; (CMD_BUFF[CMD_BUFF_COUNT] = getchar()) != '\n'; CMD_BUFF_COUNT++); CMD_BUFF[CMD_BUFF_COUNT+1] = '\0'; #ifdef KENNY_DEBUG_WINBOARD if (XB_MODE) std::cout << "#>KENNY : " << CMD_BUFF << std::endl; #endif } #ifdef KENNY_DEBUG_WINBOARD else { if (XB_MODE) std::cout << "#>KENNY : " << CMD_BUFF << " (from peek)" << std::endl; } #endif XB_DO_PENDING = false; // ================================================================= // ignore empty lines // ================================================================= if (!CMD_BUFF_COUNT) continue; // ================================================================= // extract the first word // ================================================================= sscanf(CMD_BUFF, "%s", command); // ================================================================= // help, h or ?: show this help - list of CONSOLE-ONLY COMMANDS // ================================================================= if ((!XB_MODE) && ((!strcmp(command, "help")) || (!strcmp(command, "h")) || (!strcmp(command, "?")))) { std::cout << std::endl << "help:" << std::endl; std::cout << "black : BLACK to move" << std::endl; std::cout << "cc : play computer-to-computer " << std::endl; std::cout << "d : display board " << std::endl; std::cout << "eval : show static evaluation of this position" << std::endl; std::cout << "exit : exit program " << std::endl; std::cout << "game : show game moves " << std::endl; std::cout << "go : computer next move " << std::endl; std::cout << "help, h, or ? : show this help " << std::endl; std::cout << "info : display variables (for testing purposes)" << std::endl; std::cout << "ini : read the initialization file" << std::endl; std::cout << "memory n : max memory to use (in MB)" << std::endl; std::cout << "move e2e4, or h7h8q : enter a move (use this format)" << std::endl; std::cout << "moves : show all legal moves" << std::endl; std::cout << "new : start new game" << std::endl; std::cout << "perft n : calculate raw number of nodes from here, depth n " << std::endl; #ifdef KENNY_VERBOSE_SEE std::cout << "qsearch : shows sorted capture movelist" << std::endl; #endif std::cout << "quit : exit program " << std::endl; std::cout << "r : rotate board " << std::endl; std::cout << "readfen filename n : reads #-th FEN position from filename" << std::endl; std::cout << "sd n : set the search depth to n" << std::endl; std::cout << "setup : setup board... " << std::endl; std::cout << "test filename : starts search on all FEN position in 'filename'" << std::endl; std::cout << " using current time & search depth parameters" << std::endl; std::cout << " output is written in test.log" << std::endl; std::cout << "time s : time per move in seconds" << std::endl; std::cout << "undo : take back last move" << std::endl; std::cout << "white : WHITE to move" << std::endl; std::cout << std::endl; continue; } // ================================================================= // accepted: in reply to the "feature" command // ================================================================= if (XB_MODE && !strcmp(command, "accepted")) continue; // ================================================================= // analyze: enter analyze mode // ================================================================= if (XB_MODE && !strcmp(command, "analyze")) { XB_COMPUTER_SIDE = XB_ANALYZE; continue; } // ================================================================= // black: BLACK to move // ================================================================= if (!XB_MODE && !strcmp(command, "black") && board.nextMove == WHITE_MOVE) { board.hashkey ^= KEY.side; board.endOfSearch = 0; board.endOfGame = 0; board.nextMove = BLACK_MOVE; continue; } // ================================================================= // bk: show book moves from this position, if any // ================================================================= if (XB_MODE && !strcmp(command, "bk")) continue; // ================================================================= // cc: play computer-to-computer // ================================================================= if (!XB_MODE && !strcmp(command, "cc")) { while (!_kbhit() && !board.isEndOfgame(i, dummy)) { move = board.think(); if (move.moveInt) { makeMove(move); board.endOfGame++; board.endOfSearch = board.endOfGame; board.display(); } } continue; } // ================================================================= // computer: the opponent is also a computer chess engine // ================================================================= if (XB_MODE && !strcmp(command, "computer")) continue; // ================================================================= // cores n: informs the engine on how many CPU cores it is allowed to use maximally // ================================================================= if (XB_MODE && !strcmp(command, "cores")) continue; // ================================================================= // d: display board // ================================================================= if (!XB_MODE && !strcmp(command, "d")) { board.display(); continue; } // ================================================================= // easy: turn off pondering // ================================================================= if (XB_MODE && !strcmp(command, "easy")) { XB_PONDER = false; continue; } // ================================================================= // egtpath type path: informs the engine in which directory it can find end-game tables // ================================================================= if (XB_MODE && !strcmp(command, "egtpath")) continue; // ================================================================= // eval: show static evaluation of this position // ================================================================= if (!XB_MODE && !strcmp(command, "eval")) { number = board.eval(); std::cout << "eval score = " << number << std::endl; #ifdef KENNY_DEBUG_EVAL board.mirror(); board.display(); i = board.eval(); std::cout << "eval score = " << i << std::endl; board.mirror(); if (number != i) std::cout << "evaluation is not symmetrical! " << number << std::endl; else std::cout << "evaluation is symmetrical" << std::endl; #endif continue; } // ================================================================= // exit: leave analyze mode / exit program (if not in WB) // ================================================================= if (!strcmp(command, "exit")) { if (XB_MODE) { XB_COMPUTER_SIDE = XB_NONE; continue; } else break; } // ================================================================= // force: Set the engine to play neither color // ================================================================= if (XB_MODE && !strcmp(command, "force")) { XB_COMPUTER_SIDE = XB_NONE; continue; } // ================================================================= // game: show game moves // ================================================================= if (!XB_MODE && !strcmp(command, "game")) { if (board.endOfGame) { // make a temporary copy of board.gameLine[]; number = board.endOfGame; GameLineRecord *tmp = new GameLineRecord[number]; memcpy(tmp, board.gameLine, number * sizeof(GameLineRecord)); // unmake all moves: for (i = number-1 ; i >= 0 ; i--) { unmakeMove(tmp[i].move); board.endOfSearch = --board.endOfGame; } // redo all moves: j = board.nextMove; for (i = 0 ; i < number; i++) { // move numbering: if (!((i+j+2)%2)) std::cout << (i+2*j+2)/2 << ". "; else if (!i) std::cout << "1. ... "; // construct the move string toSan(tmp[i].move, sanMove); std::cout << sanMove; // output CRLF, or space: if (!((i+j+1)%2)) std::cout << std::endl; else std::cout << " "; // make the move: makeMove(tmp[i].move); board.endOfSearch = ++board.endOfGame; } std::cout << std::endl; // delete the temporary copy: delete[] tmp; } else { std::cout << "there are no game moves" << std::endl; } continue; } // ================================================================= // go: leave force mode and set the engine to play the color that is on move // ================================================================= if (!strcmp(command, "go")) { if (XB_MODE) { XB_COMPUTER_SIDE = board.nextMove; continue; } else { if (!board.isEndOfgame(i, dummy)) { move = board.think(); if (move.moveInt) { makeMove(move); board.endOfGame++; board.endOfSearch = board.endOfGame; } board.display(); board.isEndOfgame(i, dummy); CMD_BUFF_COUNT = '\0'; } else { board.display(); CMD_BUFF_COUNT = '\0'; } } continue; } // ================================================================= // hard: turn on pondering // ================================================================= if (XB_MODE && !strcmp(command, "hard")) { XB_PONDER = true; continue; } // ================================================================= // hint: respond with "Hint: xxx", where xxx is a suggested move // ================================================================= if (XB_MODE && !strcmp(command, "hint")) { continue; } // ================================================================= // ics hostname: the engine is playing on an Internet Chess Server (ICS) with the given hostname // ================================================================= if (XB_MODE && !strcmp(command, "ics")) { continue; } // ================================================================= // info: display variables (for testing purposes) // ================================================================= if (!XB_MODE && !strcmp(command, "info")) { info(); continue; } // ================================================================= // ini: read the initialization file // ================================================================= if (!XB_MODE && !strcmp(command, "ini")) { readIniFile(); continue; } // ================================================================= // level mps base inc: set time controls // ================================================================= if (XB_MODE && !strcmp(command, "level")) { sscanf(CMD_BUFF, "level %d %d %d", &XB_MPS, &XB_MIN, &XB_INC) == 3 || sscanf(CMD_BUFF, "level %d %d:%d %d", &XB_MPS, &XB_MIN, &XB_SEC, &XB_INC); XB_INC *= 1000; continue; } // ================================================================= // memory n: informs the engine on how much memory it is allowed to use maximally, in MB // ================================================================= if (XB_MODE && !strcmp(command, "memory")) continue; // ================================================================= // moves: show all legal moves // ================================================================= if (!XB_MODE && !strcmp(command, "moves")) { board.moveBufLen[0] = 0; board.moveBufLen[1] = movegen(board.moveBufLen[0]); std::cout << std::endl << "moves from this position:" << std::endl; number = 0; for (i = board.moveBufLen[0]; i < board.moveBufLen[1]; i++) { makeMove(board.moveBuffer[i]); if (isOtherKingAttacked()) { unmakeMove(board.moveBuffer[i]); } else { unmakeMove(board.moveBuffer[i]); toSan(board.moveBuffer[i], sanMove); std::cout << ++number << ". " << sanMove << std::endl; } } continue; } // ================================================================= // move: enter a move (use this format: move e2e4, or h7h8q) // ================================================================= if (!XB_MODE && !strcmp(command, "")) { sscanf(CMD_BUFF,"%s",userinput); // generate the pseudo-legal move list board.moveBufLen[0] = 0; board.moveBufLen[1] = movegen(board.moveBufLen[0]); if (isValidTextMove(userinput, move)) // check to see if the user move is also found in the pseudo-legal move list { makeMove(move); if (isOtherKingAttacked()) // post-move check to see if we are leaving our king in check { unmakeMove(move); std::cout << " invalid move, leaving king in check: " << userinput << std::endl; } else { board.endOfGame++; board.endOfSearch = board.endOfGame; board.display(); } } else { std::cout << " move is invalid or not recognized: " << userinput << std::endl; } continue; } // ================================================================= // name <something>: informs the engine of its opponent's name // ================================================================= if (XB_MODE && !strcmp(command, "name")) continue; // ================================================================= // new: reset the board to the standard chess starting position // ================================================================= if (!strcmp(command, "new")) { board.init(); if (XB_MODE) { XB_COMPUTER_SIDE = BLACK_MOVE; board.searchDepth = MAX_PLY; } continue; } // ================================================================= // nopost: turn off thinking/pondering output // ================================================================= if (XB_MODE && !strcmp(command, "nopost")) { XB_POST = false; continue; } // ================================================================= // otim n: set a clock that belongs to the opponent, in centiseconds // ================================================================= if (XB_MODE && !strcmp(command, "otim")) { // do not start pondering after receiving time commands, as a move will follow immediately sscanf(CMD_BUFF, "otim %d", &XB_OTIM); XB_OTIM *= 10; // convert to miliseconds; goto noPonder; } // ================================================================= // option name[=value]: setting of an engine-define option // ================================================================= if (XB_MODE && !strcmp(command, "option")) continue; // ================================================================= // perft: calculate raw number of nodes from here, depth n // ================================================================= if (!XB_MODE && !strcmp(command, "perft")) { sscanf(CMD_BUFF,"perft %d", &number); std::cout << " starting perft " << number << "..." << std::endl; timer.init(); board.moveBufLen[0] = 0; #ifdef KENNY_DEBUG_PERFT ICAPT = 0; IEP = 0; IPROM = 0; ICASTLOO = 0; ICASTLOOO = 0; ICHECK = 0; #endif msStart = timer.getms(); perftcount = perft(0, number); msStop = timer.getms(); std::cout << "nodes = " << perftcount << ", " << msStop - msStart << " ms, "; if ((msStop - msStart) > 0) std::cout << (perftcount/(msStop - msStart)) << " knods/s"; std::cout << std::endl; CMD_BUFF_COUNT = '\0'; #ifdef KENNY_DEBUG_PERFT std::cout << "captures = " << ICAPT << std::endl; std::cout << "en-passant = " << IEP << std::endl; std::cout << "castlings = " << ICASTLOO + ICASTLOOO << std::endl; std::cout << "promotions = " << IPROM << std::endl; std::cout << "checks = " << ICHECK << std::endl; #endif continue; } // ================================================================= // ping n: reply by sending the string pong n // ================================================================= if (XB_MODE && !strcmp(command, "ping")) { sscanf(CMD_BUFF,"ping %d", &number); std::cout << "pong " << number << std::endl; continue; } // ================================================================= // post: turn on thinking/pondering output // ================================================================= if (XB_MODE && !strcmp(command, "post")) { XB_POST = true; continue; } // ================================================================= // protover n: protocol version // ================================================================= if (XB_MODE && !strcmp(command, "protover")) { std::cout << "feature ping=1" << std::endl; std::cout << "feature setboard=1" << std::endl; std::cout << "feature colors=0" << std::endl; std::cout << "feature usermove=1" << std::endl; std::cout << "feature memory=1" << std::endl; std::cout << "feature debug=1" << std::endl; std::cout << "feature done=1" << std::endl; continue; } #ifdef KENNY_VERBOSE_SEE // ================================================================= // qsearch: shows sorted capture movelist // ================================================================= if (!XB_MODE && !strcmp(command, "qsearch")) { board.moveBufLen[0] = 0; board.moveBufLen[1] = captgen(board.moveBufLen[0]); std::cout << std::endl << "sorted capturing moves from this position:" << std::endl; std::cout << std::endl << " score:" << std::endl; number = 0; for (i = board.moveBufLen[0]; i < board.moveBufLen[1]; i++) { makeMove(board.moveBuffer[i]); if (isOtherKingAttacked()) { unmakeMove(board.moveBuffer[i]); } else { unmakeMove(board.moveBuffer[i]); std::cout << ++number << ". "; displayMove(board.moveBuffer[i]); std::cout << " " << board.moveBuffer[i + OFFSET].moveInt << std::endl; } } continue; } #endif // ================================================================= // quit: exit program // ================================================================= if (!strcmp(command, "quit")) break; // ================================================================= // r: rotate board // ================================================================= if (!XB_MODE && !strcmp(command, "r")) { board.viewRotated = !board.viewRotated; continue; } // ================================================================= // random: ignored // ================================================================= if (XB_MODE && !strcmp(command, "random")) continue; // ================================================================= // rating: ICS opponent's rating // ================================================================= if (XB_MODE && !strcmp(command, "rating")) continue; // ================================================================= // readfen filename n: reads #-th FEN position from filename // ================================================================= if (!XB_MODE && !strcmp(command, "readfen")) { sscanf(CMD_BUFF,"readfen %s %d", userinput, &number); board.init(); readFen(userinput, number); board.display(); continue; } // ================================================================= // rejected: feature is rejected // ================================================================= if (XB_MODE && !strcmp(command, "rejected")) continue; // ================================================================= // remove: undo the last two moves (one for each player) and continue playing the same color. // ================================================================= if (XB_MODE && !strcmp(command, "remove")) { if (board.endOfGame) { unmakeMove(board.gameLine[--board.endOfGame].move); board.endOfSearch = board.endOfGame; } if (board.endOfGame) { unmakeMove(board.gameLine[--board.endOfGame].move); board.endOfSearch = board.endOfGame; } continue; } // ================================================================= // result string {comment}: end the each game, e.g.: result 1-0 {White mates} // ================================================================= if (XB_MODE && !strcmp(command, "result")) { XB_COMPUTER_SIDE = XB_NONE; continue; } // ================================================================= // sd n: set the search depth to n // ================================================================= if (!strcmp(command, "sd")) { sscanf(CMD_BUFF,"sd %d", &board.searchDepth); if (board.searchDepth < 1) board.searchDepth = 1; if (board.searchDepth > MAX_PLY) board.searchDepth = MAX_PLY; std::cout << "KENNY> search depth " << board.searchDepth << std::endl; continue; } // ================================================================= // setboard fen: set up the board/position // ================================================================= if (XB_MODE && !strcmp(command, "setboard")) { XB_COMPUTER_SIDE = XB_NONE; sscanf(CMD_BUFF, "setboard %s %s %s %s %d %d", fen, fencolor, fencastling, fenenpassant, &fenhalfmoveclock, &fenfullmovenumber); setupFen(fen, fencolor, fencastling, fenenpassant, fenhalfmoveclock, fenfullmovenumber); continue; } // ================================================================= // setup: setup board... // ================================================================= if (!XB_MODE && !strcmp(command, "setup")) { setup(); continue; } // ================================================================= // stopfrac (0-100%): undocumented command to interactively change this // parameter (e.g. for running testsuites), default value is 60 // Don't start a new iteration if STOPFRAC fraction of the max search time // has passed // ================================================================= if (!XB_MODE && !strcmp(command, "stopfrac")) { number = (int)(STOPFRAC * 100); sscanf(CMD_BUFF, "stopfrac %d", &number); if (number < 1) number = 1; if (number > 100) number = 100; STOPFRAC = (float)(number/100.0); std::cout << "KENNY> stopfrac " << 100*STOPFRAC << std::endl; continue; } // ================================================================= // st time: set time controls // ================================================================= if (XB_MODE && !strcmp(command, "st")) { sscanf(CMD_BUFF, "st %d", &board.maxTime); board.maxTime *= board.maxTime; // convert to ms continue; } // ================================================================= // test filename: starts search on all FEN position in 'filename // ================================================================= if (!XB_MODE && !strcmp(command, "test")) { sscanf(CMD_BUFF,"test %s", userinput); board.init(); test(userinput); continue; } // ================================================================= // time: set a clock that belongs to the engine // ================================================================= if (!strcmp(command, "time")) { number = (int)board.maxTime / 1000; sscanf(CMD_BUFF,"time %d", &number); if (number < 1) number = 1; if (!XB_MODE) std::cout << "KENNY> search time " << number << " seconds" << std::endl; if (XB_MODE) { XB_CTIM = number * 10; board.maxTime = number * 10; // conversion to ms } else { board.maxTime = number * 1000; // conversion to ms } goto noPonder; } // ================================================================= // undo: take back last move // ================================================================= if (!strcmp(command, "undo")) { if (board.endOfGame) { unmakeMove(board.gameLine[--board.endOfGame].move); board.endOfSearch = board.endOfGame; if (!XB_MODE) board.display(); } else if (!XB_MODE) std::cout << "already at start of game" << std::endl; continue; } // ================================================================= // usermove move: do a move // ================================================================= if (XB_MODE && !strcmp(command, "usermove")) { sscanf(CMD_BUFF,"usermove %s",userinput); // generate the pseudo-legal move list board.moveBufLen[0] = 0; board.moveBufLen[1] = movegen(board.moveBufLen[0]); if (isValidTextMove(userinput, move)) // check to see if the user move is also found in the pseudo-legal move list { makeMove(move); if (isOtherKingAttacked()) // post-move check to see if we are leaving our king in check { #ifdef KENNY_DEBUG_WINBOARD std::cout << "#-KENNY : usermove illegal" << std::endl; #endif unmakeMove(move); } else { #ifdef KENNY_DEBUG_WINBOARD std::cout << "#-KENNY : usermove " << userinput << " made" << std::endl; #endif board.endOfGame++; board.endOfSearch = board.endOfGame; } } else { #ifdef KENNY_DEBUG_WINBOARD std::cout << "#-KENNY : usermove illegal" << std::endl; #endif } continue; } // ================================================================= // variant: the game is not standard chess // ================================================================= if(XB_MODE && !strcmp(command, "variant")) continue; // ================================================================= // white: WHITE to move // ================================================================= if (!XB_MODE && !strcmp(command, "white") && board.nextMove == BLACK_MOVE) { board.hashkey ^= KEY.side; board.endOfSearch = 0; board.endOfGame = 0; board.nextMove = WHITE_MOVE; continue; } // ================================================================= // xboard: put the engine into "xboard mode", stop all unsolicited output // ================================================================= if (!XB_MODE && !strcmp(command, "xboard")) { #ifdef KENNY_DEBUG_WINBOARD if (XB_MODE) std::cout << "#>KENNY : xboard" << std::endl; #endif std::cout << std::endl; XB_COMPUTER_SIDE = XB_NONE; XB_MODE = true; XB_POST = false; board.init(); continue; } // ================================================================= // unknown command: // ================================================================= printf("Error: unknown command: %s\n", command); #ifdef KENNY_DEBUG_WINBOARD if (XB_MODE) std::cout << "#<KENNY : Error: unknown command: " << command << std::endl; #endif } }