00001
00002
00003 #ifndef OSL_CHECKMATE_PROOF_NUMBER_TABLE_H
00004 #define OSL_CHECKMATE_PROOF_NUMBER_TABLE_H
00005 #include "osl/checkmate/proofDisproof.h"
00006 #include "osl/numEffectState.h"
00007 #include "osl/bits/king8Info.h"
00008 #include "osl/additionalEffect.h"
00009 #include "osl/bits/boardTable.h"
00010
00011 namespace osl
00012 {
00013 namespace checkmate
00014 {
00015 class ProofNumberTable
00016 {
00017 public:
00018 struct Liberty
00019 {
00021 uint8_t liberty;
00023 bool has_effect;
00024 explicit Liberty(uint8_t l=0, bool e=false) : liberty(l), has_effect(e)
00025 {
00026 }
00027 };
00028 private:
00031 CArray2d<CArray<Liberty,DIRECTION_SIZE>,0x100u,PTYPE_SIZE> liberties;
00035 CArray2d<uint8_t,0x10000u,8> drop_liberty;
00037 CArray2d<uint8_t,0x100u,0x100u> pmajor_liberty;
00041 CArray2d<uint8_t,0x100u,0x100u> promote_liberty;
00043 CArray2d<uint8_t,0x100u,0x100u> other_move_liberty;
00044 public:
00045 void init();
00046
00050 const Liberty countLiberty(Ptype ptype, Direction d, unsigned int liberty_mask) const
00051 {
00052 assert((d != UUL) && (d != UUR));
00053 assert(liberty_mask <= 0xff);
00054 return liberties[liberty_mask][ptype][d];
00055 }
00062 const Liberty countLibertyShortNotKnight(Player player, Square to, Ptype ptype,
00063 Square king, King8Info info) const
00064 {
00065 assert(to.isNeighboring8(king));
00066 assert(ptype != KNIGHT);
00067 const unsigned int liberty_mask = info.liberty();
00068 const Direction d =
00069 (player == BLACK)
00070 ? Board_Table.getShort8<BLACK>(to, king)
00071 : Board_Table.getShort8<WHITE>(to, king);
00072 return countLiberty(ptype, d, liberty_mask);
00073 }
00074 const Liberty countLibertyLong(Player player, Square to, Ptype ptype,
00075 Square king, King8Info info) const
00076 {
00077 assert(! to.isNeighboring8(king));
00078 const unsigned int liberty_mask = info.liberty();
00079 const Offset32 offset32(king,to);
00080 const Offset offset = Board_Table.getShortOffsetNotKnight(offset32);
00081 if (offset.zero())
00082 return Liberty(0, false);
00083 if (to + offset + offset != king)
00084 {
00085 if (isMajor(ptype))
00086 ptype = unpromote(ptype);
00087 else if (ptype != LANCE)
00088 return Liberty(0, false);
00089 }
00090 const Direction d =
00091 (player == BLACK)
00092 ? Board_Table.getLongDirection<BLACK>(offset32)
00093 : Board_Table.getLongDirection<WHITE>(offset32);
00094 assert(isLong(d));
00095 return countLiberty(ptype, d, liberty_mask);
00096 }
00100 int countLiberty(const NumEffectState& state, int liberty_count,
00101 Move move, Square king, King8Info info) const
00102 {
00103 assert(liberty_count == misc::BitOp::countBit(info.liberty()));
00104 const Player attack = move.player();
00105 const Player defense = alt(attack);
00106 const Square to = move.to();
00107 const Ptype ptype = move.ptype();
00108 if (ptype == KNIGHT)
00109 return std::max(1,liberty_count + state.countEffect(defense, to));
00110
00111 const bool neighboring = to.isNeighboring8(king);
00112 Liberty liberty = neighboring
00113 ? countLibertyShortNotKnight(attack, to, ptype, king, info)
00114 : countLibertyLong(attack, to, ptype, king, info);
00115 if (liberty.liberty == 0)
00116 return std::max(liberty_count-1,1);
00117 if (! neighboring && liberty.has_effect)
00118 {
00119
00120
00121 ++liberty.liberty;
00122 }
00123
00124 liberty.liberty += state.countEffect(defense, to);
00125 if (move.isDrop())
00126 {
00127 if (neighboring)
00128 {
00129 if (state.countEffect(attack, to))
00130 --liberty.liberty;
00131 }
00132 assert(liberty.liberty);
00133 return liberty.liberty;
00134 }
00135
00136 if (neighboring)
00137 {
00138 if (state.countEffect(attack, to) >= 2
00139 || effect_util::AdditionalEffect::hasEffect(state, to, attack))
00140 --liberty.liberty;
00141 }
00142 assert(liberty.liberty);
00143 return liberty.liberty;
00144 }
00146 int countLiberty(const NumEffectState& state, Move move) const;
00147
00149 int
00150 #ifdef __GNUC__
00151 __attribute__ ((pure))
00152 #endif
00153 libertyAfterAllDrop(const NumEffectState& state) const;
00154 int
00155 #ifdef __GNUC__
00156 __attribute__ ((pure))
00157 #endif
00158 libertyAfterAllDrop(const NumEffectState& state, Player attack,
00159 King8Info info) const;
00161 int
00162 #ifdef __GNUC__
00163 __attribute__ ((pure))
00164 #endif
00165 libertyAfterAllMove(const NumEffectState& state) const;
00166 int
00167 #ifdef __GNUC__
00168 __attribute__ ((pure))
00169 #endif
00170 libertyAfterAllMove(const NumEffectState& state, Player attack,
00171 King8Info info, Square king) const;
00173 int
00174 #ifdef __GNUC__
00175 __attribute__ ((pure))
00176 #endif
00177 libertyAfterAllCheck(const NumEffectState& state) const;
00178
00179 int
00180 #ifdef __GNUC__
00181 __attribute__ ((pure))
00182 #endif
00183 disproofAfterAllCheck(const NumEffectState&, Player, King8Info) const;
00185 const ProofDisproof
00186 #ifdef __GNUC__
00187 __attribute__ ((pure))
00188 #endif
00189 attackEstimation(const NumEffectState& state) const;
00190 const ProofDisproof
00191 #ifdef __GNUC__
00192 __attribute__ ((pure))
00193 #endif
00194 attackEstimation(const NumEffectState& state,
00195 Player attack,
00196 King8Info info, Square king) const;
00197 };
00198
00199 extern ProofNumberTable Proof_Number_Table;
00200
00201 class EdgeTable
00202 {
00203 CArray2d<uint64_t, 2, Square::SIZE> edge_mask;
00204 public:
00205 void init();
00207 const King8Info
00208 #ifdef __GNUC__
00209 __attribute__ ((pure))
00210 #endif
00211 resetEdgeFromLiberty(Player king_player, Square king, King8Info info) const
00212 {
00213 uint64_t ret = info.uint64Value();
00214 ret &= edge_mask[king_player][king.index()];
00215 const uint64_t count = misc::BitOp::countBit((ret>>8)&0xffull);
00216 ret |= count << 48;
00217 return King8Info(ret);
00218 }
00219 };
00220 extern EdgeTable Edge_Table;
00221 }
00222 }
00223
00224 #endif
00225
00226
00227
00228
00229