00001
00002
00003 #ifndef OSL_CHECKMATE_KING8INFO_H
00004 #define OSL_CHECKMATE_KING8INFO_H
00005
00006 #include "osl/state/numEffectState.h"
00007 #include "osl/misc/bitOp.h"
00008 #include "osl/effect_util/additionalEffect.h"
00009 #include <boost/cstdint.hpp>
00010 #include <iosfwd>
00011 namespace osl
00012 {
00013 namespace checkmate
00014 {
00030 struct King8Info
00031 {
00032 uint64_t value;
00033 explicit King8Info(uint64_t v) : value(v)
00034 {
00035 }
00036
00037 template<Player P>
00038 static const King8Info make(NumEffectState const& state,Position king, PieceMask pinned);
00039 template<Player P>
00040 static const King8Info make(NumEffectState const& state,Position king);
00041
00043 static const King8Info make(Player attack, NumEffectState const& state);
00045 static const King8Info makeWithPin(Player attack, NumEffectState const& state,
00046 const PieceMask& pinned);
00047
00049 unsigned int dropCandidate() const
00050 {
00051 return (unsigned int)(value&0xffull);
00052 }
00054 unsigned int liberty() const
00055 {
00056 return (unsigned int)((value>>8)&0xffull);
00057 }
00059 unsigned int libertyDropMask() const
00060 {
00061 return (unsigned int)(value&0xffffull);
00062 }
00064 unsigned int libertyCandidate() const
00065 {
00066 return (unsigned int)((value>>16)&0xffull);
00067 }
00069 unsigned int moveCandidate2() const
00070 {
00071 return (unsigned int)((value>>24)&0xffull);
00072 }
00073 unsigned int spaces() const
00074 {
00075 return (unsigned int)((value>>32)&0xffull);
00076 }
00077 unsigned int moves() const
00078 {
00079 return (unsigned int)((value>>40)&0xffull);
00080 }
00082 unsigned int libertyCount() const
00083 {
00084 return (unsigned int)((value>>48)&0xfull);
00085 }
00086 template<Player P,Direction Dir>
00087 unsigned int moveCandidateDir(NumEffectState const& state,Position target) const{
00088 if((value & (1ull<<(24+Dir)))==0) return 0;
00089 Position pos=target-DirectionPlayerTraits<Dir,P>::offset();
00090 if(state.countEffect(P,pos)<2 &&
00091 !effect_util::AdditionalEffect::hasEffect(state,pos,P)) return 0;
00092 return 1;
00093 }
00094 template<Player P>
00095 unsigned int countMoveCandidate(NumEffectState const& state) const
00096 {
00097 const Player altP=PlayerTraits<P>::opponent;
00098 Position king=state.getKingPosition<altP>();
00099 return moveCandidateDir<P,UL>(state,king)+
00100 moveCandidateDir<P,U>(state,king)+
00101 moveCandidateDir<P,UR>(state,king)+
00102 moveCandidateDir<P,L>(state,king)+
00103 moveCandidateDir<P,R>(state,king)+
00104 moveCandidateDir<P,DL>(state,king)+
00105 moveCandidateDir<P,D>(state,king)+
00106 moveCandidateDir<P,DR>(state,king);
00107 }
00108 unsigned int countMoveCandidate(Player player, NumEffectState const& state) const
00109 {
00110 if(player==BLACK) return countMoveCandidate<BLACK>(state);
00111 else return countMoveCandidate<WHITE>(state);
00112 }
00113 template<Player P>
00114 unsigned int moveCandidateMask(NumEffectState const& state) const
00115 {
00116 const Player altP=PlayerTraits<P>::opponent;
00117 Position king=state.getKingPosition<altP>();
00118 return (moveCandidateDir<P,UL>(state,king)<<UL)+
00119 (moveCandidateDir<P,U>(state,king)<<U)+
00120 (moveCandidateDir<P,UR>(state,king)<<UR)+
00121 (moveCandidateDir<P,L>(state,king)<<L)+
00122 (moveCandidateDir<P,R>(state,king)<<R)+
00123 (moveCandidateDir<P,DL>(state,king)<<DL)+
00124 (moveCandidateDir<P,D>(state,king)<<D)+
00125 (moveCandidateDir<P,DR>(state,king)<<DR);
00126 }
00127 template<Player P>
00128 bool hasMoveCandidate(NumEffectState const& state) const
00129 {
00130 const Player altP=PlayerTraits<P>::opponent;
00131 Position king=state.getKingPosition<altP>();
00132 if(moveCandidateDir<P,U>(state,king)!=0) return true;
00133 if(moveCandidateDir<P,UL>(state,king)!=0) return true;
00134 if(moveCandidateDir<P,UR>(state,king)!=0) return true;
00135 if(moveCandidateDir<P,L>(state,king)!=0) return true;
00136 if(moveCandidateDir<P,R>(state,king)!=0) return true;
00137 if(moveCandidateDir<P,D>(state,king)!=0) return true;
00138 if(moveCandidateDir<P,DL>(state,king)!=0) return true;
00139 if(moveCandidateDir<P,DR>(state,king)!=0) return true;
00140 return false;
00141 }
00142 private:
00150 template<Player P,Direction Dir>
00151 static uint64_t hasEffectMask(NumEffectState const& state,Position target, PieceMask pinned,
00152 PieceMask on_board_defense);
00153 };
00154
00155 class EdgeTable
00156 {
00157 CArray2d<uint64_t, 2, Position::SIZE> edge_mask;
00158 public:
00159 EdgeTable();
00161 const King8Info resetEdgeFromLiberty(Player king_player, Position king, King8Info info) const
00162 {
00163 uint64_t ret = info.value;
00164 ret &= edge_mask[king_player][king.index()];
00165 const uint64_t count = misc::BitOp::countBit((ret>>8)&0xffull);
00166 ret |= count << 48;
00167 return King8Info(ret);
00168 }
00169 };
00170 extern const EdgeTable Edge_Table;
00171
00172 std::ostream& operator<<(std::ostream&, King8Info);
00173 }
00174 using checkmate::King8Info;
00175 }
00176
00177 #endif
00178
00179
00180
00181
00182