00001 /* repetitionCounter.h 00002 */ 00003 #ifndef _RepetitionCounter_H 00004 #define _RepetitionCounter_H 00005 00006 #include "osl/move.h" 00007 #include "osl/state/hashEffectState.h" 00008 #include "osl/hash/hashKeyStack.h" 00009 #include "osl/stl/slist.h" 00010 #include "osl/stl/vector.h" 00011 #include "osl/sennichite.h" 00012 #include <boost/scoped_ptr.hpp> 00013 #include <cassert> 00014 #include <iosfwd> 00015 namespace osl 00016 { 00022 class RepetitionCounter 00023 { 00024 class Table; 00025 boost::scoped_ptr<Table> table; 00026 CArray<osl::vector<int>, 2> continuous_check; 00027 HashKeyStack hash_history; 00028 int order() const { return hash_history.size(); } 00029 public: 00030 typedef osl::slist<int> list_t; 00031 00032 RepetitionCounter(); 00033 RepetitionCounter(const RepetitionCounter& c); 00034 explicit RepetitionCounter(const HashEffectState& initial); 00035 RepetitionCounter(const NumEffectState& initial); 00036 ~RepetitionCounter(); 00037 00038 private: 00039 void push(const HashKey& new_key, bool is_check); 00040 public: 00044 void push(const HashEffectState& state, Move move); 00048 void push(const HashEffectState& state); 00052 void push(const HashKey& key, const NumEffectState& state); 00053 void pop(); 00054 void clear(); 00055 00056 const Sennichite isSennichite(const HashEffectState& state, Move move) const; 00057 private: 00058 const Sennichite isAlmostSennichiteUnsafe(int first_move) const 00059 { 00060 assert(first_move >= 0); 00061 const int duration = (order() - first_move) / 2; 00062 if (continuous_check[playerToIndex(BLACK)].back() >= duration) 00063 return Sennichite::BLACK_LOSE(); 00064 if (continuous_check[playerToIndex(WHITE)].back() >= duration) 00065 return Sennichite::WHITE_LOSE(); 00066 return Sennichite::DRAW(); 00067 } 00068 public: 00072 const Sennichite isAlmostSennichite(const HashKey& key) const 00073 { 00074 const int first_move = getFirstMove(key); 00075 if (first_move < 0) 00076 return Sennichite::NORMAL(); 00077 return isAlmostSennichiteUnsafe(first_move); 00078 } 00080 const std::pair<Sennichite,int> distanceToSennichite(const HashKey& key) const; 00081 unsigned int countRepetition(const HashKey&) const; 00082 const list_t getRepetitions(const HashKey&) const; 00083 void printMatches(const HashKey& key) const; 00088 int getLastMove(const HashKey& key) const; 00093 int getFirstMove(const HashKey& key) const; 00094 int checkCount(Player attack) const { 00095 assert(! continuous_check[playerToIndex(attack)].empty()); 00096 return continuous_check[playerToIndex(attack)].back(); 00097 } 00098 const HashKeyStack& history() const { return hash_history; } 00099 bool isConsistent() const; 00100 00101 static bool maybeEqual(const RepetitionCounter& l, const RepetitionCounter& r); 00102 }; 00103 00104 } 00105 00106 #endif /* _RepetitionCounter_H */ 00107 // ;;; Local Variables: 00108 // ;;; mode:c++ 00109 // ;;; c-basic-offset:2 00110 // ;;; End: