00001 #include "osl/record/kanjiMove.h"
00002 #include "osl/record/kanjiPrint.h"
00003 #include "osl/container/moveVector.h"
00004 #include "osl/move_generator/legalMoves.h"
00005 #include "osl/stl/copy_if.h"
00006 #include <boost/lambda/lambda.hpp>
00007 #include <boost/lambda/bind.hpp>
00008 #include <algorithm>
00009 #include <iterator>
00010 #include <iostream>
00011 using namespace boost::lambda;
00012
00013 const std::string osl::record::KanjiMove::BLACK_SIGN = "";
00014 const std::string osl::record::KanjiMove::WHITE_SIGN = "";
00015
00016 osl::record::
00017 KanjiMove::KanjiMove()
00018 : verbose(false)
00019 {
00020 for (size_t x=1; x<=9; ++x)
00021 {
00022 for (size_t y=1; y<=9; ++y)
00023 {
00024 const std::string str = osl::record::StandardCharacters::suji[x] +
00025 osl::record::StandardCharacters::dan[y];
00026 str2position[str] = osl::Position(x,y);
00027 }
00028 }
00029 str2piece[""] = osl::PAWN;
00030 str2piece[""] = osl::PPAWN;
00031 str2piece[""] = osl::LANCE;
00032 str2piece[""] = osl::PLANCE;
00033 str2piece[""] = osl::KNIGHT;
00034 str2piece[""] = osl::PKNIGHT;
00035 str2piece[""] = osl::SILVER;
00036 str2piece[""] = osl::PSILVER;
00037 str2piece[""] = osl::GOLD;
00038 str2piece[""] = osl::BISHOP;
00039 str2piece[""] = osl::PBISHOP;
00040 str2piece[""] = osl::ROOK;
00041 str2piece["ζ"] = osl::PROOK;
00042 str2piece["ε"] = osl::PROOK;
00043 str2piece[""] = osl::KING;
00044 }
00045
00046 osl::record::
00047 KanjiMove::~KanjiMove()
00048 {
00049 }
00050
00051 #if ! (__GNUC__ >= 4 && __GNUC_MINOR__ >=3)
00052 void osl::record::
00053 KanjiMove::selectCandidates(found_moves_t& found,
00054 std::string& str,
00055 const osl::Position& to_pos,
00056 const osl::Player& player) const
00057 {
00058 assert(!str.empty());
00059 assert(found.size() >= 2);
00060
00061 if ( (str.substr(0,2) == "" && player == osl::BLACK) ||
00062 (str.substr(0,2) == "" && player == osl::WHITE) )
00063 {
00064 found.sort(
00065 bind(&osl::Position::x, bind(&osl::Move::from, _1)) <
00066 bind(&osl::Position::x, bind(&osl::Move::from, _2)) );
00067 const osl::Move min = found.front();
00068 found.remove_if(
00069 bind(&osl::Position::x, bind(&osl::Move::from, _1)) > min.from().x()
00070 );
00071 }
00072 else if ( (str.substr(0,2) == "" && player == osl::BLACK) ||
00073 (str.substr(0,2) == "" && player == osl::WHITE) )
00074 {
00075 found.sort(
00076 bind(&osl::Position::x, bind(&osl::Move::from, _1)) <
00077 bind(&osl::Position::x, bind(&osl::Move::from, _2)) );
00078 const osl::Move max = found.back();
00079 found.remove_if(
00080 bind(&osl::Position::x, bind(&osl::Move::from, _1)) < max.from().x()
00081 );
00082 }
00083 else if ( (str.substr(0,2) == "" && player == osl::BLACK) ||
00084 (str.substr(0,2) == "" && player == osl::WHITE) )
00085 {
00086 found.sort(
00087 bind(&osl::Position::y, bind(&osl::Move::from, _1)) <
00088 bind(&osl::Position::y, bind(&osl::Move::from, _2)) );
00089 const osl::Move min = found.front();
00090 found.remove_if(
00091 bind(&osl::Position::y, bind(&osl::Move::from, _1)) > min.from().y()
00092 );
00093 }
00094 else if ( (str.substr(0,2) == "" && player == osl::BLACK) ||
00095 (str.substr(0,2) == "" && player == osl::WHITE) )
00096 {
00097 found.sort(
00098 bind(&osl::Position::y, bind(&osl::Move::from, _1)) >
00099 bind(&osl::Position::y, bind(&osl::Move::from, _2)) );
00100 const osl::Move max = found.front();
00101 found.remove_if(
00102 bind(&osl::Position::y, bind(&osl::Move::from, _1)) < max.from().y()
00103 );
00104 }
00105 else if (str.substr(0,2) == "")
00106 {
00107 found.remove_if(
00108 bind(&osl::Position::y, bind(&osl::Move::from, _1)) != to_pos.y()
00109 );
00110 }
00111 else if (str.substr(0,2) == "ľ" && player == osl::WHITE)
00112 {
00113 found.remove_if(
00114 bind(&osl::Position::x, bind(&osl::Move::from, _1)) != to_pos.x() ||
00115 bind(&osl::Position::y, bind(&osl::Move::from, _1)) + 1 != to_pos.y()
00116 );
00117 }
00118 else if (str.substr(0,2) == "ľ" && player == osl::BLACK)
00119
00120 {
00121 found.remove_if(
00122 bind(&osl::Position::x, bind(&osl::Move::from, _1)) != to_pos.x() ||
00123 bind(&osl::Position::y, bind(&osl::Move::from, _1)) - 1 != to_pos.y()
00124 );
00125 }
00126 else if (str.substr(0,2) == "" && player == osl::BLACK)
00127 {
00128 found.remove_if(
00129 bind(&osl::Position::y, bind(&osl::Move::from, _1)) >= to_pos.y()
00130 );
00131 }
00132 else if (str.substr(0,2) == "" && player == osl::WHITE)
00133 {
00134 found.remove_if(
00135 bind(&osl::Position::y, bind(&osl::Move::from, _1)) <= to_pos.y()
00136 );
00137 }
00138 else if (str.substr(0,2) == "" && player == osl::BLACK)
00139 {
00140 found.remove_if(
00141 bind(&osl::Position::y, bind(&osl::Move::from, _1)) <= to_pos.y()
00142 );
00143 }
00144 else if (str.substr(0,2) == "" && player == osl::WHITE)
00145 {
00146 found.remove_if(
00147 bind(&osl::Position::y, bind(&osl::Move::from, _1)) >= to_pos.y()
00148 );
00149 }
00150
00151 str.erase(0,2);
00152 assert(!found.empty());
00153
00154 if (found.size() > 1)
00155 {
00156 assert(!str.empty());
00157 selectCandidates(found, str, to_pos, player);
00158 }
00159
00160 assert(found.size() == 1);
00161 if (!str.empty())
00162 std::cerr << "WARNING: A single candidate is selected, but the input string still has some characters: " << str << std::endl;
00163 }
00164
00165 const osl::Move osl::record::
00166 KanjiMove::strToMove(const std::string& orig,
00167 const osl::NumEffectState& state,
00168 const osl::Move& last_move) const
00169 {
00170 std::string str(orig);
00171 assert(orig.size() >= 4*2);
00172 const osl::Player player = str.substr(0,2) == BLACK_SIGN ? osl::BLACK : osl::WHITE;
00173 assert(player == state.getTurn());
00174 str.erase(0,2);
00175
00176 osl::Position to_pos;
00177 if (str.substr(0,2) == "Ʊ")
00178 {
00179 to_pos = last_move.to();
00180 str.erase(0,2);
00181 if (str.substr(0,2) == "")
00182 str.erase(0,2);
00183 }
00184 else
00185 {
00186 to_pos = str2position[str.substr(0,4)];
00187 str.erase(0,4);
00188 }
00189
00190 osl::Ptype ptype;
00191 if (str.substr(0,2) == "")
00192 {
00193 ptype = str2piece[str.substr(0,4)];
00194 str.erase(0,4);
00195 }
00196 else
00197 {
00198 ptype = str2piece[str.substr(0,2)];
00199 str.erase(0,2);
00200 }
00201
00202
00203 bool is_promote = false;
00204 if (str.size() >= 4 && str.substr(0,4) == "")
00205 str.erase(0,4);
00206 else if (str.size() >= 4 && str.substr(str.size()-4,4) == "")
00207 str.erase(str.size()-4,4);
00208 else if (str.size() >= 2 && str.substr(0,2) == "")
00209 {
00210 is_promote = true;
00211 str.erase(0,2);
00212 }
00213 else if (str.size() >= 2 && str.substr(str.size()-2,2) == "")
00214 {
00215 is_promote = true;
00216 str.erase(str.size()-2,2);
00217 }
00218
00219 osl::MoveVector moves;
00220 osl::LegalMoves::generate(state, moves);
00221 found_moves_t found;
00222 std::back_insert_iterator<found_moves_t> bii(found);
00223 osl::stl::copy_if(moves.begin(), moves.end(), bii,
00224 bind(&osl::Move::oldPtype, _1) == ptype &&
00225 bind(&osl::Move::to, _1) == to_pos &&
00226 bind(&osl::Move::isPromote, _1) == is_promote
00227 );
00228 if (verbose)
00229 {
00230 std::cerr << "\n" << orig << "\n" << state;
00231 std::cerr << "remain: " << str << " (" << str.size() << " bytes)\n";
00232 std::cerr << "promote: " << is_promote << "\n";
00233 std::cerr << "ptype: " << "\n";
00234 std::cerr << "to_position: " << to_pos << "\n";
00235 std::cerr << "candidates: " << found.size() << std::endl;
00236 }
00237 assert(!found.empty());
00238
00239
00240 if (found.size() == 1)
00241 return found.front();
00242
00243
00244 assert(found.size() >= 2);
00245
00246
00247 if (str.substr(0,2) == "")
00248 {
00249 found_moves_t::iterator it =
00250 std::find_if(found.begin(), found.end(),
00251 bind(&osl::Move::isDrop, _1) == true
00252 );
00253 str.erase(0,2);
00254 assert(str.empty());
00255 assert(it != found.end());
00256 return *it;
00257 }
00258 else
00259 {
00260 found.remove_if(
00261 bind(&osl::Move::isDrop, _1) == true
00262 );
00263 if (found.size() == 1)
00264 return found.front();
00265 }
00266
00267
00268 assert(found.size() >= 2);
00269 assert(!str.empty());
00270 selectCandidates(found, str, to_pos, player);
00271 assert(found.size() == 1);
00272 return found.front();
00273 }
00274 #endif