00001
00002
00003 #ifndef _SEARCHWINDOW_H
00004 #define _SEARCHWINDOW_H
00005
00006 #include "osl/search/simpleHashRecord.h"
00007 #include "osl/eval/evalTraits.h"
00008 namespace osl
00009 {
00010 namespace search
00011 {
00012 enum TableHit { NO_HIT=0, LOWER_HIT, UPPER_HIT };
00013 struct AlphaBetaWindow
00014 {
00015 int alpha_value, beta_value;
00016 explicit AlphaBetaWindow(int a, int b) : alpha_value(a), beta_value(b)
00017 {
00018 assert(a % 2);
00019 assert(b % 2);
00020 }
00021 int& alpha() { return alpha_value; }
00022 int& beta() { return beta_value; }
00023 int alpha() const { return alpha_value; }
00024 int beta() const { return beta_value; }
00025 const AlphaBetaWindow flipPlayer() const
00026 {
00027 return AlphaBetaWindow(beta(), alpha());
00028 }
00029 bool isConsistent(Player P) const
00030 {
00031 return eval::notLessThan(P, beta(), alpha());
00032 }
00033 bool null() const { return alpha() == beta(); }
00034 void dump() const;
00035 };
00036
00037 template <Player P, class EvalBase>
00038 struct AlphaBetaWindowUtil
00039 {
00040 typedef typename EvalBase::eval_t eval_t;
00044 template <class Recorder>
00045 static
00046 TableHit isOutOfWindow(const SimpleHashRecord& record, int limit,
00047 AlphaBetaWindow& w, int& val,
00048 const Recorder& recorder)
00049 {
00050 #ifdef __APPLE__
00051 int table_value=0;
00052 #else
00053 int table_value;
00054 #endif
00055 if (record.template hasGreaterLowerBound<P>(limit, w.alpha(),
00056 table_value))
00057 {
00058 assert(eval::isConsistentValue(table_value));
00059 w.alpha() = table_value + EvalTraits<P>::delta;
00060 if (EvalTraits<P>::betterThan(table_value, w.beta()))
00061 {
00062 recorder.tableHitLowerBound(P, table_value, w.beta(), limit);
00063 val = table_value;
00064 return LOWER_HIT;
00065 }
00066 }
00067 if (record.template hasLesserUpperBound<P>(limit, w.beta(), table_value))
00068 {
00069 assert(eval::isConsistentValue(table_value));
00070 w.beta() = table_value - EvalTraits<P>::delta;
00071 if (EvalTraits<P>::betterThan(w.alpha(), table_value))
00072 {
00073 recorder.tableHitUpperBound(P, table_value, w.alpha(), limit);
00074 val = table_value;
00075 return UPPER_HIT;
00076 }
00077 }
00078 return NO_HIT;
00079 }
00080 };
00081
00082
00083 struct NullWindow
00084 {
00085 int value;
00086
00087 explicit NullWindow(int v) :value(v)
00088 {
00089 }
00090 int& alpha() { return value; }
00091 int& beta() { return value; }
00092 int alpha() const { return value; }
00093 int beta() const { return value; }
00094 bool isConsistent(Player) const { return true; }
00095 void dump() const;
00096 };
00097
00098 template <Player P, class EvalBase, bool best_move_extension>
00099 struct NullWindowUtil
00100 {
00101 typedef typename EvalBase::eval_t eval_t;
00110 template <class Recorder>
00111 static
00112 TableHit isOutOfWindow(const SimpleHashRecord& record, int limit,
00113 NullWindow w,
00114 int& val, const Recorder& recorder)
00115 {
00116 const int lookUpLimit = (best_move_extension ? limit + 200 : limit);
00117 #ifdef __APPLE__
00118 int table_value=0;
00119 #else
00120 int table_value;
00121 #endif
00122 if (record.template hasGreaterLowerBound<P>
00123 (lookUpLimit, w.beta(), table_value))
00124 {
00125 assert(eval::isConsistentValue(table_value));
00126 recorder.tableHitLowerBound(P, table_value, w.beta(), limit);
00127
00128 val = table_value;
00129 return LOWER_HIT;
00130 }
00131 if (record.template hasLesserUpperBound<P>
00132 (lookUpLimit, w.alpha(), table_value))
00133 {
00134 assert(eval::isConsistentValue(table_value));
00135 recorder.tableHitUpperBound(P, table_value, w.alpha(), limit);
00136
00137 val = table_value;
00138 return UPPER_HIT;
00139 }
00140 return NO_HIT;
00141 }
00142
00143 };
00144
00145 }
00146 }
00147
00148
00149 #endif
00150
00151
00152
00153