00001
00002
00003 #ifndef _CHECKMOVEGENERATOR_TCC
00004 #define _CHECKMOVEGENERATOR_TCC
00005
00006 #include "osl/checkmate/checkMoveGenerator.h"
00007 #include "osl/checkmate/checkMoveList.h"
00008 #include "osl/checkmate/checkMoveListProvider.h"
00009 #include "osl/checkmate/checkAssert.h"
00010 #include "osl/checkmate/pawnCheckmateMoves.h"
00011 #include "osl/move_generator/escape_.h"
00012 #include "osl/move_generator/addEffect_.h"
00013 #include "osl/move_action/store.h"
00014 #include "osl/move_action/safeFilter.h"
00015 #include "osl/move_action/checkFilter.h"
00016 #include "osl/move_classifier/check_.h"
00017 #include "osl/move_classifier/moveAdaptor.h"
00018 #include "osl/move_classifier/pawnDropCheckmate.h"
00019 #include "osl/container/moveVector.h"
00020 #include <cassert>
00021
00022
00023
00024 template <osl::Player P>
00025 void osl::checkmate::CheckMoveGenerator<P>::
00026 generateAttack(const NumEffectState& state, CheckMoveListProvider& src,
00027 CheckMoveList& out, Move last_move)
00028 {
00029 using namespace move_classifier;
00030 check_assert(out.empty());
00031 const Position targetKing
00032 = state.template getKingPosition<PlayerTraits<P>::opponent>();
00033 Piece attackerPiece;
00034 const bool counter_check =
00035 state.template lastMoveIsCheck<P>(last_move, attackerPiece);
00036 MoveVector moves;
00037 {
00038 if (counter_check)
00039 {
00040 #if 0
00041
00042 move_action::Store store(moves);
00043 typedef move_action::CheckFilter<P,NumEffectState,move_action::Store> check_filter_t;
00044 check_filter_t checkFilter(state,store);
00045 move_generator::Escape<P,NumEffectState,check_filter_t>::
00046 generateKingEscape(state, last_move, checkFilter);
00047 #else
00048 MoveVector escape;
00049 move_action::Store store(escape);
00050 move_generator::Escape<P,NumEffectState,move_action::Store>::
00051 generateKingEscape(state, last_move, store);
00052 for (size_t i=0; i<escape.size(); ++i)
00053 {
00054 if (MoveAdaptor<Check<P> >::isMember(state, escape[i]))
00055 moves.push_back(escape[i]);
00056 }
00057 #endif
00058 }
00059 else
00060 {
00061 move_action::Store store(moves);
00062 typedef move_action::SafeFilter<P,NumEffectState,move_action::Store> safe_filter_t;
00063 safe_filter_t safeFilter(state,store);
00064 move_generator::AddEffect<P,true>::generate
00065 (state,targetKing,safeFilter);
00066 }
00067 }
00068
00069 out.setSize(moves.size(), src);
00070 for (size_t i=0; i<moves.size(); ++i)
00071 {
00072 CheckMove new_move(moves[i]);
00073 const Position from = moves[i].from();
00074 if (! from.isPieceStand())
00075 {
00076 const Ptype ptype = moves[i].ptype();
00077 const Position to = moves[i].to();
00078
00079 #ifdef PAWN_CHECKMATE_SENSITIVE
00080 if (PawnCheckmateMoves::effectiveOnlyIfPawnCheckmate<P>(ptype, from, to))
00081 {
00082 new_move.flags = MoveFlags::NoPromote;
00083 }
00084 #endif
00085 }
00086 #ifdef DELAY_SACRIFICE
00087 const Position to = moves[i].to();
00088 const Ptype capturePtype = moves[i].capturePtype();
00089 if (capturePtype == PTYPE_EMPTY)
00090 {
00091 const int defense = state.countEffect(alt(P),to);
00092 int offense = state.countEffect(P,to);
00093 if (from.isPieceStand())
00094 --offense;
00095 if (defense > offense)
00096 {
00097 new_move.flags.set(MoveFlags::SacrificeAttack);
00098 }
00099 }
00100 #endif
00101 check_assert(std::find(moves.begin(), moves.begin()+=i, moves[i])
00102 == (moves.begin()+=i));
00103 out[i] = new_move;
00104 }
00105 }
00106
00107 namespace osl
00108 {
00109 namespace checkmate
00110 {
00111 template <class NumEffectState>
00112 Ptype getCheapestDrop(Player turn, const NumEffectState& state)
00113 {
00114 if (state.hasPieceOnStand(turn, PAWN))
00115 return PAWN;
00116 if (state.hasPieceOnStand(turn, LANCE))
00117 return LANCE;
00118 if (state.hasPieceOnStand(turn, KNIGHT))
00119 return KNIGHT;
00120 if (state.hasPieceOnStand(turn, SILVER))
00121 return SILVER;
00122 if (state.hasPieceOnStand(turn, GOLD))
00123 return GOLD;
00124 if (state.hasPieceOnStand(turn, BISHOP))
00125 return BISHOP;
00126 if (state.hasPieceOnStand(turn, ROOK))
00127 return ROOK;
00128 return PTYPE_EMPTY;
00129 }
00130 template <class NumEffectState>
00131 Ptype getSecondCheapestDrop(Player turn, const NumEffectState& state,
00132 Ptype cheapest)
00133 {
00134 if (cheapest == PAWN)
00135 {
00136 if (state.hasPieceOnStand(turn, LANCE))
00137 return LANCE;
00138 if (state.hasPieceOnStand(turn, KNIGHT))
00139 return KNIGHT;
00140 if (state.hasPieceOnStand(turn, SILVER))
00141 return SILVER;
00142 if (state.hasPieceOnStand(turn, GOLD))
00143 return GOLD;
00144 if (state.hasPieceOnStand(turn, BISHOP))
00145 return BISHOP;
00146 if (state.hasPieceOnStand(turn, ROOK))
00147 return ROOK;
00148 }
00149 return PTYPE_EMPTY;
00150 }
00151 }
00152 }
00153
00154 template <osl::Player P>
00155 unsigned int osl::checkmate::CheckMoveGenerator<P>::
00156 generateEscape(const NumEffectState& state, CheckMoveListProvider& src,
00157 CheckMoveList& out, Move last_move)
00158 {
00159 using namespace move_classifier;
00160 const Player Defense = PlayerTraits<P>::opponent;
00161
00162 unsigned int simple_king_moves = 0;
00163
00164 MoveVector moves;
00165 {
00166 move_action::Store store(moves);
00167 move_generator::Escape<Defense,NumEffectState,move_action::Store>::
00168 generateKingEscape(state, last_move, store);
00169 }
00170 assert(out.empty());
00171 out.setSize(moves.size(), src);
00172 #ifdef DELAY_INTERPOSE
00173 const Ptype cheapest = getCheapestDrop(alt(P), state);
00174 const Ptype secondCheapest = getSecondCheapestDrop(alt(P), state, cheapest);
00175 #endif
00176 size_t num_output = 0;
00177 for (size_t i=0; i<moves.size(); ++i)
00178 {
00179 const Move m = moves[i];
00180 CheckMove cm(m);
00181 const Position to = m.to();
00182 const Position from = m.from();
00183 const Ptype ptype = m.ptype();
00184 if (from.isPieceStand())
00185 {
00186 if (PawnDropCheckmate<Defense>::isMember(state, ptype, from, to))
00187 continue;
00188 #ifdef DELAY_INTERPOSE
00189 if (((ptype != cheapest)
00190 && (ptype != secondCheapest))
00191 || ((! state.hasEffectBy(alt(P), to))
00192 && (! state.hasMultipleEffectBy(P, to))))
00193 cm.flags = MoveFlags::BlockingBySacrifice;
00194 #endif
00195 }
00196 else
00197 {
00198 assert(move_classifier::SafeMove<PlayerTraits<P>::opponent>
00199 ::isMember(state, ptype, from, to));
00200 #ifdef DELAY_INTERPOSE
00201 if ((ptype != KING)
00202 && (m.capturePtype() == PTYPE_EMPTY)
00203 && (! state.hasMultipleEffectBy(alt(P), to)))
00204 {
00205
00206 cm.flags = MoveFlags::BlockingBySacrifice;
00207 }
00208 #endif
00209 if (ptype == KING && m.capturePtype() == PTYPE_EMPTY)
00210 ++simple_king_moves;
00211 }
00212 out[num_output++] = cm;
00213 }
00214 out.shrinkSize(num_output);
00215 return simple_king_moves;
00216 }
00217
00218 #endif
00219
00220
00221
00222