00001
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
00190
00191
00192
00193