Go to the documentation of this file.00001
00002
00003 #ifndef OSL_SEARCHBASE_H
00004 #define OSL_SEARCHBASE_H
00005
00006 #include "osl/search/searchRecorder.h"
00007 #include "osl/search/searchTable.h"
00008 #include "osl/search/realizationProbability.h"
00009 #include "osl/search/simpleHashRecord.h"
00010 #include "osl/search/searchWindow.h"
00011 #include "osl/search/fixedEval.h"
00012 #include "osl/hash/hashCollision.h"
00013 #include "osl/hash/hashKey.h"
00014 #include "osl/state/numEffectState.h"
00015 #include <cassert>
00016 namespace osl
00017 {
00018 namespace search
00019 {
00020 class SimpleHashTable;
00021
00026 template<typename Eval,
00027 typename Table, typename Recorder, typename Probabilities>
00028 struct SearchBase : protected FixedEval
00029 {
00030
00031 typedef Eval eval_t;
00032
00033 typedef Probabilities Probabilities_t;
00034 protected:
00035 Recorder& recorder;
00036 Table *table;
00037 public:
00038 SearchBase(Recorder& r, Table *t)
00039 : recorder(r), table(t)
00040 {
00041 assert(table);
00042 assert(winThreshold(BLACK) > eval_t::infty());
00043 }
00044 virtual ~SearchBase() {}
00045 virtual bool abort(Move) const { return false; }
00046
00055 bool validTableMove(const NumEffectState& state,
00056 const MoveLogProb& move, int limit) const
00057 {
00058 if ((limit < move.logProb()) || (! move.validMove()))
00059 return false;
00060 if (! move.isNormal())
00061 return false;
00062 const bool valid
00063 = ((move.player() == state.turn())
00064 && state.isAlmostValidMove<false>(move.move()));
00065 if (! valid)
00066 {
00067
00068 recorder.recordInvalidMoveInTable(state, move, limit);
00069 throw hash::HashCollision();
00070 }
00071 return valid;
00072 }
00073 private:
00074 void recordCheckmateResult(Player P, SimpleHashRecord *record,
00075 int val, Move move) const
00076 {
00077 assert(isWinValue(P,val) || isWinValue(alt(P),val));
00078 const int limit = SearchTable::CheckmateSpecialDepth;
00079 const MoveLogProb best_move(move, 101);
00080 recorder.tableStoreLowerBound(P, best_move, val, limit);
00081 recorder.tableStoreUpperBound(P, best_move, val, limit);
00082 record->setAbsoluteValue(best_move.move(), val,
00083 SearchTable::CheckmateSpecialDepth);
00084 }
00085 public:
00087 void recordWinByCheckmate(Player P, SimpleHashRecord *record,
00088 Move check_move) const
00089 {
00090 assert(record);
00091 recordCheckmateResult(P, record, winByCheckmate(P), check_move);
00092 }
00094 void recordLoseByCheckmate(Player P, SimpleHashRecord *record) const
00095 {
00096 assert(record);
00097 recordCheckmateResult(P, record, winByCheckmate(alt(P)), Move::INVALID());
00098 }
00099
00100 using FixedEval::isWinValue;
00101 using FixedEval::winByCheckmate;
00102 using FixedEval::winByFoul;
00103 using FixedEval::winByLoop;
00104 using FixedEval::minusInfty;
00105 using FixedEval::drawValue;
00106
00107 };
00108 }
00109 }
00110
00111
00112 #endif
00113
00114
00115
00116