00001 //---------------------------------------------------------------------------- 00002 /** @file GoEyeCount.h 00003 Upper and lower bounds on number of eyes and potential eyes. 00004 Also track whether an area can form a local seki. 00005 00006 @todo the implementation of seki support is incomplete. 00007 @todo needs unit test cases. */ 00008 //---------------------------------------------------------------------------- 00009 00010 #ifndef GO_EYECOUNT_H 00011 #define GO_EYECOUNT_H 00012 00013 #include <ostream> 00014 00015 //---------------------------------------------------------------------------- 00016 00017 /** Quick summary of eye status 00018 @todo there are more cases, see Landman's paper 00019 in Games of no Chance. 00020 Will add them later as needed. */ 00021 enum GoEyeStatus 00022 { 00023 EYE_UNKNOWN, 00024 EYE_NONE, 00025 EYE_HALF, 00026 EYE_ONE, 00027 EYE_ONE_AND_HALF, 00028 EYE_TWO 00029 }; 00030 00031 //---------------------------------------------------------------------------- 00032 00033 /** upper and lower bounds on number of eyes and potential eyes */ 00034 class GoEyeCount 00035 { 00036 public: 00037 GoEyeCount() 00038 : m_minEyes(0), 00039 m_maxEyes(0), 00040 m_minPotEyes(0), 00041 m_maxPotEyes(0), 00042 m_isLocalSeki(false), 00043 m_maybeLocalSeki(false) 00044 { } 00045 00046 GoEyeCount(int minEyes, int maxEyes, int minPotEyes, int maxPotEyes) 00047 : m_minEyes(minEyes), 00048 m_maxEyes(maxEyes), 00049 m_minPotEyes(minPotEyes), 00050 m_maxPotEyes(maxPotEyes), 00051 m_isLocalSeki(false), 00052 m_maybeLocalSeki(false) 00053 { } 00054 00055 int MinEyes() const 00056 { 00057 return m_minEyes; 00058 } 00059 00060 int MaxEyes() const 00061 { 00062 return m_maxEyes; 00063 } 00064 00065 int MinPotEyes() const 00066 { 00067 return m_minPotEyes; 00068 } 00069 00070 int MaxPotEyes() const 00071 { 00072 return m_maxPotEyes; 00073 } 00074 00075 bool IsLocalSeki() const 00076 { 00077 return m_isLocalSeki; 00078 } 00079 00080 bool MaybeLocalSeki() const 00081 { 00082 return m_maybeLocalSeki; 00083 } 00084 00085 void Clear() 00086 { 00087 m_minEyes = m_maxEyes = m_minPotEyes = m_maxPotEyes = 0; 00088 } 00089 00090 /** unknown eye count: min = 0, max = 2 */ 00091 void SetUnknown() 00092 { 00093 m_minEyes = m_minPotEyes = 0; 00094 m_maxEyes = m_maxPotEyes = 2; 00095 } 00096 00097 void SetMinEyes(int eyes) 00098 { 00099 m_minEyes = eyes; 00100 } 00101 00102 void SetMaxEyes(int eyes) 00103 { 00104 m_maxEyes = eyes; 00105 } 00106 00107 void SetExactEyes(int eyes) 00108 { 00109 m_minEyes = m_maxEyes = eyes; 00110 } 00111 00112 void SetMinPotEyes(int eyes) 00113 { 00114 m_minPotEyes = eyes; 00115 } 00116 00117 void SetMaxPotEyes(int eyes) 00118 { 00119 m_maxPotEyes = eyes; 00120 } 00121 00122 void SetExactPotEyes(int eyes) 00123 { 00124 m_minPotEyes = m_maxPotEyes = eyes; 00125 } 00126 00127 void SetEyes(int eyes, int potEyes) 00128 { 00129 SetExactEyes(eyes); 00130 SetExactPotEyes(potEyes); 00131 } 00132 00133 /** locally, at least a seki for defender */ 00134 void SetLocalSeki(); 00135 00136 /** Could be a seki for defender but not sure. */ 00137 void SetMaybeLocalSeki() 00138 { 00139 m_maybeLocalSeki = true; 00140 } 00141 00142 /** Make sure all eye counts are <=2 and consistent */ 00143 void Normalize(); 00144 00145 /** Compute total eye count of two independent areas. 00146 This takes sente and gote into account - if there are 00147 two independent gote eyes, then it is one sure eye. */ 00148 void AddIndependent(const GoEyeCount& from); 00149 00150 /** In contrast to AddIndependent, just adds numbers */ 00151 void NumericalAdd(const GoEyeCount& from); 00152 00153 void AddPotential(const GoEyeCount& from); 00154 00155 private: 00156 int m_minEyes; 00157 int m_maxEyes; 00158 int m_minPotEyes; 00159 int m_maxPotEyes; 00160 bool m_isLocalSeki; 00161 bool m_maybeLocalSeki; 00162 }; 00163 00164 std::ostream& operator<<(std::ostream& stream, const GoEyeCount& s); 00165 00166 //---------------------------------------------------------------------------- 00167 00168 #endif // GO_EYECOUNT_H