00001 /* repetitionCounter.h 00002 */ 00003 #ifndef OSL_REPETITIONCOUNTER_H 00004 #define OSL_REPETITIONCOUNTER_H 00005 00006 #include "osl/numEffectState.h" 00007 #include "osl/hash/hashKeyStack.h" 00008 #include "osl/sennichite.h" 00009 #include <list> 00010 #include <vector> 00011 #include <cassert> 00012 #include <iosfwd> 00013 namespace osl 00014 { 00020 class RepetitionCounter 00021 { 00022 struct Table; 00023 std::unique_ptr<Table> table; 00024 CArray<std::vector<int>, 2> continuous_check; 00025 HashKeyStack hash_history; 00026 int order() const { return hash_history.size(); } 00027 public: 00028 typedef std::list<int> list_t; 00029 00030 RepetitionCounter(); 00031 RepetitionCounter(const RepetitionCounter& c); 00032 explicit RepetitionCounter(const NumEffectState& initial); 00033 ~RepetitionCounter(); 00034 00035 private: 00036 void push(const HashKey& new_key, bool is_check); 00037 public: 00041 void push(const NumEffectState& state, Move move); 00045 void push(const NumEffectState& state); 00049 void push(const HashKey& key, const NumEffectState& state); 00050 void pop(); 00051 void clear(); 00052 00053 const Sennichite isSennichite(const NumEffectState& state, Move move) const; 00054 private: 00055 const Sennichite isAlmostSennichiteUnsafe(int first_move) const 00056 { 00057 assert(first_move >= 0); 00058 const int duration = (order() - first_move) / 2; 00059 if (continuous_check[BLACK].back() >= duration) 00060 return Sennichite::BLACK_LOSE(); 00061 if (continuous_check[WHITE].back() >= duration) 00062 return Sennichite::WHITE_LOSE(); 00063 return Sennichite::DRAW(); 00064 } 00065 public: 00069 const Sennichite isAlmostSennichite(const HashKey& key) const 00070 { 00071 const int first_move = getFirstMove(key); 00072 if (first_move < 0) 00073 return Sennichite::NORMAL(); 00074 return isAlmostSennichiteUnsafe(first_move); 00075 } 00077 const std::pair<Sennichite,int> distanceToSennichite(const HashKey& key) const; 00078 unsigned int countRepetition(const HashKey&) const; 00079 const list_t getRepetitions(const HashKey&) const; 00080 void printMatches(const HashKey& key) const; 00085 int getLastMove(const HashKey& key) const; 00090 int getFirstMove(const HashKey& key) const; 00091 int checkCount(Player attack) const { 00092 assert(! continuous_check[attack].empty()); 00093 return continuous_check[attack].back(); 00094 } 00095 const HashKeyStack& history() const { return hash_history; } 00096 bool isConsistent() const; 00097 00098 static bool maybeEqual(const RepetitionCounter& l, const RepetitionCounter& r); 00099 }; 00100 00101 } 00102 00103 #endif /* OSL_REPETITIONCOUNTER_H */ 00104 // ;;; Local Variables: 00105 // ;;; mode:c++ 00106 // ;;; c-basic-offset:2 00107 // ;;; End: