virtual ChessPlayer *CreatePlayer(ChessSide side) { while (humanSide == SIDE_NEITHER) { TheTerminal.print("Which side do you want to play (w, b, quit)? "); std::string choice = TheTerminal.readline(); if (choice == "w") { humanSide = SIDE_WHITE; } else if (choice == "b") { humanSide = SIDE_BLACK; } else if (choice == "quit") { throw "Chess program exited."; } } if (side == humanSide) { human = new HumanChessPlayer(*this); return human; } else { computer = new ComputerChessPlayer(*this); computer->SetTimeLimit(ComputerThinkTime); computer->SetSearchBias(1); computer->setResignFlag(false); return computer; } }
//-------------------------------------------------------------- // Called whenever a player needs to be asked which // piece a pawn should be promoted to. // Must return one of the following values: // Q_INDEX, R_INDEX, B_INDEX, N_INDEX //-------------------------------------------------------------- virtual SQUARE PromotePawn(int pawnDest, ChessSide side) { while (true) { TheTerminal.print("Promote pawn to Q, R, N, B? "); std::string answer = TheTerminal.readline(); if (answer == "q") { return Q_INDEX; } else if (answer == "r") { return R_INDEX; } else if (answer == "n") { return N_INDEX; } else if (answer == "b") { return B_INDEX; } } }
//-------------------------------------------------------------- // The following function should return true if the Move // was read successfully, or false to abort the game. // The move does not have to be legal; if an illegal move // is returned, the caller will repeatedly call until a // legal move is obtained. //-------------------------------------------------------------- virtual bool ReadMove ( ChessBoard &board, int &source, int &dest, SQUARE &promPieceIndex ) // set to 0 (P_INDEX) if no promotion, or call to PromotePawn is needed; set to N_INDEX..Q_INDEX to specify promotion. { promPieceIndex = P_INDEX; bool boardWasAlreadyPrinted = AutoPrintBoard; // accept either of the following two formats: e2e4, g7g8q while (true) { if (IsFirstPrompt) { IsFirstPrompt = false; TheTerminal.printline("Enter 'help' for info and more options."); } TheTerminal.print("Your move? "); std::string line = TheTerminal.readline(); // ================================================================= // REMEMBER: Update "PrintHelp()" every time you add a command! // ================================================================= if (line == "board") { ReallyDrawBoard(board); boardWasAlreadyPrinted = true; } else if (line == "help") { PrintHelp(); } else if (line == "new") { if (human) { human->SetQuitReason(qgr_startNewGame); // suppress saying that the player resigned } return false; // Start a new game. } else if (line == "quit") { throw "Chess program exited."; } else if (line == "show") { AutoPrintBoard = true; if (!boardWasAlreadyPrinted) { ReallyDrawBoard(board); boardWasAlreadyPrinted = true; } } else if (line == "swap") { if (game) { humanSide = OppositeSide(humanSide); if (humanSide == SIDE_WHITE) { game->SetPlayers(human, computer); } else { game->SetPlayers(computer, human); } TheTerminal.print("You are now playing as "); TheTerminal.print(SideName(humanSide)); TheTerminal.printline("."); source = 0; dest = SPECIAL_MOVE_NULL; return true; } } else if (line == "time") { // Adjust computer's think time. TheTerminal.print("The computer's max think time is now "); TheTerminal.printChessTime(ComputerThinkTime); TheTerminal.printline("."); TheTerminal.print("Enter new think time (0.1 .. 600): "); std::string line = TheTerminal.readline(); double thinkTime = atof(line.c_str()); if ((thinkTime >= 0.1) && (thinkTime < 600.0)) { ComputerThinkTime = static_cast<int>(100.0*thinkTime + 0.5); // round seconds to integer centiseconds if (computer) { computer->SetTimeLimit(ComputerThinkTime); } } else { TheTerminal.printline("Invalid think time - ignoring."); } } else { if (ParseFancyMove(line.c_str(), board, source, dest, promPieceIndex)) { return true; } } } }