00001
00002
00003 #ifndef _SAMEBOARDLIST_H
00004 #define _SAMEBOARDLIST_H
00005
00006 #include "osl/checkmate/checkHashRecord.h"
00007 #include "osl/checkmate/proofDisproof.h"
00008 #include "osl/checkmate/checkAssert.h"
00009 #ifdef CHECKMATE_DEBUG
00010 # include "osl/stat/ratio.h"
00011 #endif
00012 #include "osl/stl/slist.h"
00013
00014 namespace osl
00015 {
00016 namespace checkmate
00017 {
00022 class SameBoardList
00023 {
00024 public:
00025 typedef slist<CheckHashRecord> list_t;
00026 typedef list_t::iterator iterator;
00027 typedef list_t::const_iterator const_iterator;
00028 private:
00029 list_t colleagues;
00030 public:
00031 ~SameBoardList();
00032 void clear();
00033 iterator begin() { return colleagues.begin(); }
00034 iterator end() { return colleagues.end(); }
00035 const_iterator begin() const { return colleagues.begin(); }
00036 const_iterator end() const { return colleagues.end(); }
00037
00038 bool empty() const { return colleagues.empty(); }
00039 size_t size() const { return colleagues.size(); }
00040 size_t confirmNoVisitedRecords() const;
00041 CheckHashRecord *find(const PieceStand& black_stand)
00042 {
00043 for (iterator p=begin(); p!=end(); ++p)
00044 {
00045 if (p->stand(BLACK) == black_stand)
00046 return &*p;
00047 }
00048 return 0;
00049 }
00050 const CheckHashRecord *find(const PieceStand& black_stand) const
00051 {
00052 for (const_iterator p=begin(); p!=end(); ++p)
00053 {
00054 if (p->stand(BLACK) == black_stand)
00055 return &*p;
00056 }
00057 return 0;
00058 }
00059 private:
00060 inline static
00061 void setMoreProvable(unsigned int& proofLL, unsigned int& disproofUL,
00062 const CheckHashRecord *& final_by_dominance,
00063 CheckHashRecord& record);
00064 inline static
00065 void setLessProvable(unsigned int& proofUL, unsigned int& disproofLL,
00066 const CheckHashRecord *& final_by_dominance,
00067 CheckHashRecord& record);
00068 public:
00069 template <Player Attacker>
00070 CheckHashRecord *allocate(const PieceStand& black_stand,
00071 const PieceStand& white_stand,
00072 const PathEncoding& path,
00073 size_t& counter);
00074 CheckHashRecord *allocateSlow(Player attacker,
00075 const PieceStand& black_stand,
00076 const PieceStand& white_stand,
00077 const PathEncoding& path,
00078 size_t& counter);
00083 template <Player Attacker>
00084 const CheckHashRecord *
00085 findIneffectiveDropLoop(const PieceStand& black_stand) const
00086 {
00087 for (list_t::const_iterator p=begin(); p!=end(); ++p)
00088 {
00089 if (p->stand(BLACK) == black_stand)
00090 continue;
00091 if (p->stand(BLACK).template hasMoreThan<Attacker>(black_stand))
00092 {
00093 if (p->isVisited)
00094 {
00095 return &*p;
00096 }
00097 }
00098 }
00099 return 0;
00100 }
00101
00105 template <bool isAttack>
00106 void updateSlow(Player attacker,
00107 CheckHashRecord& record, const PathEncoding& path)
00108 {
00109 if (attacker == BLACK)
00110 {
00111 check_assert(path.turn() == (isAttack ? BLACK : WHITE));
00112 update<isAttack,BLACK>(record, path);
00113 }
00114 else
00115 {
00116 check_assert(path.turn() == (isAttack ? WHITE : BLACK));
00117 update<isAttack,WHITE>(record, path);
00118 }
00119 }
00120 void updateSlow(bool is_attack, Player attacker,
00121 CheckHashRecord& record, const PathEncoding& path);
00122 template <bool isAttack, Player Attacker>
00123 void update(CheckHashRecord& record, const PathEncoding& path);
00124 };
00125 }
00126 }
00127
00128 #endif
00129
00130
00131
00132