csaClient.cc
Go to the documentation of this file.
00001 /* csaClient.cc
00002  */
00003 #include "osl/game_playing/csaClient.h"
00004 #include "osl/game_playing/gnuShogiClient.h"
00005 #include "osl/game_playing/gameState.h"
00006 #include "osl/game_playing/csaLogger.h"
00007 #include "osl/game_playing/csaStopwatch.h"
00008 #include "osl/search/moveWithComment.h"
00009 #include "osl/record/csa.h"
00010 #include "osl/record/csaIOError.h"
00011 #include "osl/container/moveStack.h"
00012 #include "osl/sennichite.h"
00013 #include "osl/misc/ctime.h"
00014 #include <boost/foreach.hpp>
00015 #include <iostream>
00016 
00017 osl::game_playing::
00018 CsaClient::CsaClient(ComputerPlayer *black, ComputerPlayer *white,
00019                      CsaLogger *l, std::istream& is, std::ostream& os)
00020   : CuiClient(black, white, l, is, os),
00021     show_move_with_comment(false), silent(false), line(128,' ')
00022 {
00023   setComputerPlayer(WHITE, true);
00024 }
00025 
00026 osl::game_playing::
00027 CsaClient::~CsaClient()
00028 {
00029 }
00030 
00031 bool osl::game_playing::
00032 CsaClient::readAndProcessCommand()
00033 {
00034   char ctime_buf[64];
00035   if (! silent) {
00036     std::cerr << "\nCsaClient start waiting ";
00037     const time_t now = time(0);
00038     std::cerr << ctime_r(&now, ctime_buf) 
00039               << state->state()
00040               << "TIME[" << time_keeper.timeElapsed(BLACK)
00041               << ":" << time_keeper.timeElapsed(WHITE)
00042               << "] ";
00043     const MoveStack& history = state->moveHistory();
00044     const vector<int>& eval_history = state->evalStack();
00045     for (int i=1; i<=8 && history.hasLastMove(i); ++i) {
00046       std::cerr << "(" << history.size() - i + 1 << ")" << record::csa::show(history.lastMove(i));
00047       if (i-1 < (int)eval_history.size() && eval_history[eval_history.size()-i])
00048         std::cerr << "<" << eval_history[eval_history.size()-i] << ">";
00049       std::cerr << " ";
00050     }
00051     std::cerr << std::endl << std::endl;
00052   }
00053   CsaStopwatch timer;
00054   std::getline(is, line);
00055   if (! silent) {
00056     std::cerr << "\nCsaClient read " << line << " ";
00057     const time_t now = time(0);
00058     std::cerr << ctime_r(&now, ctime_buf) 
00059               << std::endl;
00060   }
00061   const long op_think_time = timer.read();
00062   if (! is)
00063   {
00064     const char *message = "istream error (maybe closed)";
00065     std::cerr << message << std::cerr;
00066     logger->writeComment(message);
00067     throw EndGame();
00068   }
00069   
00070   if (line == "%TORYO")
00071   {
00072     logger->resign(state->state().turn());
00073     throw EndGame();
00074   }
00075 
00076   // TODO: %MATTA, %CHUDAN
00077   try
00078   {
00079     const Move op_move=record::csa::strToMove(line, state->state());
00080     const GameState::MoveType illegal_move = state->isIllegal(op_move);
00081     if (illegal_move)
00082     {
00083       std::cerr << "illegal move: " << line << "\n";
00084       logger->inputError(line.c_str());
00085       if (illegal_move == GameState::PAWN_DROP_FOUL)
00086         logger->writeComment("pawn drop foul");
00087       else if (illegal_move == GameState::UNSAFE_KING)
00088         logger->writeComment("unsafe king");
00089       else if (illegal_move == GameState::OTHER_INVALID)
00090         logger->writeComment("other illegal move");
00091       os << "%CHUDAN" << std::endl;
00092       throw EndGame();
00093     }
00094     const Sennichite result = pushMove(MoveWithComment(op_move), op_think_time);
00095     if (! result.isNormal())
00096     {
00097       os << "%SENNICHITE" << std::endl;
00098       logger->endByRepetition(result);
00099       throw EndGame();
00100     }
00101     if (! silent) {
00102       std::cerr << state->state()
00103                 << "TIME[" << time_keeper.timeElapsed(BLACK)
00104                 << ":" << time_keeper.timeElapsed(WHITE)
00105                 << "] ";
00106       const MoveStack& history = state->moveHistory();
00107       const vector<int>& eval_history = state->evalStack();
00108       for (int i=1; i<=8 && history.hasLastMove(i); ++i) {
00109         std::cerr << "(" << history.size() - i + 1 << ")" << record::csa::show(history.lastMove(i));
00110         if (i-1 < (int)eval_history.size() && eval_history[eval_history.size()-i])
00111           std::cerr << "<" << eval_history[eval_history.size()-i] << "> ";
00112         std::cerr << " ";
00113       }
00114       std::cerr << std::endl << std::endl;
00115     }
00116   }
00117   catch (record::csa::CsaIOError&)
00118   {
00119     std::cerr << "bad input: " << line << "\n";
00120     logger->inputError(line.c_str());
00121     throw EndGame();
00122   }
00123   return false;
00124 }
00125 
00126 void osl::game_playing::
00127 CsaClient::setShowMoveWithComment(bool value)
00128 {
00129   show_move_with_comment = value;
00130 }
00131 
00132 void osl::game_playing::
00133 CsaClient::processComputerMove(const MoveWithComment& selected, 
00134                                int my_think_time)
00135 {
00136   static std::string reserved="+7776FU";
00137   const Move best_move = selected.move;
00138   if ((! best_move.isNormal())
00139       || (state->isIllegal(best_move)))
00140   {
00141     if (best_move == Move::DeclareWin())
00142     {
00143       os << "%KACHI\n";
00144       logger->endByDeclaration(state->state().turn());
00145     }
00146     else
00147     {
00148       if (best_move.isNormal()) {
00149         std::cerr << "error: prefer resign to playing illegal move " << best_move << " code " << state->isIllegal(best_move) << "\n";
00150         logger->writeComment("error: prefer abort to playing illegal move");
00151         abort();
00152       }
00153       os << "%TORYO\n";
00154       logger->resign(state->state().turn());
00155     }
00156     throw EndGame();
00157   }
00158 
00159   os << record::csa::show(best_move, reserved);
00160   if (show_move_with_comment && (! selected.moves.empty() || selected.value != 0))
00161   {
00162     os << ",'* " << selected.value;
00163     BOOST_FOREACH(Move move, selected.moves)
00164     {
00165       os << " ";
00166       os << record::csa::show(move, reserved);
00167     }    
00168   }
00169   os << std::endl << std::flush;
00170 
00171   assert(isComputer(state->state().turn()));
00172 
00173   const Sennichite result = pushMove(selected, my_think_time);
00174   if (! result.isNormal())
00175   {
00176     logger->endByRepetition(result);
00177     throw EndGame();
00178   }
00179 }
00180 
00181 /* ------------------------------------------------------------------------- */
00182 // ;;; Local Variables:
00183 // ;;; mode:c++
00184 // ;;; c-basic-offset:2
00185 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines