8 #include <boost/foreach.hpp> 
    9 #include <boost/mem_fn.hpp> 
   10 #include <boost/lambda/lambda.hpp> 
   11 #include <boost/lambda/bind.hpp> 
   15 using namespace boost::lambda;
 
   31 struct SortMoveFromX : 
 
   32   public std::binary_function<osl::Move, osl::Move, bool>
 
   38     return a_p.
x() < b_p.
x();
 
   42 struct SortMoveFromXDesc :
 
   43   public std::binary_function<osl::Move, osl::Move, bool>
 
   49     return a_p.
x() > b_p.
x();
 
   53 struct SortMoveFromY :
 
   54   public std::binary_function<osl::Move, osl::Move, bool>
 
   60     return a_p.
y() < b_p.
y();
 
   64 struct SortMoveFromYDesc :
 
   65   public std::binary_function<osl::Move, osl::Move, bool>
 
   71     return a_p.
y() > b_p.
y();
 
   75 struct RemoveMoveFromXOver :
 
   76   public std::unary_function<osl::Move, bool>
 
   79   RemoveMoveFromXOver(
const int min_x)
 
   90 struct RemoveMoveFromXGTE :
 
   91   public std::unary_function<osl::Move, bool>
 
   94   RemoveMoveFromXGTE(
const int min_x)
 
  101     return p.
x() >= min_x;
 
  105 struct RemoveMoveFromYOver :
 
  106   public std::unary_function<osl::Move, bool>
 
  109   RemoveMoveFromYOver(
const int min_y)
 
  113   bool operator()(
const osl::Move& m)
 const 
  116     return p.
y() > min_y;
 
  120 struct RemoveMoveFromYGTE :
 
  121   public std::unary_function<osl::Move, bool>
 
  124   RemoveMoveFromYGTE(
const int min_y)
 
  128   bool operator()(
const osl::Move& m)
 const 
  131     return p.
y() >= min_y;
 
  135 struct RemoveMoveFromXUnder :
 
  136   public std::unary_function<osl::Move, bool>
 
  139   RemoveMoveFromXUnder(
const int max_x)
 
  143   bool operator()(
const osl::Move& m)
 const 
  146     return p.
x() < max_x;
 
  150 struct RemoveMoveFromXLTE :
 
  151   public std::unary_function<osl::Move, bool>
 
  154   RemoveMoveFromXLTE(
const int max_x)
 
  158   bool operator()(
const osl::Move& m)
 const 
  161     return p.
x() <= max_x;
 
  165 struct RemoveMoveFromYUnder :
 
  166   public std::unary_function<osl::Move, bool>
 
  169   RemoveMoveFromYUnder(
const int max_y)
 
  173   bool operator()(
const osl::Move& m)
 const 
  176     return p.
y() < max_y;
 
  180 struct RemoveMoveFromYLTE :
 
  181   public std::unary_function<osl::Move, bool>
 
  184   RemoveMoveFromYLTE(
const int max_y)
 
  188   bool operator()(
const osl::Move& m)
 const 
  191     return p.
y() <= max_y;
 
  195 struct RemoveMoveFromXEqual :
 
  196   public std::unary_function<osl::Move, bool>
 
  199   RemoveMoveFromXEqual(
const int x)
 
  203   bool operator()(
const osl::Move& m)
 const 
  210 struct RemoveMoveFromYEqual :
 
  211   public std::unary_function<osl::Move, bool>
 
  214   RemoveMoveFromYEqual(
const int y)
 
  218   bool operator()(
const osl::Move& m)
 const 
  230   for (
size_t x=1; x<=9; ++x)
 
  232     for (
size_t y=1; y<=9; ++y)
 
  270   str2position_t::const_iterator p=str2position.find(s);
 
  271   if (p == str2position.end())
 
  279   str2piece_t::const_iterator p=str2piece.find(s);
 
  280   if (p == str2piece.end())
 
  291   assert(!str.empty());
 
  292   assert(found.size() >= 2);
 
  294   if ( (str.substr(0,2) == 
K_MIGI && player == 
BLACK) ||
 
  297     found.sort( bind(moveFromX, boost::lambda::_1) < bind(moveFromX, boost::lambda::_2) );
 
  299     found.remove_if( RemoveMoveFromXOver(min.
from().
x()) ); 
 
  301   else if ( (str.substr(0,2) == 
K_HIDARI && player == 
BLACK) || 
 
  304     found.sort( bind(moveFromX, boost::lambda::_1) < bind(moveFromX, boost::lambda::_2) );
 
  306     found.remove_if( RemoveMoveFromXUnder(max.
from().
x()) ); 
 
  308   else if ( (str.substr(0,2) == 
K_SHITA && player == 
BLACK) || 
 
  309             (str.substr(0,2) == 
K_UE    && player == 
WHITE) )
 
  311     found.sort( bind(moveFromY, boost::lambda::_1) < bind(moveFromY, boost::lambda::_2) );
 
  312     const Move min = found.front();
 
  313     found.remove_if( RemoveMoveFromYOver(min.
from().
y()) ); 
 
  315   else if ( (str.substr(0,2) == 
K_UE    && player == 
BLACK) || 
 
  318     found.sort( bind(moveFromY, boost::lambda::_1) > bind(moveFromY, boost::lambda::_2) );
 
  319     const Move max = found.front();
 
  320     found.remove_if( RemoveMoveFromYUnder(max.
from().
y()) ); 
 
  322   else if (str.substr(0,2) == 
K_YORU)
 
  324     found.remove_if( std::not1(RemoveMoveFromYEqual(to_pos.
y())) ); 
 
  326   else if (str.substr(0,2) == 
K_SUGU && player == 
WHITE)
 
  328     found.remove_if( std::not1(RemoveMoveFromXEqual(to_pos.
x())) ); 
 
  329     found.remove_if( std::not1(RemoveMoveFromYEqual(to_pos.
y()-1)) ); 
 
  331   else if (str.substr(0,2) == 
K_SUGU && player == 
BLACK)
 
  334     found.remove_if( std::not1(RemoveMoveFromXEqual(to_pos.
x())) ); 
 
  335     found.remove_if( std::not1(RemoveMoveFromYEqual(to_pos.
y()+1)) ); 
 
  337   else if (str.substr(0,2) == 
K_HIKU && player == 
BLACK)
 
  339     found.remove_if( RemoveMoveFromYGTE(to_pos.
y()) ); 
 
  341   else if (str.substr(0,2) == 
K_HIKU && player == 
WHITE)
 
  343     found.remove_if( RemoveMoveFromYLTE(to_pos.
y()) ); 
 
  345   else if (str.substr(0,2) == 
K_YUKU && player == 
BLACK)
 
  347     found.remove_if( RemoveMoveFromYLTE(to_pos.
y()) ); 
 
  349   else if (str.substr(0,2) == 
K_YUKU && player == 
WHITE)
 
  351     found.remove_if( RemoveMoveFromYGTE(to_pos.
y()) ); 
 
  355   assert(!found.empty());
 
  357   if (found.size() > 1)
 
  359     assert(!str.empty());
 
  360     selectCandidates(found, str, to_pos, player);
 
  363   assert(found.size() == 1);
 
  365     std::cerr << 
"WARNING: A single candidate is selected, but the input string still has some characters: " << 
misc::eucToLang(str) << std::endl;
 
  370                      const osl::NumEffectState& state, 
 
  373   std::string str(orig);
 
  376   assert(str.size() >= 4*2
 
  377          || (str.size() >= 3*2
 
  379                  || (isdigit(str[2]) && isdigit(str[3])))));
 
  381   assert(player == state.turn());
 
  385   if (str.substr(0,2) == 
K_ONAZI)
 
  387     to_pos = last_move.
to();
 
  389     if (str.substr(0,2) == 
K_SPACE)
 
  392   else if (isdigit(str[0]) && isdigit(str[1]))
 
  394     to_pos = 
Square(str[0]-
'0', str[1]-
'0');
 
  399     to_pos = toSquare(str.substr(0,4));
 
  404   if (str.substr(0,2) == 
K_NARU) 
 
  406     ptype = toPtype(str.substr(0,4));
 
  411     ptype = toPtype(str.substr(0,2));
 
  416   bool is_promote = 
false;
 
  417   if (str.size() >= 4 && str.substr(0,4) == 
K_FUNARI)
 
  419   else if (str.size() >= 4 && str.substr(str.size()-4,4) == 
K_FUNARI)
 
  420     str.erase(str.size()-4,4);
 
  421   else if (str.size() >= 2 && str.substr(0,2) == 
K_NARU)
 
  426   else if (str.size() >= 2 && str.substr(str.size()-2,2) == 
K_NARU)
 
  429     str.erase(str.size()-2,2);
 
  433   LegalMoves::generateWithFullUnpromotions(state, moves);
 
  435   BOOST_FOREACH(
Move move, moves)
 
  438         move.
to()        == to_pos &&
 
  442       if (
std::find(found.begin(), found.end(), move) == found.end())
 
  443         found.push_back(move);
 
  448     std::cerr << 
"\n" << orig << 
"\n" << state;
 
  449     std::cerr << 
"remain: " << str  << 
" (" << str.size() << 
" bytes)\n";
 
  450     std::cerr << 
"promote: " << is_promote << 
"\n";
 
  451     std::cerr << 
"ptype: " << ptype << 
"\n";
 
  452     std::cerr << 
"to_position: " << to_pos << 
"\n";
 
  453     std::cerr << 
"candidates: " << found.size() << std::endl;
 
  454     if (found.size() >=2) {
 
  455       BOOST_FOREACH(
const Move move, found) {
 
  456         std::cerr << 
"            " << move << std::endl;
 
  464   assert(!found.empty());
 
  467   if (found.size() == 1)
 
  468     return found.front();
 
  471   assert(found.size() >= 2);
 
  474   if (str.substr(0,2) == 
K_UTSU)
 
  476     found_moves_t::iterator it = 
 
  477       std::find_if(found.begin(), found.end(),
 
  482     assert(it != found.end());
 
  490     if (found.size() == 1)
 
  491       return found.front();
 
  495   assert(found.size() >= 2);
 
  498   assert(!str.empty());
 
  499   selectCandidates(found, str, to_pos, player);
 
  500   assert(found.size() == 1);
 
  501   return found.front();