00001
00002
00003 #ifndef OSL_CHECKMATE_PROOF_NUMBER_TABLE_H
00004 #define OSL_CHECKMATE_PROOF_NUMBER_TABLE_H
00005 #include "osl/checkmate/king8Info.h"
00006 #include "osl/checkmate/proofDisproof.h"
00007 #include "osl/state/numEffectState.h"
00008 #include "osl/effect_util/additionalEffect.h"
00009 #include "osl/boardTable.h"
00010 #include "osl/neighboring8.h"
00011 #include "osl/misc/carray.h"
00012 #include "osl/misc/carray2d.h"
00013 #include "osl/misc/bitOp.h"
00014 #include "osl/misc/cstdint.h"
00015 #include <boost/scoped_ptr.hpp>
00016
00017 namespace osl
00018 {
00019 namespace checkmate
00020 {
00021 class ProofNumberTable
00022 {
00023 public:
00024 struct Liberty
00025 {
00027 uint8_t liberty;
00029 bool has_effect;
00030 explicit Liberty(uint8_t l=0, bool e=false) : liberty(l), has_effect(e)
00031 {
00032 }
00033 };
00034 private:
00035 struct Table
00036 {
00039 CArray2d<CArray<Liberty,DIRECTION_SIZE>,0x100u,PTYPE_SIZE> liberties;
00043 CArray2d<PieceMask,0x10000u,8> drop_liberty;
00045 CArray2d<uint8_t,0x100u,0x100u> pmajor_liberty;
00049 CArray2d<uint8_t,0x100u,0x100u> promote_liberty;
00051 CArray2d<uint8_t,0x100u,0x100u> other_move_liberty;
00052
00053 Table();
00054 };
00055 boost::scoped_ptr<Table> table;
00056 public:
00057 ProofNumberTable();
00058
00062 const Liberty countLiberty(Ptype ptype, Direction d, unsigned int liberty_mask) const
00063 {
00064 assert((d != UUL) && (d != UUR));
00065 assert(liberty_mask <= 0xff);
00066 return (table->liberties)[liberty_mask][ptype][d];
00067 }
00074 const Liberty countLibertyShortNotKnight(Player player, Position to, Ptype ptype,
00075 Position king, King8Info info) const
00076 {
00077 assert(Neighboring8::isNeighboring8(to, king));
00078 assert(ptype != KNIGHT);
00079 const unsigned int liberty_mask = info.liberty();
00080 const Direction d =
00081 longToShort((player == BLACK)
00082 ? Board_Table.getLongDirection<BLACK>(to, king)
00083 : Board_Table.getLongDirection<WHITE>(to, king));
00084 return countLiberty(ptype, d, liberty_mask);
00085 }
00086 const Liberty countLibertyLong(Player player, Position to, Ptype ptype,
00087 Position king, King8Info info) const
00088 {
00089 assert(! Neighboring8::isNeighboring8(to, king));
00090 const unsigned int liberty_mask = info.liberty();
00091 const Offset32 offset32(king,to);
00092 const Offset offset = Board_Table.getShortOffsetNotKnight(offset32);
00093 if (offset.zero())
00094 return Liberty(0, false);
00095 if (to + offset + offset != king)
00096 {
00097 if (isMajor(ptype))
00098 ptype = unpromote(ptype);
00099 else if (ptype != LANCE)
00100 return Liberty(0, false);
00101 }
00102 const Direction d =
00103 (player == BLACK)
00104 ? Board_Table.getLongDirection<BLACK>(offset32)
00105 : Board_Table.getLongDirection<WHITE>(offset32);
00106 assert(isLong(d));
00107 return countLiberty(ptype, d, liberty_mask);
00108 }
00112 int countLiberty(const NumEffectState& state, int liberty_count,
00113 Move move, Position king, King8Info info) const
00114 {
00115 assert(liberty_count == misc::BitOp::countBit(info.liberty()));
00116 const Player attack = move.player();
00117 const Player defense = alt(attack);
00118 const Position to = move.to();
00119 const Ptype ptype = move.ptype();
00120 if (ptype == KNIGHT)
00121 return std::max(1,liberty_count + state.countEffect(defense, to));
00122
00123 const bool neighboring = Neighboring8::isNeighboring8(to, king);
00124 Liberty liberty = neighboring
00125 ? countLibertyShortNotKnight(attack, to, ptype, king, info)
00126 : countLibertyLong(attack, to, ptype, king, info);
00127 if (liberty.liberty == 0)
00128 return std::max(liberty_count-1,1);
00129 if (! neighboring && liberty.has_effect)
00130 {
00131
00132
00133 ++liberty.liberty;
00134 }
00135
00136 liberty.liberty += state.countEffect(defense, to);
00137 if (move.isDrop())
00138 {
00139 if (neighboring)
00140 {
00141 if (state.countEffect(attack, to))
00142 --liberty.liberty;
00143 }
00144 assert(liberty.liberty);
00145 return liberty.liberty;
00146 }
00147
00148 if (neighboring)
00149 {
00150 if (state.countEffect(attack, to) >= 2
00151 || effect_util::AdditionalEffect::hasEffect(state, to, attack))
00152 --liberty.liberty;
00153 }
00154 assert(liberty.liberty);
00155 return liberty.liberty;
00156 }
00158 int countLiberty(const NumEffectState& state, Move move) const;
00159
00161 int libertyAfterAllDrop(const NumEffectState& state) const;
00162 int libertyAfterAllDrop(const NumEffectState& state, Player attack,
00163 King8Info info) const
00164 {
00165 assert(state.getTurn() == attack);
00166 int result = info.libertyCount()-1;
00167 if (result < 2)
00168 return 1;
00169 const unsigned int ld_mask = info.libertyDropMask();
00170 const PieceMask stand_mask=state.standMask(attack);
00171 for (;
00172 result > 1
00173 && (stand_mask & table->drop_liberty[ld_mask][result-1]).any();
00174 --result)
00175 {
00176 }
00177 return result;
00178 }
00180 int libertyAfterAllMove(const NumEffectState& state) const;
00181 int libertyAfterAllMove(const NumEffectState& state, Player attack,
00182 King8Info info, Position king) const;
00184 int libertyAfterAllCheck(const NumEffectState& state) const;
00185
00186 int disproofAfterAllCheck(const NumEffectState&, Player, King8Info) const;
00188 const ProofDisproof attackEstimation(const NumEffectState& state) const;
00189 const ProofDisproof attackEstimation(const NumEffectState& state,
00190 Player attack,
00191 King8Info info, Position king) const;
00192 };
00193 extern const ProofNumberTable Proof_Number_Table;
00194 }
00195 }
00196
00197 #endif
00198
00199
00200
00201
00202