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();