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