26 #include <boost/foreach.hpp> 
   33 #  define SAFE_MOVE_ONLY 
   45   if (static_feature_set == 0)
 
   56         &MoveGenerator::generateKingEscape<BLACK>,
 
   57         &MoveGenerator::generateTakeBack<BLACK>,
 
   58         &MoveGenerator::generateBreakThreatmate<BLACK>,
 
   59         &MoveGenerator::generateCapture<BLACK>,
 
   61         &MoveGenerator::generateTesuji<BLACK>,
 
   62         &MoveGenerator::generateAll<BLACK>,
 
   66         &MoveGenerator::generateKingEscape<WHITE>,
 
   67         &MoveGenerator::generateTakeBack<WHITE>,
 
   68         &MoveGenerator::generateBreakThreatmate<WHITE>,
 
   69         &MoveGenerator::generateCapture<WHITE>,
 
   71         &MoveGenerator::generateTesuji<WHITE>,
 
   72         &MoveGenerator::generateAll<WHITE>,
 
   76       "INITIAL", 
"KING_ESCAPE", 
"TAKEBACK", 
"BREAK_THREATMATE", 
"TACTICAL", 
"SENTINEL", 
"TESUJI", 
"ALL", 
 
   78 #ifdef STAT_WIDTH_VS_LIMIT 
   81       CArray<stat::Average,10> averages;
 
   87       stat::Average& average(
int limit) 
 
   94         std::cerr << 
"WidthVSLimit@MoveGenerator\n";
 
   95         for (
int limit=300; limit<300+(int)averages.size()*100; limit+=100) {
 
   96           std::cerr << std::setw(5) << limit << 
" " << average(limit).getAverage() << std::endl;
 
  102     void MoveGenerator::init<osl::eval::ProgressEval>(
 
  104       const NumEffectState&, 
bool in_pv, Move hash_move, 
bool quiesce);
 
  106     void MoveGenerator::init<osl::eval::ml::OpenMidEndingEval>(
 
  107       int limit, 
const SimpleHashRecord *record,
 
  109       const NumEffectState&, 
bool in_pv, Move hash_move, 
bool quiesce);
 
  134   value_t& val = marker(toIndex(m), pieceIndex(state, m));
 
  144   return marker(toIndex(m), pieceIndex(state, m)) == cur;
 
  165 template <
class EvalT>
 
  169                     const NumEffectState& state, 
bool in_pv, 
Move hash_move,
 
  178   cur_index = tried = 0;
 
  179   progress = eval.progress32();
 
  180   eval_suggestion = eval.suggestMove(state);
 
  183   env.make(state, state.pin(state.turn()), state.pin(
alt(state.turn())),
 
  186     marker.registerMove(state, hash_move);
 
  188   in_quiesce = quiesce;
 
  196   std::cerr << 
"generator " << cur_state << 
" index " << cur_index 
 
  197             << 
" limit " << limit << 
" tried " << tried << 
"\n";
 
  198   std::cerr << 
moves.size() << 
"\n" 
  205 template <osl::Player P>
 
  211     assert(cur_index >= 
moves.size());
 
  212     if (cur_state == KING_ESCAPE && record->inCheck()) {
 
  216     if (++cur_state >= TACTICAL_FINISH)
 
  221     if (cur_index < 
moves.size()) {
 
  223       return moves[cur_index++];
 
  229 template <osl::Player P>
 
  235     assert(cur_index >= 
moves.size());
 
  236     if (++cur_state >= FINISH)
 
  241     if (cur_index < 
moves.size()) {
 
  243       return moves[cur_index++];
 
  249 template <osl::Player P>
 
  253   env.history = sstate.
history();
 
  254   if (! record->inCheck()) 
 
  257   const NumEffectState& state = sstate.
state();
 
  258   const Piece king = state.kingPiece<P>();
 
  259   assert(state.hasEffectAt(
alt(P), king.
square()));
 
  263   size_t last = src.size();
 
  264   for (
size_t i=0; i<last; ++i)
 
  265     if (src[i].hasIgnoredUnpromote<P>())
 
  268   if (src.size() == 1) {
 
  272   BOOST_FOREACH(
Move move, src) {
 
  277   moves.sortByProbability();
 
  282 template <osl::Player P>
 
  286   const NumEffectState& state = sstate.
state();
 
  287   const Move threatmate_move = record->threatmate().threatmateMove(state.turn());
 
  292     marker.registerMove(state, move.
move());
 
  295 template <osl::Player P>
 
  299   using namespace move_action;
 
  301   if (! last_move.isNormal())
 
  303   const Square last_to = last_move.to();
 
  305   const NumEffectState& state = sstate.
state();
 
  308     return quiesceCapture<P>(state, last_to);
 
  313   assert(
moves.empty());
 
  314   BOOST_FOREACH(
Move move, src) {
 
  315     assert(! ShouldPromoteCut::canIgnoreMove<P>(move));
 
  319         && env.my_pin.test(state.pieceOnBoard(move.
from()).number())) {
 
  324     if (prob <= 
std::min(200, limit) && marker.registerIfNew(state, move))
 
  327   moves.sortByProbability();
 
  332   template <Player P, Ptype PTYPE>
 
  337     mask_t pieces = state.piecesOnBoard(
alt(P)).template selectBit<PTYPE>() 
 
  348 template <osl::Player P>
 
  354     BOOST_FOREACH(
Move move, src) {
 
  355       assert(!ShouldPromoteCut::canIgnoreMove<P>(move));
 
  356       const int see = PieceEval::computeDiffAfterMoveForRP(state, move);
 
  364   BOOST_FOREACH(
Move move, src) {
 
  365     assert(! ShouldPromoteCut::canIgnoreMove<P>(move));
 
  366 #ifdef SAFE_MOVE_ONLY 
  368         && env.my_pin.test(state.pieceOnBoard(move.
from()).number())) {
 
  375     if (prob <= 200 && marker.registerIfNew(state, move)) {
 
  382 template <osl::Player P>
 
  386   using namespace move_action;
 
  388   const NumEffectState& state = sstate.
state();
 
  392   makeCapture<P,LANCE>(state, src);
 
  393   makeCapture<P,BISHOP>(state, src);
 
  394   makeCapture<P,ROOK>(state, src);
 
  396   makeCapture<P,KNIGHT>(state, src);
 
  397   makeCapture<P,SILVER>(state, src);
 
  398   makeCapture<P,GOLD>(state, src);
 
  400   makeCaptureOtherThanPawn<P>(state, src);
 
  402   addCapture<P>(state, env, src);
 
  405 template <osl::Player P>
 
  409   const NumEffectState& state = sstate.
state();
 
  410   if (! state.inCheck() && eval_suggestion.isNormal()
 
  411       && marker.registerIfNew(state, eval_suggestion)) {
 
  412     assert(sstate.
state().isValidMove(eval_suggestion));
 
  419     makeCapture<P,PAWN>(state, src);
 
  420     addCapture<P>(state, env, src);
 
  426 template <osl::Player P>
 
  433   BOOST_FOREACH(
Move move, moves) {
 
  434     assert(!ShouldPromoteCut::canIgnoreAndNotDrop<P>(move));
 
  435     int see = PieceEval::computeDiffAfterMoveForRP(state, move);
 
  440   this->moves.sortByProbabilityReverse();
 
  444 template <osl::Player P>
 
  452   const NumEffectState& state = sstate.
state();
 
  453   MoveLogProbVector all;
 
  455 #ifdef STAT_WIDTH_VS_LIMIT 
  456   const size_t moves_size_before = 
moves.size();
 
  459     assert(!ShouldPromoteCut::canIgnoreAndNotDrop<P>(move.
move()));
 
  462     if (this->limit >= 400) {
 
  463       using namespace move_classifier;
 
  465           || (in_pv && MoveAdaptor<Check<P> >::isMember(state, move.
move())))
 
  468     if (limit <= this->limit
 
  469         && marker.registerIfNew(state, move.
move())) {
 
  472         assert(! (env.my_pin.test(state.pieceOnBoard(m.
from()).number())
 
  474         assert(! (m.
ptype() == 
KING && state.hasEffectAt(
alt(P), m.
to())));
 
  480 #ifdef STAT_WIDTH_VS_LIMIT 
  481   Width_VS_Limit.average(limit).add(
moves.size() - moves_size_before);
 
  490   assert(
moves.size() == 0);
 
  492   for (
int i=0; i<FINISH; ++i) {
 
  497     bool generated = 
moves.size();
 
  499     if (i == KING_ESCAPE && generated)
 
  506 template <osl::Player P>
 
  508 #if (defined __GNUC__) && (! defined GPSONE) && (! defined GPSUSIONE) 
  514   using namespace move_classifier;
 
  516        m.
validMove(); m = nextTacticalMove<P>(state)) {
 
  517     assert(state.
state().isValidMove(m.move()));
 
  518     if (ConditionAdaptor<SafeMove>::isMember(state.
state(), m.move()))
 
  522        m = nextMove<P>(state)) {
 
  523     assert(state.
state().isValidMove(m.move()));
 
  524     if (ConditionAdaptor<SafeMove>::isMember(state.
state(), m.move()))
 
  533     generateAll<BLACK>(state, 
out);
 
  535     generateAll<WHITE>(state, 
out);