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