Go to the documentation of this file.00001
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
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
00183
00184
00185