king8Info.cc
Go to the documentation of this file.
00001 /* king8Info.cc
00002  */
00003 #include "osl/checkmate/king8Info.h"
00004 #include "osl/state/numEffectState.h"
00005 #include "osl/effect_util/additionalEffect.h"
00006 #include "osl/effect_util/pin.h"
00007 #include <bitset>
00008 #include <iostream>
00009 
00010 #ifndef MINIMAL
00011 std::ostream& osl::checkmate::operator<<(std::ostream& os, King8Info info)
00012 {
00013   typedef std::bitset<8> bs_t;
00014   os << bs_t(info.moveCandidate2()) << " " 
00015      << bs_t(info.libertyCandidate()) << " " 
00016      << bs_t(info.liberty()) << " " 
00017      << bs_t(info.dropCandidate());
00018   return os;
00019 }
00020 #endif
00021 namespace osl
00022 {
00023   namespace
00024   {
00034 template<Player P> inline
00035 bool
00036 #ifdef __GNUC__
00037 __attribute__ ((pure))
00038 #endif
00039  hasEnoughEffect(NumEffectState const& state,Square target,Square pos, const PieceMask& pinned,
00040                      const PieceMask& on_board_defense,
00041   Direction dir)
00042 {
00043   assert(state.kingSquare(P)==target);
00044   assert(pos.isOnBoard());
00045   PieceMask pieceMask = state.effectSetAt(pos)&on_board_defense;
00046   if(pieceMask.none()) return false;
00047   PieceMask pieceMask1=pieceMask&~pinned;
00048   if(pieceMask1.any()) return true;
00049   pieceMask&=pinned;
00050   assert(pieceMask.any());
00051   do {
00052     int num=pieceMask.takeOneBit();
00053     Piece p=state.pieceOf(num);
00054     assert(p.isOnBoardByOwner(P));
00055     Square pos1=p.square();
00056     assert(Board_Table.getShortOffset(Offset32(pos,target))
00057            == pos-target);
00058     Direction dir1=Board_Table.getShort8<P>(target,pos1);
00059     if(dir1==dir) return true;
00060   } while(pieceMask.any());
00061   return false;
00062 }
00063   }
00064 }
00065 
00066 template<osl::Player P,osl::Direction Dir>
00067 uint64_t osl::checkmate::
00068 King8Info::hasEffectMask(NumEffectState const& state,Square target, PieceMask pinned,
00069                          PieceMask on_board_defense)
00070 {
00071   const Player altP=PlayerTraits<P>::opponent;
00072   Square pos=target-DirectionPlayerTraits<Dir,P>::offset();
00073   Piece p=state.pieceAt(pos);
00074   if(p.isEdge())
00075     return 0ull;
00076   if(!state.hasEffectAt(P,pos)){
00077     if(p.canMoveOn<altP>()){ // 自分の駒か空白
00078       if(p.isEmpty())
00079         return 0x1000000000000ull+(0x100010100ull<<static_cast<int>(Dir));
00080       else
00081         return 0x1000000000000ull+(0x10100ull<<static_cast<int>(Dir));
00082     }
00083     else // 相手の駒
00084       return 0ull;
00085   }
00086   const bool has_enough_effect = hasEnoughEffect<altP>(state,target,pos,pinned,on_board_defense,Dir);
00087   if(has_enough_effect){
00088     if(p.canMoveOn<altP>()){
00089       if(p.isEmpty())
00090         return 0x10100010000ull<<static_cast<int>(Dir);
00091       else
00092         return 0x10000ull<<static_cast<int>(Dir);
00093     }
00094     else
00095       return 0x10000000000ull<<static_cast<int>(Dir);
00096   }
00097   else{
00098     if(p.isEmpty())
00099       return 0x10101010001ull<<static_cast<int>(Dir);
00100     else if(p.isOnBoardByOwner<P>())
00101       return 0x10000ull<<static_cast<int>(Dir);
00102     else
00103       return 0x10001000000ull<<static_cast<int>(Dir);
00104   }
00105 }
00106 
00107 template<osl::Player P>
00108 const osl::checkmate::King8Info 
00109 #if (defined __GNUC__) && (! defined GPSONE) && (! defined GPSUSIONE)
00110 __attribute__ ((noinline))
00111 #endif
00112 osl::checkmate::King8Info::make(NumEffectState const& state,Square target, PieceMask pinned)
00113 {
00114   PieceMask on_board_defense=state.piecesOnBoard(alt(P));
00115   on_board_defense.reset(KingTraits<PlayerTraits<P>::opponent>::index);
00116   uint64_t canMoveMask=
00117     hasEffectMask<P,UR>(state,target,pinned,on_board_defense)+
00118     hasEffectMask<P,R>(state,target,pinned,on_board_defense)+
00119     hasEffectMask<P,DR>(state,target,pinned,on_board_defense)+
00120     hasEffectMask<P,U>(state,target,pinned,on_board_defense)+
00121     hasEffectMask<P,D>(state,target,pinned,on_board_defense)+
00122     hasEffectMask<P,UL>(state,target,pinned,on_board_defense)+
00123     hasEffectMask<P,L>(state,target,pinned,on_board_defense)+
00124     hasEffectMask<P,DL>(state,target,pinned,on_board_defense);
00125   mask_t longMask=state.longEffectAt(target,P);
00126   while(longMask.any()){
00127     int num=longMask.takeOneBit()+PtypeFuns<LANCE>::indexNum*32;
00128     Piece attacker=state.pieceOf(num);
00129     Direction d=
00130       Board_Table.getShort8<P>(target,attacker.square());
00131     if((canMoveMask&(0x100<<d))!=0){
00132       canMoveMask-=((0x100<<d)+0x1000000000000ull);
00133     }
00134   }
00135   return King8Info(canMoveMask);
00136 }
00137 
00138 template <osl::Player P>
00139 const osl::checkmate::King8Info 
00140 #if (defined __GNUC__) && (! defined GPSONE) && (! defined GPSUSIONE)
00141 __attribute__ ((noinline))
00142 #endif
00143 osl::checkmate::
00144 King8Info::make(NumEffectState const& state, Square target)
00145 {
00146   return make<P>(state,target,state.pin(alt(P)));
00147 }
00148 
00149 const osl::checkmate::King8Info osl::checkmate::
00150 King8Info::make(Player attack, NumEffectState const& state)
00151 {
00152   const Square king=state.kingSquare(alt(attack));
00153   if (attack == BLACK)
00154     return make<BLACK>(state, king);
00155   else
00156     return make<WHITE>(state, king);
00157 }
00158 
00159 const osl::checkmate::King8Info osl::checkmate::
00160 King8Info::makeWithPin(Player attack, NumEffectState const& state,
00161                        const PieceMask& pins)
00162 {
00163   const Square king=state.kingSquare(alt(attack));
00164   if (attack == BLACK)
00165     return make<BLACK>(state, king, pins);
00166   else
00167     return make<WHITE>(state, king, pins);
00168 }
00169 
00170 osl::checkmate::EdgeTable::EdgeTable()
00171 {
00172   edge_mask.fill(~(0xfull << 48));
00173   for (int x=1; x<=9; ++x) {
00174     for (int y=1; y<=9; ++y) {
00175       Square king(x,y);
00176       for (int d=DIRECTION_MIN; d<=SHORT8_DIRECTION_MAX; ++d) {
00177         Square target = king+Board_Table.getOffset(BLACK, Direction(d));
00178         if (target.x() <= 1 || target.x() >= 9 || target.y() <=1 || target.y() >=9)
00179           edge_mask[BLACK][king.index()] &= ~(0x100ull<<d);
00180         target = king+Board_Table.getOffset(WHITE, Direction(d));
00181         if (target.x() <= 1 || target.x() >= 9 || target.y() <=1 || target.y() >=9)
00182           edge_mask[WHITE][king.index()] &= ~(0x100ull<<d);
00183       }
00184     }
00185   }
00186 }
00187 
00188 /* ------------------------------------------------------------------------- */
00189 // ;;; Local Variables:
00190 // ;;; mode:c++
00191 // ;;; c-basic-offset:2
00192 // ;;; End:
00193 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines