00001
00002
00003 #include "osl/game_playing/usiResponse.h"
00004 #include "osl/game_playing/gameState.h"
00005 #include "osl/move_probability/featureSet.h"
00006 #include "osl/rating/ratingEnv.h"
00007 #include "osl/rating/featureSet.h"
00008 #include "osl/progress/ml/newProgress.h"
00009 #include "osl/sennichite.h"
00010 #include "osl/record/csa.h"
00011 #include "osl/record/usi.h"
00012 #ifndef MINIMAL
00013 # include "osl/record/ki2.h"
00014 #endif
00015 #include <boost/foreach.hpp>
00016 #include <boost/lexical_cast.hpp>
00017 #include <sstream>
00018 #include <iostream>
00019
00020 osl::game_playing::
00021 UsiResponse::UsiResponse(const UsiState& u, bool n, bool v)
00022 : usi_state(u), new_move_probability(n), verbose(v)
00023 {
00024 }
00025 osl::game_playing::
00026 UsiResponse::~UsiResponse()
00027 {
00028 }
00029
00030 osl::MoveVector osl::game_playing::
00031 UsiResponse::generateGoodMoves()
00032 {
00033 GameState state(usi_state.initial_state);
00034 BOOST_FOREACH(Move m, usi_state.moves)
00035 state.pushMove(m);
00036
00037 MoveVector normal_or_win_or_draw, loss;
00038 state.generateNotLosingMoves(normal_or_win_or_draw, loss);
00039 if (verbose && ! loss.empty()) {
00040 std::cerr << " removed losing move ";
00041 BOOST_FOREACH(Move m, loss)
00042 std::cerr << record::csa::show(m);
00043 std::cerr << "\n";
00044 }
00045 return normal_or_win_or_draw;
00046 }
00047
00048 void osl::game_playing::
00049 UsiResponse::genmoveProbability(int limit, MoveLogProbVector& out)
00050 {
00051 GameState gstate(usi_state.initial_state);
00052 BOOST_FOREACH(Move m, usi_state.moves)
00053 gstate.pushMove(m);
00054 const NumEffectState& state= gstate.state();
00055 const MoveStack& history = gstate.moveHistory();
00056 progress::ml::NewProgress progress(state);
00057 MoveLogProbVector moves;
00058 if (new_move_probability) {
00059 const move_probability::StandardFeatureSet& feature_set
00060 = move_probability::StandardFeatureSet::instance();
00061 Move threatmate = move_probability::StateInfo::findShortThreatmate
00062 (state, history.lastMove());
00063 move_probability::StateInfo info(state, progress.progress16(),
00064 history, threatmate);
00065 feature_set.generateLogProb(info, moves);
00066 } else {
00067 const rating::StandardFeatureSet& feature_set
00068 = rating::StandardFeatureSet::instance();
00069 rating::RatingEnv env;
00070 env.history = history;
00071 env.make(state, state.pin(state.turn()), state.pin(alt(state.turn())),
00072 progress.progress16());
00073 feature_set.generateLogProb(state, env, limit, moves);
00074 }
00075 for (size_t i=1; i<moves.size(); ++i)
00076 if (moves[i].logProb() <= moves[i-1].logProb() && moves[i-1].logProb()+1<=limit)
00077 moves[i].setLogProb(moves[i-1].logProb()+1);
00078
00079 MoveVector good_moves = generateGoodMoves();
00080 BOOST_FOREACH(MoveLogProb move, moves)
00081 if (good_moves.isMember(move.move()))
00082 out.push_back(move);
00083 }
00084
00085 void osl::game_playing::
00086 UsiResponse::genmoveProbability(int limit, std::string& out)
00087 {
00088 MoveLogProbVector moves;
00089 genmoveProbability(limit, moves);
00090 out = "genmove_probability";
00091 BOOST_FOREACH(MoveLogProb move, moves) {
00092 out += " ";
00093 out += record::usi::show(move.move());
00094 out += " ";
00095 out += boost::lexical_cast<std::string>(move.logProb());
00096 }
00097 }
00098
00099 void osl::game_playing::
00100 UsiResponse::genmove(std::string& out)
00101 {
00102 MoveVector moves = generateGoodMoves();
00103 out = "genmove";
00104 BOOST_FOREACH(Move move, moves) {
00105 out += " ";
00106 out += record::usi::show(move);
00107 }
00108 }
00109
00110 void osl::game_playing::
00111 UsiResponse::csashow(const NumEffectState& state, std::string& out)
00112 {
00113 std::ostringstream os;
00114 os << state;
00115 os << "csashowok";
00116 out = os.str();
00117 }
00118
00119 void osl::game_playing::
00120 UsiResponse::csamove(const NumEffectState& state, const std::string& str,
00121 std::string& out)
00122 {
00123 const Move move = record::usi::strToMove(str, state);
00124 out = "csamove ";
00125 out += record::csa::show(move);
00126 }
00127
00128 #ifndef MINIMAL
00129
00132 void osl::game_playing::
00133 UsiResponse::ki2moves(const NumEffectState& current,
00134 const std::string& moves_str, std::string& out)
00135 {
00136 NumEffectState state(current);
00137 vector<Move> moves;
00138 std::istringstream is(moves_str);
00139 std::string s;
00140 while (is >> s) {
00141 const Move move = record::usi::strToMove(s, state);
00142 moves.push_back(move);
00143 state.makeMove(move);
00144 }
00145 assert(!moves.empty());
00146
00147 Move last_move;
00148 if (! usi_state.moves.empty()) {
00149 last_move = usi_state.moves.back();
00150 }
00151 out = "ki2moves ";
00152 out += record::ki2::show(&*moves.begin(), &*moves.end(),
00153 current, last_move);
00154 }
00155
00159 void osl::game_playing::
00160 UsiResponse::ki2currentinfo(const NumEffectState& current, std::string& out)
00161 {
00162 Move last_last_move, last_move;
00163 if (1 <= usi_state.moves.size()) {
00164 last_move = usi_state.moves.back();
00165 }
00166 if (2 <= usi_state.moves.size()) {
00167 last_last_move = usi_state.moves[usi_state.moves.size()-2];
00168 }
00169
00170 if (last_move.isValid()) {
00171 out = "ki2currentinfo ";
00172 out += boost::lexical_cast<std::string>(usi_state.moves.size());
00173 out += " ";
00174 out += record::ki2::show(last_move, current, last_last_move);
00175 } else {
00176 out = "ki2currentinfo";
00177 }
00178 }
00179 #endif
00180
00181 void osl::game_playing::
00182 UsiResponse::isValidPosition(const std::string& line, std::string& out)
00183 {
00184 out = "invalid";
00185 if (line.find("position") == 0) {
00186 try {
00187 SimpleState initial_state;
00188 vector<Move> moves;
00189 record::usi::parse(line.substr(8), initial_state, moves);
00190 out = "valid";
00191 }
00192 catch (std::exception& e) {
00193
00194 }
00195 }
00196 }
00197
00198 bool osl::game_playing::
00199 UsiResponse::hasImmediateResponse(const std::string& command,
00200 std::string& out)
00201 {
00202 if (command.find("genmove_probability") == 0) {
00203 int limit = 2000, value;
00204 std::istringstream is(command.substr(strlen("genmove_probability")));
00205 if (is >> value)
00206 limit = value;
00207 genmoveProbability(limit, out);
00208 return true;
00209 }
00210 if (command.find("genmove") == 0) {
00211 genmove(out);
00212 return true;
00213 }
00214 const NumEffectState state = usi_state.currentState();
00215 if (command.find("csashow") == 0) {
00216 csashow(state, out);
00217 return true;
00218 }
00219 if (command.find("csamove ") == 0) {
00220 csamove(state, command.substr(8), out);
00221 return true;
00222 }
00223 #ifndef MINIMAL
00224 if (command.find("ki2moves ") == 0) {
00225 ki2moves(state, command.substr(9), out);
00226 return true;
00227 }
00228 if (command.find("ki2currentinfo") == 0) {
00229 ki2currentinfo(state, out);
00230 return true;
00231 }
00232 #endif
00233 if (command.find("isvalidposition ") == 0) {
00234 isValidPosition(command.substr(16), out);
00235 return true;
00236 }
00237 if (command.find("echo ") == 0) {
00238 out = command.substr(5);
00239 return true;
00240 }
00241 return false;
00242 }
00243
00244
00245
00246
00247