00001 /* repetitionCounter.h 00002 */ 00003 #ifndef _RepetitionCounter_H 00004 #define _RepetitionCounter_H 00005 00006 #include "osl/move.h" 00007 #include "osl/state/numEffectState.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 NumEffectState& initial); 00035 ~RepetitionCounter(); 00036 00037 private: 00038 void push(const HashKey& new_key, bool is_check); 00039 public: 00043 void push(const NumEffectState& state, Move move); 00047 void push(const NumEffectState& state); 00051 void push(const HashKey& key, const NumEffectState& state); 00052 void pop(); 00053 void clear(); 00054 00055 const Sennichite isSennichite(const NumEffectState& state, Move move) const; 00056 private: 00057 const Sennichite isAlmostSennichiteUnsafe(int first_move) const 00058 { 00059 assert(first_move >= 0); 00060 const int duration = (order() - first_move) / 2; 00061 if (continuous_check[BLACK].back() >= duration) 00062 return Sennichite::BLACK_LOSE(); 00063 if (continuous_check[WHITE].back() >= duration) 00064 return Sennichite::WHITE_LOSE(); 00065 return Sennichite::DRAW(); 00066 } 00067 public: 00071 const Sennichite isAlmostSennichite(const HashKey& key) const 00072 { 00073 const int first_move = getFirstMove(key); 00074 if (first_move < 0) 00075 return Sennichite::NORMAL(); 00076 return isAlmostSennichiteUnsafe(first_move); 00077 } 00079 const std::pair<Sennichite,int> distanceToSennichite(const HashKey& key) const; 00080 unsigned int countRepetition(const HashKey&) const; 00081 const list_t getRepetitions(const HashKey&) const; 00082 void printMatches(const HashKey& key) const; 00087 int getLastMove(const HashKey& key) const; 00092 int getFirstMove(const HashKey& key) const; 00093 int checkCount(Player attack) const { 00094 assert(! continuous_check[attack].empty()); 00095 return continuous_check[attack].back(); 00096 } 00097 const HashKeyStack& history() const { return hash_history; } 00098 bool isConsistent() const; 00099 00100 static bool maybeEqual(const RepetitionCounter& l, const RepetitionCounter& r); 00101 }; 00102 00103 } 00104 00105 #endif /* _RepetitionCounter_H */ 00106 // ;;; Local Variables: 00107 // ;;; mode:c++ 00108 // ;;; c-basic-offset:2 00109 // ;;; End: