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 class King8Info
00031 {
00032 uint64_t value;
00033 public:
00034 explicit King8Info(uint64_t v) : value(v)
00035 {
00036 }
00037
00038 template<Player P>
00039 static const King8Info make(NumEffectState const& state,Square king, PieceMask pinned);
00040 template<Player P>
00041 static const King8Info make(NumEffectState const& state,Square king);
00042
00044 static const King8Info make(Player attack, NumEffectState const& state);
00046 static const King8Info makeWithPin(Player attack, NumEffectState const& state,
00047 const PieceMask& pinned);
00048 uint64_t uint64Value() const { return value; }
00049
00051 unsigned int dropCandidate() const
00052 {
00053 return (unsigned int)(value&0xffull);
00054 }
00056 unsigned int liberty() const
00057 {
00058 return (unsigned int)((value>>8)&0xffull);
00059 }
00061 unsigned int libertyDropMask() const
00062 {
00063 return (unsigned int)(value&0xffffull);
00064 }
00066 unsigned int libertyCandidate() const
00067 {
00068 return (unsigned int)((value>>16)&0xffull);
00069 }
00071 unsigned int moveCandidate2() const
00072 {
00073 return (unsigned int)((value>>24)&0xffull);
00074 }
00075 unsigned int spaces() const
00076 {
00077 return (unsigned int)((value>>32)&0xffull);
00078 }
00079 unsigned int moves() const
00080 {
00081 return (unsigned int)((value>>40)&0xffull);
00082 }
00084 unsigned int libertyCount() const
00085 {
00086 return (unsigned int)((value>>48)&0xfull);
00087 }
00088 template<Player P,Direction Dir>
00089 unsigned int moveCandidateDir(NumEffectState const& state,Square target) const{
00090 if((value & (1ull<<(24+Dir)))==0) return 0;
00091 Square pos=target-DirectionPlayerTraits<Dir,P>::offset();
00092 if(state.countEffect(P,pos)<2 &&
00093 !effect_util::AdditionalEffect::hasEffect(state,pos,P)) return 0;
00094 return 1;
00095 }
00096 template<Player P>
00097 unsigned int countMoveCandidate(NumEffectState const& state) const
00098 {
00099 const Player altP=PlayerTraits<P>::opponent;
00100 Square king=state.kingSquare<altP>();
00101 return moveCandidateDir<P,UL>(state,king)+
00102 moveCandidateDir<P,U>(state,king)+
00103 moveCandidateDir<P,UR>(state,king)+
00104 moveCandidateDir<P,L>(state,king)+
00105 moveCandidateDir<P,R>(state,king)+
00106 moveCandidateDir<P,DL>(state,king)+
00107 moveCandidateDir<P,D>(state,king)+
00108 moveCandidateDir<P,DR>(state,king);
00109 }
00110 unsigned int countMoveCandidate(Player player, NumEffectState const& state) const
00111 {
00112 if(player==BLACK) return countMoveCandidate<BLACK>(state);
00113 else return countMoveCandidate<WHITE>(state);
00114 }
00115 template<Player P>
00116 unsigned int moveCandidateMask(NumEffectState const& state) const
00117 {
00118 const Player altP=PlayerTraits<P>::opponent;
00119 Square king=state.kingSquare<altP>();
00120 return (moveCandidateDir<P,UL>(state,king)<<UL)+
00121 (moveCandidateDir<P,U>(state,king)<<U)+
00122 (moveCandidateDir<P,UR>(state,king)<<UR)+
00123 (moveCandidateDir<P,L>(state,king)<<L)+
00124 (moveCandidateDir<P,R>(state,king)<<R)+
00125 (moveCandidateDir<P,DL>(state,king)<<DL)+
00126 (moveCandidateDir<P,D>(state,king)<<D)+
00127 (moveCandidateDir<P,DR>(state,king)<<DR);
00128 }
00129 template<Player P>
00130 bool hasMoveCandidate(NumEffectState const& state) const
00131 {
00132 const Player altP=PlayerTraits<P>::opponent;
00133 Square king=state.kingSquare<altP>();
00134 if(moveCandidateDir<P,U>(state,king)!=0) return true;
00135 if(moveCandidateDir<P,UL>(state,king)!=0) return true;
00136 if(moveCandidateDir<P,UR>(state,king)!=0) return true;
00137 if(moveCandidateDir<P,L>(state,king)!=0) return true;
00138 if(moveCandidateDir<P,R>(state,king)!=0) return true;
00139 if(moveCandidateDir<P,D>(state,king)!=0) return true;
00140 if(moveCandidateDir<P,DL>(state,king)!=0) return true;
00141 if(moveCandidateDir<P,DR>(state,king)!=0) return true;
00142 return false;
00143 }
00144 private:
00152 template<Player P,Direction Dir>
00153 static uint64_t
00154 #ifdef __GNUC__
00155 __attribute__ ((pure))
00156 #endif
00157 hasEffectMask(NumEffectState const& state,Square target, PieceMask pinned,
00158 PieceMask on_board_defense);
00159 };
00160
00161 class EdgeTable
00162 {
00163 CArray2d<uint64_t, 2, Square::SIZE> edge_mask;
00164 public:
00165 EdgeTable();
00167 const King8Info
00168 #ifdef __GNUC__
00169 __attribute__ ((pure))
00170 #endif
00171 resetEdgeFromLiberty(Player king_player, Square king, King8Info info) const
00172 {
00173 uint64_t ret = info.uint64Value();
00174 ret &= edge_mask[king_player][king.index()];
00175 const uint64_t count = misc::BitOp::countBit((ret>>8)&0xffull);
00176 ret |= count << 48;
00177 return King8Info(ret);
00178 }
00179 };
00180 extern const EdgeTable Edge_Table;
00181
00182 std::ostream& operator<<(std::ostream&, King8Info);
00183 }
00184 using checkmate::King8Info;
00185 }
00186
00187 #endif
00188
00189
00190
00191
00192