00001
00002
00003 #include "osl/ntesuki/ntesukiMoveGenerator.h"
00004 #include "osl/state/numEffectState.h"
00005 #include "osl/effect_util/neighboring8Direct.h"
00006 #include "osl/effect_util/neighboring25Direct.h"
00007 #include "osl/move_classifier/canAttackInNMoves.h"
00008 #include "osl/move_classifier/moveAdaptor.h"
00009 #include "osl/move_classifier/safeMove.h"
00010 #include "osl/move_classifier/check.h"
00011 #include "osl/move_generator/escape.h"
00012 #include "osl/move_generator/legalMoves.h"
00013 #include "osl/move_generator/addEffect.h"
00014 #include "osl/move_generator/addEffect.tcc"
00015 #include "osl/move_generator/addEffect8.h"
00016 #include "osl/move_generator/kingWalk.h"
00017 #include "osl/move_generator/drop.h"
00018 #include "osl/move_generator/dropAroundKing8.h"
00019 #include "osl/move_generator/openKingRoad.h"
00020 #include "osl/move_generator/capture.h"
00021 #include "osl/move_generator/capture.tcc"
00022 #include "osl/move_generator/captureEffectToAroundKing8.h"
00023 #include "osl/move_action/store.h"
00024 #include "osl/move_action/safeFilter.h"
00025 #include <iostream>
00026
00027
00028
00029
00030
00031 namespace osl
00032 {
00033 namespace ntesuki
00034 {
00035
00036
00037
00038
00039 static
00040 bool
00041 hasEffectByBigPieces (const NumEffectState& state,
00042 const Player player,
00043 const Position pos)
00044 {
00045 #if OSL_WORDSIZE == 64
00046 const PieceMask bigPieceMask (container::PieceMaskBase(
00047 PieceMask::numToMask (PtypeTraits<ROOK>::indexMin)
00048 | PieceMask::numToMask (PtypeTraits<ROOK>::indexMin + 1)
00049 | PieceMask::numToMask (PtypeTraits<BISHOP>::indexMin)
00050 | PieceMask::numToMask (PtypeTraits<BISHOP>::indexMin + 1)));
00051
00052 const PieceMask pieceMask = (state.getOnBoardMask (player)
00053 & state.getEffect (pos)
00054 & bigPieceMask);
00055 return pieceMask.any();
00056 #elif OSL_WORDSIZE == 32
00057
00058
00059 PieceMask bigPieceMask;
00060 bigPieceMask.set(PtypeTraits<ROOK>::indexMin);
00061 bigPieceMask.set(PtypeTraits<ROOK>::indexMin + 1);
00062 bigPieceMask.set(PtypeTraits<BISHOP>::indexMin);
00063 bigPieceMask.set(PtypeTraits<BISHOP>::indexMin + 1);
00064 const PieceMask pieceMask = (state.getOnBoardMask (player)
00065 & state.getEffect (pos)
00066 & bigPieceMask);
00067 return pieceMask.any();
00068 #endif
00069 }
00070
00071 template <Player P>
00072 static
00073 void
00074 getCheckMoves (const NumEffectState& state, MoveVector& moves)
00075 {
00076 using namespace move_classifier;
00077
00078 const Position targetKing
00079 = state.getKingPosition<PlayerTraits<P>::opponent>();
00080
00081 move_action::Store store(moves);
00082 move_action::SafeFilter<P, state::NumEffectState, move_action::Store> store_safe(state, store);
00083 move_generator::AddEffect<P, true>::generate(state, targetKing, store_safe);
00084 }
00085
00086 template <Player P>
00087 struct CaptureHelper
00088 {
00089 CaptureHelper(const NumEffectState& state,
00090 move_action::Store& action)
00091 : state(state), action(action)
00092 {
00093 }
00094
00095 void operator()(Piece p)
00096 {
00097 move_generator::GenerateCapture::generate(P,state, p.position(), action);
00098 }
00099 private:
00100 const NumEffectState& state;
00101 move_action::Store& action;
00102 };
00103
00104 template <Player P, Ptype T>
00105 static
00106 void
00107 capture(const NumEffectState& state, move_action::Store action)
00108 {
00109 CaptureHelper<P> captureHelper(state, action);
00110 state.forEachOnBoard<PlayerTraits<P>::opponent, T, CaptureHelper<P> >(captureHelper);
00111 }
00112
00113
00114
00115
00116
00117
00118
00119 GetAllAttackMoves::GetAllAttackMoves(bool verbose)
00120 : NtesukiAttackMoveGenerator(verbose) {}
00121 GetAllAttackMoves::~GetAllAttackMoves() {}
00122 template <Player P>
00123 void GetAllAttackMoves::
00124 generate(const NumEffectState& state,
00125 NtesukiMoveList& moves)
00126 {
00127 MoveVector move_candidates;
00128 LegalMoves::generate(state, move_candidates);
00129 moves = NtesukiMoveList(state, move_candidates);
00130 }
00131 template void GetAllAttackMoves::generate<BLACK>(const NumEffectState& state,
00132 NtesukiMoveList& moves);
00133 template void GetAllAttackMoves::generate<WHITE>(const NumEffectState& state,
00134 NtesukiMoveList& moves);
00135
00136
00137
00138 GetAttackMoves::GetAttackMoves(bool verbose)
00139 : NtesukiAttackMoveGenerator(verbose) {}
00140 GetAttackMoves::~GetAttackMoves() {}
00141 template <Player P>
00142 void GetAttackMoves::
00143 generate(const NumEffectState& state,
00144 NtesukiMoveList& moves)
00145 {
00146 #if 0
00147 const Position pos = state.template getKingPosition<P>();
00148 const bool check = state.hasEffectBy(PlayerTraits<P>::opponent, pos);
00149
00150 if (check)
00151 {
00152 MoveVector move_candidates;
00153 GenerateEscapeKing::generate(state, move_candidates);
00154 moves = NtesukiMoveList(state, move_candidates);
00155 return;
00156 }
00157
00158 MoveVector check_candidates;
00159 getCheckMoves<P>(state, check_candidates);
00160
00161 MoveVector move_candidates;
00162 move_action::Store store(move_candidates);
00163
00164 move_generator::AddEffect8<P>::generate(state, store);
00165 capture<P, ROOK>(state, store);
00166 capture<P, BISHOP>(state, store);
00167 capture<P, GOLD>(state, store);
00168 capture<P, SILVER>(state, store);
00169 capture<P, KNIGHT>(state, store);
00170 capture<P, LANCE>(state, store);
00171
00172
00173 size_t deleted = 0;
00174 for (size_t i = 0; i < move_candidates.size(); ++i)
00175 {
00176 const Move m = move_candidates[i];
00177 if (check_candidates.isMember(move_candidates[i])
00178 || (m.from() != Position::STAND() &&
00179 !move_classifier::SafeMove<P>::isMember(state,
00180 m.ptype(),
00181 m.from(),
00182 m.to())))
00183 {
00184 ++deleted;
00185 move_candidates[i] = Move::INVALID();
00186 }
00187 }
00188
00189 for (size_t i = 0; i < move_candidates.size(); ++i)
00190 {
00191 if (move_candidates[i] == Move::INVALID()) continue;
00192
00193 {
00194 ntesuki_assert(!move_classifier::
00195 PlayerMoveAdaptor<move_classifier::Check>::
00196 isMember(state, move_candidates[i])
00197 || (std::cerr << std::endl
00198 << state
00199 << check_candidates << std::endl
00200 << move_candidates << std::endl,
00201 0));
00202 }
00203
00204 moves.push_front(NtesukiMove(move_candidates[i], NtesukiMove::NONE));
00205 }
00206 for (size_t i = 0; i < check_candidates.size(); ++i)
00207 {
00208 moves.push_front(NtesukiMove(check_candidates[i], NtesukiMove::CHECK_FLAG));
00209 }
00210
00211 #else
00212 MoveVector all_moves;
00213 MoveVector move_candidates;
00214 LegalMoves::generate(state, all_moves);
00215
00216 const Position opKingPosition =
00217 state.getKingPosition (alt(state.getTurn ()));
00218
00219 for (unsigned int i=0; i<all_moves.size(); ++i)
00220 {
00221 const Move m = all_moves[i];
00222
00223
00224
00225
00226
00227
00228
00229 const Position from = m.from();
00230
00231 if (Neighboring25Direct::hasEffect(state, m.ptypeO(), m.to(),
00232 opKingPosition))
00233 {
00234 move_candidates.push_back(m);
00235 }
00236 else if (hasEffectByBigPieces (state, state.getTurn (), from))
00237 {
00238 move_candidates.push_back(m);
00239 }
00240 else
00241 {
00242 const Position to = m.to();
00243 const Piece atTo = state.getPieceOnBoard (to);
00244
00245 if ((atTo.isPiece())
00246 && (atTo.owner() == alt (state.getTurn ())))
00247 {
00248 move_candidates.push_back(m);
00249 }
00250 }
00251 }
00252 moves = NtesukiMoveList(state, move_candidates);
00253 #endif
00254 }
00255 template void GetAttackMoves::generate<BLACK>(const NumEffectState& state,
00256 NtesukiMoveList& moves);
00257 template void GetAttackMoves::generate<WHITE>(const NumEffectState& state,
00258 NtesukiMoveList& moves);
00259
00260
00261
00262 GetMultipleAttackMoves::GetMultipleAttackMoves(bool verbose)
00263 : NtesukiAttackMoveGenerator(verbose) {}
00264 GetMultipleAttackMoves::~GetMultipleAttackMoves() {}
00265 template <Player P>
00266 void GetMultipleAttackMoves::
00267 generate(const NumEffectState& state,
00268 NtesukiMoveList& moves)
00269 {
00270 assert (state.getTurn() == P);
00271 MoveVector all_moves;
00272 MoveVector move_candidates;
00273 LegalMoves::generate(state, all_moves);
00274
00275 const Position opKingPosition =
00276 state.getKingPosition (alt(state.getTurn ()));
00277
00278 for (unsigned int i=0; i<all_moves.size(); ++i)
00279 {
00280 const Move m = all_moves[i];
00281 const Position from = m.from();
00282
00283 if (move_classifier::canAttackInThreeMoves (m.player(),
00284 m.ptype(),
00285 m.to(),
00286 opKingPosition))
00287 {
00288 move_candidates.push_back(m);
00289 }
00290 else if (hasEffectByBigPieces (state, state.getTurn (), from))
00291 {
00292 move_candidates.push_back(m);
00293 }
00294 else
00295 {
00296 const Position to = m.to();
00297 const Piece atTo = state.getPieceOnBoard (to);
00298 if (atTo.isPiece()
00299 && (atTo.owner() == alt (state.getTurn ())))
00300 {
00301 move_candidates.push_back(m);
00302 }
00303 }
00304 }
00305 moves = NtesukiMoveList(state, move_candidates);
00306 }
00307 template void GetMultipleAttackMoves::generate<BLACK>(const NumEffectState& state,
00308 NtesukiMoveList& moves);
00309 template void GetMultipleAttackMoves::generate<WHITE>(const NumEffectState& state,
00310 NtesukiMoveList& moves);
00311
00312 }
00313 }
00314
00315
00316
00317
00318
00319