ntesukiMoveGeneratorAttack.cc
Go to the documentation of this file.
00001 /* ntesukiMoveGenerator.cc
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  * n 手すき探索で用いる move generator.
00029  */
00030 
00031 namespace osl
00032 {
00033   namespace ntesuki
00034   {
00035     /* ----------------------------------------------------------------------
00036      * Utility
00037      * ----------------------------------------------------------------------
00038      */
00039     static
00040     bool
00041     hasEffectByBigPieces (const NumEffectState& state,
00042                           const Player player,
00043                           const Square 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.piecesOnBoard (player)
00053                                    & state.effectAt (pos)
00054                                    & bigPieceMask);
00055       return pieceMask.any();
00056 #elif OSL_WORDSIZE == 32
00057       // TODO: 多分このコードで64bit 環境と共通にできると思うんだけど
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.piecesOnBoard (player)
00065                                    & state.effectAt (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 Square targetKing
00079         = state.kingSquare<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.square(), 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      * ATTACK
00115      * ----------------------------------------------------------------------
00116      */
00117     /* GetAllAttackMoves
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     /* GetAttackMoves
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 Square pos = state.template kingSquare<P>();
00148       const bool check = state.hasEffectAt(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       //shold we generate pawn?
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() != Square::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 Square opKingSquare =
00217         state.kingSquare (alt(state.turn ()));
00218 
00219       for (unsigned int i=0; i<all_moves.size(); ++i)
00220       {
00221         const Move m = all_moves[i];
00222         
00223         /*
00224          * 次の手を生成する
00225          *  - 王に迫る可能性のある手(25近傍に利きをつける手)
00226          *  - 角道・飛車道を空ける手 (CHECK)
00227          *  - 取る手
00228          */
00229         const Square from = m.from();
00230 
00231         if (Neighboring25Direct::hasEffect(state, m.ptypeO(), m.to(),
00232                                            opKingSquare))
00233         {
00234           move_candidates.push_back(m);
00235         }
00236         else if (hasEffectByBigPieces (state, state.turn (), from))
00237         {
00238           move_candidates.push_back(m);
00239         }
00240         else
00241         {
00242           const Square to = m.to();
00243           const Piece atTo = state.pieceOnBoard (to);
00244             
00245           if ((atTo.isPiece())
00246               && (atTo.owner() == alt (state.turn ())))
00247           {
00248             move_candidates.push_back(m);
00249           }
00250         }
00251       }//for each move in all_moves
00252       moves = NtesukiMoveList(state, move_candidates);
00253 #endif
00254     }//generate
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     /* GetMultipleAttackMoves
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.turn() == P);
00271       MoveVector all_moves;
00272       MoveVector move_candidates;
00273       LegalMoves::generate(state, all_moves);
00274 
00275       const Square opKingSquare =
00276         state.kingSquare (alt(state.turn ()));
00277 
00278       for (unsigned int i=0; i<all_moves.size(); ++i)
00279       {
00280         const Move m = all_moves[i];
00281         const Square from = m.from();
00282       
00283         if (move_classifier::canAttackInThreeMoves (m.player(),
00284                                                     m.ptype(),
00285                                                     m.to(),
00286                                                     opKingSquare))
00287         {
00288           move_candidates.push_back(m);
00289         }
00290         else if (hasEffectByBigPieces (state, state.turn (), from))
00291         {
00292           move_candidates.push_back(m);
00293         }
00294         else
00295         {
00296           const Square to = m.to();
00297           const Piece atTo = state.pieceOnBoard (to);
00298           if (atTo.isPiece()
00299               && (atTo.owner() == alt (state.turn ())))
00300           {
00301             move_candidates.push_back(m);
00302           }
00303         }
00304       }//for each move in all_moves
00305       moves = NtesukiMoveList(state, move_candidates);
00306     }//generate
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   }//ntesuki
00313 }//osl
00314 
00315 
00316 // ;;; Local Variables:
00317 // ;;; mode:c++
00318 // ;;; c-basic-offset:2
00319 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines