proofNumberTable.h
Go to the documentation of this file.
00001 /* proofNumberTable.h
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<uint8_t,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, Square to, Ptype ptype, 
00075                                                Square 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           (player == BLACK)
00082           ? Board_Table.getShort8<BLACK>(to, king)
00083           : Board_Table.getShort8<WHITE>(to, king);
00084         return countLiberty(ptype, d, liberty_mask);
00085       }
00086       const Liberty countLibertyLong(Player player, Square to, Ptype ptype, 
00087                                      Square 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) // 2マス以上遠く
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, Square 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 Square 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           // TODO: 詰将棋と協調できるなら liberty.liberty <=
00132           // liberty_count を保つように調整したい,が.
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;                // adjust king capture
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;          // adjust king capture
00153         }
00154         assert(liberty.liberty);
00155         return liberty.liberty;
00156       }
00158       int countLiberty(const NumEffectState& state, Move move) const;
00159 
00161       int
00162 #ifdef __GNUC__
00163         __attribute__ ((pure))
00164 #endif
00165       libertyAfterAllDrop(const NumEffectState& state) const;
00166       int
00167 #ifdef __GNUC__
00168         __attribute__ ((pure))
00169 #endif
00170       libertyAfterAllDrop(const NumEffectState& state, Player attack,
00171                           King8Info info) const;
00173       int
00174 #ifdef __GNUC__
00175         __attribute__ ((pure))
00176 #endif
00177       libertyAfterAllMove(const NumEffectState& state) const;
00178       int
00179 #ifdef __GNUC__
00180         __attribute__ ((pure))
00181 #endif
00182       libertyAfterAllMove(const NumEffectState& state, Player attack,
00183                           King8Info info, Square king) const;
00185       int
00186 #ifdef __GNUC__
00187         __attribute__ ((pure))
00188 #endif
00189       libertyAfterAllCheck(const NumEffectState& state) const;
00190 
00191       int
00192 #ifdef __GNUC__
00193         __attribute__ ((pure))
00194 #endif
00195       disproofAfterAllCheck(const NumEffectState&, Player, King8Info) const;
00197       const ProofDisproof
00198 #ifdef __GNUC__
00199         __attribute__ ((pure))
00200 #endif
00201       attackEstimation(const NumEffectState& state) const;
00202       const ProofDisproof
00203 #ifdef __GNUC__
00204         __attribute__ ((pure))
00205 #endif
00206       attackEstimation(const NumEffectState& state,
00207                        Player attack,
00208                        King8Info info, Square king) const;
00209     };
00210     extern const ProofNumberTable Proof_Number_Table;
00211   }
00212 }
00213 
00214 #endif /* _CHECKMATE_IMMEDIATE_CHECKMATE_TABLE_H */
00215 // ;;; Local Variables:
00216 // ;;; mode:c++
00217 // ;;; c-basic-offset:2
00218 // ;;; End:
00219 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines