00001
00002
00003 #ifndef _CATEGORYLISTUTIL_H
00004 #define _CATEGORYLISTUTIL_H
00005 #include "osl/category/categoryConcept.h"
00006 #include "osl/category/categoryList.h"
00007 #include "osl/category/categoryTraits.h"
00008 #include "osl/category/categoryEnv.h"
00009 #include "osl/category/categoryFlags.h"
00010 #include "osl/container/moveLogProbVector.h"
00011 #include "osl/effect_util/effectUtil.h"
00012
00013 namespace osl
00014 {
00015 namespace container
00016 {
00017 class MoveLogProbVector;
00018 class MoveLogProbSet;
00019 class MoveStack;
00020 }
00021 namespace category
00022 {
00023 using namespace container;
00024 struct CategoryListUtil
00025 {
00026 public:
00031 template <typename Head, typename Tail, typename Function>
00032 static bool forEachCategory(CategoryList<Head,Tail>,
00033 const CategoryEnv& env, Function f);
00037 template <typename Function>
00038 static bool forEachCategory(NullCategory, const CategoryEnv&, Function)
00039 {
00040 return false;
00041 }
00046 template <typename Head, typename Tail, typename Function>
00047 static bool forEachCategory(CategoryList<Head,Tail>,
00048 const CategoryEnv& env, Function f,
00049 CategoryFlags& flags, size_t cur=0);
00050 template <typename Function>
00051 static bool forEachCategory(NullCategory,
00052 const CategoryEnv&, Function,
00053 CategoryFlags&, size_t)
00054 {
00055 return false;
00056 }
00057
00061 template <typename Categories, typename MoveSet>
00062 static void gatherAllMoves(const CategoryEnv& env, MoveSet& out);
00063 private:
00068 template <typename Category, typename Function>
00069 static bool useOneCategory(const CategoryEnv& env, Function f);
00073 template <class Generator>
00074 static void generate(const CategoryEnv&, MoveLogProbVector& out);
00075 };
00076
00077 template <typename Head, typename Tail, typename Function>
00078 bool CategoryListUtil::forEachCategory(CategoryList<Head,Tail>,
00079 const CategoryEnv& env, Function f)
00080 {
00081 const bool try_next =
00082 useOneCategory<Head,Function>(env, f);
00083 if (! try_next)
00084 return true;
00085
00086 if (Head::IsKingEscape
00087 && EffectUtil::isKingInCheck(env.state->getTurn(), *env.state))
00088 return false;
00089
00090 return forEachCategory(Tail(), env, f);
00091 }
00092
00093 template <typename Head, typename Tail, typename Function>
00094 bool CategoryListUtil::forEachCategory(CategoryList<Head,Tail>,
00095 const CategoryEnv& env, Function f,
00096 CategoryFlags& flags, size_t cur)
00097 {
00098 if (! flags.isSet(cur))
00099 {
00100 flags.set(cur);
00101 const bool try_next =
00102 useOneCategory<Head,Function>(env, f);
00103 if (! try_next)
00104 return true;
00105 }
00106
00107
00108 if (Head::IsKingEscape
00109 && EffectUtil::isKingInCheck(env.state->getTurn(), *env.state))
00110 return false;
00111
00112 return forEachCategory(Tail(), env, f, flags, cur+1);
00113 }
00114
00115 }
00116 using category::CategoryListUtil;
00117 }
00118
00119 template <typename Category, typename Function>
00120 bool osl::category::CategoryListUtil::
00121 useOneCategory(const CategoryEnv& env, Function f)
00122 {
00123 if (MinProb<Category>::minProb() > env.limit)
00124 return true;
00125
00126 MoveLogProbVector moves;
00127 generate<Category>(env, moves);
00128
00129 const bool try_next = f.template operator()<Category::IsKingEscape>
00130 (Category::getName(), moves);
00131
00132 return try_next;
00133 }
00134
00135 #endif
00136
00137
00138
00139