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 hasEnoughEffect(NumEffectState const& state,Position target,Position pos, const PieceMask& pinned,
00036 const PieceMask& on_board_defense,
00037 Direction dir)
00038 {
00039 assert(state.getKingPosition(P)==target);
00040 assert(pos.isOnBoard());
00041 PieceMask pieceMask = state.getEffect(pos)&on_board_defense;
00042 if(pieceMask.none()) return false;
00043 PieceMask pieceMask1=pieceMask&~pinned;
00044 if(pieceMask1.any()) return true;
00045 pieceMask&=pinned;
00046 assert(pieceMask.any());
00047 do {
00048 int num=pieceMask.takeOneBit();
00049 Piece p=state.getPieceOf(num);
00050 assert(p.isOnBoardByOwner(P));
00051 Position pos1=p.position();
00052 assert(Board_Table.getShortOffset(Offset32(pos,target))
00053 == pos-target);
00054 Direction dir1=Board_Table.getShort8<P>(target,pos1);
00055 if(dir1==dir) return true;
00056 } while(pieceMask.any());
00057 return false;
00058 }
00059 }
00060 }
00061
00062 template<osl::Player P,osl::Direction Dir>
00063 uint64_t osl::checkmate::
00064 King8Info::hasEffectMask(NumEffectState const& state,Position target, PieceMask pinned,
00065 PieceMask on_board_defense)
00066 {
00067 const Player altP=PlayerTraits<P>::opponent;
00068 Position pos=target-DirectionPlayerTraits<Dir,P>::offset();
00069 Piece p=state.getPieceAt(pos);
00070 if(p.isEdge())
00071 return 0ull;
00072 if(!state.hasEffectBy(P,pos)){
00073 if(p.canMoveOn<altP>()){
00074 if(p.isEmpty())
00075 return 0x1000000000000ull+(0x100010100ull<<static_cast<int>(Dir));
00076 else
00077 return 0x1000000000000ull+(0x10100ull<<static_cast<int>(Dir));
00078 }
00079 else
00080 return 0ull;
00081 }
00082 const bool has_enough_effect = hasEnoughEffect<altP>(state,target,pos,pinned,on_board_defense,Dir);
00083 if(has_enough_effect){
00084 if(p.canMoveOn<altP>()){
00085 if(p.isEmpty())
00086 return 0x10100010000ull<<static_cast<int>(Dir);
00087 else
00088 return 0x10000ull<<static_cast<int>(Dir);
00089 }
00090 else
00091 return 0x10000000000ull<<static_cast<int>(Dir);
00092 }
00093 else{
00094 if(p.isEmpty())
00095 return 0x10101010001ull<<static_cast<int>(Dir);
00096 else if(p.isOnBoardByOwner<P>())
00097 return 0x10000ull<<static_cast<int>(Dir);
00098 else
00099 return 0x10001000000ull<<static_cast<int>(Dir);
00100 }
00101 }
00102
00103 template<osl::Player P>
00104 const osl::checkmate::King8Info
00105 #if (defined __GNUC__) && (! defined GPSONE) && (! defined GPSUSIONE)
00106 __attribute__ ((noinline))
00107 #endif
00108 osl::checkmate::King8Info::make(NumEffectState const& state,Position target, PieceMask pinned)
00109 {
00110 PieceMask on_board_defense=state.getOnBoardMask(alt(P));
00111 on_board_defense.reset(KingTraits<PlayerTraits<P>::opponent>::index);
00112 uint64_t canMoveMask=
00113 hasEffectMask<P,UR>(state,target,pinned,on_board_defense)+
00114 hasEffectMask<P,R>(state,target,pinned,on_board_defense)+
00115 hasEffectMask<P,DR>(state,target,pinned,on_board_defense)+
00116 hasEffectMask<P,U>(state,target,pinned,on_board_defense)+
00117 hasEffectMask<P,D>(state,target,pinned,on_board_defense)+
00118 hasEffectMask<P,UL>(state,target,pinned,on_board_defense)+
00119 hasEffectMask<P,L>(state,target,pinned,on_board_defense)+
00120 hasEffectMask<P,DL>(state,target,pinned,on_board_defense);
00121 mask_t longMask=state.selectLong(target,P);
00122 while(longMask.any()){
00123 int num=longMask.takeOneBit()+PtypeFuns<LANCE>::indexNum*32;
00124 Piece attacker=state.getPieceOf(num);
00125 Direction d=
00126 Board_Table.getShort8<P>(target,attacker.position());
00127 if((canMoveMask&(0x100<<d))!=0){
00128 canMoveMask-=((0x100<<d)+0x1000000000000ull);
00129 }
00130 }
00131 return King8Info(canMoveMask);
00132 }
00133
00134 template <osl::Player P>
00135 const osl::checkmate::King8Info
00136 #if (defined __GNUC__) && (! defined GPSONE) && (! defined GPSUSIONE)
00137 __attribute__ ((noinline))
00138 #endif
00139 osl::checkmate::
00140 King8Info::make(NumEffectState const& state, Position target)
00141 {
00142 return make<P>(state,target,state.pin(alt(P)));
00143 }
00144
00145 const osl::checkmate::King8Info osl::checkmate::
00146 King8Info::make(Player attack, NumEffectState const& state)
00147 {
00148 const Position king=state.getKingPosition(alt(attack));
00149 if (attack == BLACK)
00150 return make<BLACK>(state, king);
00151 else
00152 return make<WHITE>(state, king);
00153 }
00154
00155 const osl::checkmate::King8Info osl::checkmate::
00156 King8Info::makeWithPin(Player attack, NumEffectState const& state,
00157 const PieceMask& pins)
00158 {
00159 const Position king=state.getKingPosition(alt(attack));
00160 if (attack == BLACK)
00161 return make<BLACK>(state, king, pins);
00162 else
00163 return make<WHITE>(state, king, pins);
00164 }
00165
00166 osl::checkmate::EdgeTable::EdgeTable()
00167 {
00168 edge_mask.fill(~(0xfull << 48));
00169 for (int x=1; x<=9; ++x) {
00170 for (int y=1; y<=9; ++y) {
00171 Position king(x,y);
00172 for (int d=DIRECTION_MIN; d<=SHORT8_DIRECTION_MAX; ++d) {
00173 Position target = king+Board_Table.getOffset(BLACK, Direction(d));
00174 if (target.x() <= 1 || target.x() >= 9 || target.y() <=1 || target.y() >=9)
00175 edge_mask[BLACK][king.index()] &= ~(0x100ull<<d);
00176 target = king+Board_Table.getOffset(WHITE, Direction(d));
00177 if (target.x() <= 1 || target.x() >= 9 || target.y() <=1 || target.y() >=9)
00178 edge_mask[WHITE][king.index()] &= ~(0x100ull<<d);
00179 }
00180 }
00181 }
00182 }
00183
00184
00185
00186
00187
00188
00189