gnuShogiClient.cc
Go to the documentation of this file.
00001 /* gnuShogiClient.cc
00002  */
00003 #include "osl/game_playing/gnuShogiClient.h"
00004 #include "osl/game_playing/gameState.h"
00005 #include "osl/game_playing/csaLogger.h"
00006 #include "osl/game_playing/csaStopwatch.h"
00007 #include "osl/search/moveWithComment.h"
00008 #include "osl/record/psn.h"
00009 #include "osl/sennichite.h"
00010 #include <iostream>
00011 #include <sstream>
00012 
00013 osl::game_playing::
00014 GnuShogiClient::GnuShogiClient(ComputerPlayer *black, ComputerPlayer *white,
00015                                CsaLogger *l,
00016                                std::istream& is, std::ostream& os)
00017   : CuiClient(black, white, l, is, os)
00018 {
00019 }
00020 
00021 osl::game_playing::
00022 GnuShogiClient::~GnuShogiClient()
00023 {
00024 }
00025 
00026 bool osl::game_playing::
00027 GnuShogiClient::readAndProcessCommand()
00028 {
00029   CsaStopwatch timer;
00030   std::string line;
00031   std::getline(is, line);
00032   const long op_think_time = timer.read();
00033   if (! is) {
00034     logger->inputError("(stream not available)");
00035     throw EndGame();
00036   }
00037 
00038   if (line == "quit" || line == "exit")
00039     throw GnuShogiQuit();
00040 
00041   if (line == "undo")
00042   {
00043     logger->popMove();
00044     popMove();
00045     return false;
00046   }
00047   if (line == "force")
00048   {
00049     setComputerPlayer(BLACK, false);
00050     setComputerPlayer(WHITE, false);
00051     logger->breakGame();
00052     return false;
00053   }
00054   if (line == "black") {
00055     setComputerPlayer(BLACK, true);
00056     setComputerPlayer(WHITE, false);
00057     return true;
00058   }
00059   if (line == "white") {
00060     setComputerPlayer(BLACK, false);
00061     setComputerPlayer(WHITE, true);
00062     return true;
00063   }
00064   if (line == "go") {
00065     const Player turn = state->state().turn();
00066     if (! isComputer(turn)) {
00067       setComputerPlayer(turn, true);
00068       setComputerPlayer(alt(turn), false);
00069     }
00070     return false;
00071   }
00072   if (line == "new" || line == "beep" || line == "random")
00073     return false; // XXX
00074   if (line.find("time") == 0 || line.find("otime") == 0) {
00075     if (line.find("time") == 0) {
00076       std::istringstream ss(line);
00077       std::string dummy;
00078       int time;
00079       ss >> dummy >> time;
00080       setTimeLeft(time/100, time/100);
00081     }
00082     std::cerr << line << "\n";
00083     return false;
00084   }
00085   if (line.find("help") == 0) {
00086     std::cerr << "  2g7f        move a piece from 2g to 2f\n"
00087       "  P*2d        drop a pawn to 2d\n"
00088       "  undo        undo the last move\n"
00089       "  force       human plays both colors\n"
00090       "  black/white set computer's color\n"
00091       "  exit/quit   exit program\n";
00092     return true;
00093   }
00094   
00095   if (line.size() < 4)
00096     goto ignore;
00097   if (isdigit(line[0]) || line[1] == '*') // FIXME
00098   {
00099     const Move op_move=record::psn::strToMove(line, state->state());
00100     
00101     if (state->isIllegal(op_move))
00102     {
00103       os << "Illegal move\n";
00104       logger->inputError(line.c_str());
00105       return true;
00106     }
00107     const Sennichite result = pushMove(MoveWithComment(op_move), op_think_time);
00108     if (! result.isNormal())
00109     {
00110       if (result == Sennichite::BLACK_LOSE())
00111         os << "White mates!\n";
00112       else if (result == Sennichite::WHITE_LOSE())
00113         os << "Black mates!\n";
00114       else 
00115         os << "Black mates!\n"; // does xshogi know draw?
00116       setComputerPlayer(BLACK, false);
00117       setComputerPlayer(WHITE, false);
00118       logger->endByRepetition(result);
00119       throw EndGame();
00120     }
00121     const int chess_moves = state->chessMoves();
00122     os << chess_moves << ". " << record::psn::show(op_move)
00123        << " " << (time_keeper.timeLeft(op_move.player()) - op_think_time)*100
00124        << std::endl << std::flush;
00125     return false;
00126   }
00127 ignore:
00128   std::cerr << line << "\n";
00129   std::string comment = "ignored line " + line;
00130   logger->writeComment(comment.c_str());
00131   return false;
00132 }
00133 
00134 void osl::game_playing::
00135 GnuShogiClient::processComputerMove(const MoveWithComment& selected, 
00136                                     int my_think_time)
00137 {
00138   const Move best_move = selected.move;
00139   const Player turn = state->state().turn();
00140   if ((! best_move.isNormal())
00141       || (state->isIllegal(best_move)))
00142   {
00143     os << ((alt(turn) == BLACK) ? "Black" : "White")
00144               << " mates!\n";
00145     logger->resign(turn);
00146     setComputerPlayer(BLACK, false);
00147     setComputerPlayer(WHITE, false);
00148     throw EndGame();
00149   }
00150 
00151   const int chess_moves = state->chessMoves();
00152   os << chess_moves << ". ... " << record::psn::show(best_move)
00153      << " " << (time_keeper.timeLeft(turn) - my_think_time)*100
00154      << std::endl << std::flush;
00155 
00156   const Sennichite result = pushMove(selected, my_think_time);
00157   if (! result.isNormal())
00158   {
00159     if (result == Sennichite::BLACK_LOSE())
00160       os << "White mates!\n";
00161     else if (result == Sennichite::WHITE_LOSE())
00162       os << "Black mates!\n";
00163     else 
00164       os << "Black mates!\n";   // does xshogi know draw?
00165     setComputerPlayer(BLACK, false);
00166     setComputerPlayer(WHITE, false);
00167     logger->endByRepetition(result);
00168     throw EndGame();
00169   }
00170 }
00171 
00172 /* ------------------------------------------------------------------------- */
00173 // ;;; Local Variables:
00174 // ;;; mode:c++
00175 // ;;; c-basic-offset:2
00176 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines