00001
00002
00003 #ifndef _CATEGORYUTIL_H
00004 #define _CATEGORYUTIL_H
00005
00006 #include "osl/category/categoryEnv.h"
00007 #include "osl/category/categoryTraits.h"
00008 #include "osl/category/moveEvaluation.h"
00009
00010 #include "osl/search/simpleHashRecord.h"
00011 #include "osl/effect_util/sendOffPosition.h"
00012
00013 #include "osl/move_classifier/moveAdaptor.h"
00014 #include "osl/move.h"
00015 #include "osl/container/moveVector.h"
00016 #include "osl/container/moveLogProbVector.h"
00017 #include "osl/container/position8.h"
00018 #include "osl/misc/loki.h"
00019 #include <utility>
00020
00021
00022 #include "osl/eval/pieceEval.h"
00023
00024 namespace osl
00025 {
00026 namespace category
00027 {
00028 struct CategoryUtilBase
00029 {
00030 static void findSendOff(const CategoryEnv& env, Position8& out)
00031 {
00032 const Player turn = env.state->getTurn();
00033 if (env.record)
00034 {
00035 out = env.record->qrecord.sendOffPosition(turn, *env.state);
00036 }
00037 else
00038 {
00039 const Position king_position = env.state->getKingPosition(alt(turn));
00040 effect_util::SendOffPosition::find(turn, *env.state, king_position,
00041 out);
00042 }
00043 }
00044
00045
00046 enum {
00047 SendOffBonus = eval::PtypeEvalTraits<PAWN>::val,
00048 CaptureIfCheckmateBonus = eval::PtypeEvalTraits<PAWN>::val*2
00049 };
00050 };
00051
00052 template <class Category>
00053 struct CategoryUtil : public CategoryUtilBase
00054 {
00055 private:
00056 static void doNotCompile();
00057 private:
00058 static std::pair<bool,size_t>
00059 getIndexIf(const CategoryEnv& env, Move m, int, Int2Type<FIXED>)
00060 {
00061 if (Category::isInCategory(env, m))
00062 return std::make_pair(true, 0u);
00063 return std::make_pair(false,0u);
00064 }
00065 static std::pair<bool,size_t>
00066 getIndexIf(const CategoryEnv& env, Move m, int pieceValue,
00067 Int2Type<STANDARD_TABLE>)
00068 {
00069 if (Category::isInCategory(env, m))
00070 return std::make_pair(true, Category::getIndex(env,m,pieceValue));
00071 return std::make_pair(false, 0u);
00072 }
00073 static std::pair<bool,size_t>
00074 getIndexIf(const CategoryEnv& env, Move m, int pieceValue,
00075 Int2Type<TABLE>)
00076 {
00077 return Category::getIndexIf(env, m, pieceValue);
00078 }
00079 static std::pair<bool,size_t>
00080 getIndexIf(const CategoryEnv& env, Move m, int pieceValue,
00081 Int2Type<SPECIAL>)
00082 {
00083 doNotCompile();
00084 return std::make_pair(false, 0u);
00085 }
00086 public:
00095 static std::pair<bool,size_t> getIndexIf(const CategoryEnv& env,
00096 Move m, int pieceValue)
00097 {
00098 return getIndexIf(env, m, pieceValue, Int2Type<Category::probType>());
00099 }
00100 private:
00101 static std::pair<bool,int>
00102 getProbIf(const CategoryEnv& env, Move m, int pieceValue,
00103 Int2Type<false>)
00104 {
00105 const std::pair<bool,size_t> r =
00106 getIndexIf(env, m, pieceValue);
00107 if (r.first)
00108 return std::make_pair
00109 (true, Category::probTable[r.second]);
00110 return std::make_pair(false,0);
00111 }
00112 static std::pair<bool,int>
00113 getProbIf(const CategoryEnv& env, Move m, int pieceValue,
00114 Int2Type<true>)
00115 {
00116 return Category::getProbIf(env, m, pieceValue);
00117 }
00118 public:
00127 static std::pair<bool,int> getProbIf(const CategoryEnv& env,
00128 Move m,
00129 int pieceValue)
00130 {
00131 return getProbIf(env, m, pieceValue,
00132 Int2Type<Category::probType==SPECIAL>());
00133 }
00134 private:
00135 static void generate(const CategoryEnv& env, MoveLogProbVector& out,
00136 Int2Type<SPECIAL>)
00137 {
00138 Category::generate(env, out);
00139 out.sortByProbability();
00140 }
00141 static void generate(const CategoryEnv& env, MoveLogProbVector& out,
00142 Int2Type<TABLE>)
00143 {
00144
00145
00146 Category::generate(env, out);
00147 out.sortByProbability();
00148 }
00149 static void generate(const CategoryEnv& env, MoveLogProbVector& out,
00150 Int2Type<STANDARD_TABLE>);
00151 static void generate(const CategoryEnv& env, MoveLogProbVector& out,
00152 Int2Type<FIXED>);
00153 public:
00159 static void generate(const CategoryEnv& env, MoveLogProbVector& out)
00160 {
00161 generate(env, out, Int2Type<Category::probType>());
00162 }
00163 };
00164 }
00165 }
00166
00167 template <class Category>
00168 void osl::category::
00169 CategoryUtil<Category>::generate(const CategoryEnv& env, MoveLogProbVector& out,
00170 Int2Type<FIXED>)
00171 {
00172 assert(env.limit >= Category::probTable[0]);
00173 MoveVector moves;
00174 Category::generate(env, moves);
00175 for (MoveVector::const_iterator p=moves.begin(); p!=moves.end(); ++p)
00176 {
00177 assert(p->isValid());
00178 out.push_back(*p, Category::probTable[0]);
00179 }
00180
00181 }
00182
00183 template <class Category>
00184 void osl::category::
00185 CategoryUtil<Category>::generate(const CategoryEnv& env, MoveLogProbVector& out,
00186 Int2Type<STANDARD_TABLE>)
00187 {
00188 MoveVector moves;
00189 Category::generate(env, moves);
00190 Position8 sendoffs;
00191 if (Category::AdjustSendOff)
00192 {
00193 findSendOff(env, sendoffs);
00194 }
00195 const int limit = env.limit;
00196 for (MoveVector::const_iterator p=moves.begin(); p!=moves.end(); ++p)
00197 {
00198 int diff = MoveEvaluation::evalLight(*env.state, *p);
00199 if (Category::AdjustSendOff
00200 && sendoffs.isMember(p->to()))
00201 diff = std::max(diff, (const int)SendOffBonus);
00202
00203 const size_t index = Category::getIndex(env, *p, diff);
00204 const int moveProb = Category::probTable[index];
00205 assert(p->isValid());
00206 if (! Category::IsKingEscape)
00207 {
00208 if (moveProb <= limit)
00209 out.push_back(*p, moveProb);
00210 }
00211 else
00212 {
00213
00214 out.push_back(*p, std::min(moveProb, limit));
00215 }
00216 }
00217 out.sortByProbability();
00218 }
00219
00220 #endif
00221
00222
00223
00224