00001 //---------------------------------------------------------------------------- 00002 /** @file GoKomi.h */ 00003 //---------------------------------------------------------------------------- 00004 00005 #ifndef GO_KOMI_H 00006 #define GO_KOMI_H 00007 00008 #include <string> 00009 #include "SgException.h" 00010 00011 //---------------------------------------------------------------------------- 00012 00013 /** Class wrapping a komi value. 00014 Supported komi values are "unknown" or multiples of 0.5. 00015 */ 00016 class GoKomi 00017 { 00018 public: 00019 /** Exception thrown if komi is constructed with invalid value. */ 00020 class InvalidKomi 00021 : public SgException 00022 { 00023 public: 00024 /** Constructor. 00025 @param komi The invalid komi value. 00026 */ 00027 InvalidKomi(float komi); 00028 00029 /** Constructor. 00030 @param komi The invalid komi value. 00031 */ 00032 InvalidKomi(const std::string& komi); 00033 }; 00034 00035 /** Construct komi with unknown value. */ 00036 GoKomi(); 00037 00038 /** Construct komi from float. 00039 @param komi The komi, will be rounded to a multiple of 0.5. 00040 */ 00041 GoKomi(float komi); 00042 00043 /** Construct komi from string. 00044 @param komi The string, leading and trailing whitespaces will be 00045 ignored, empty for unknown komi, float otherwise. The float will be 00046 rounded to a multiple of 0.5. 00047 @throws InvalidKomi If string is not empty or contains a float. 00048 */ 00049 GoKomi(const std::string& komi); 00050 00051 GoKomi& operator=(const GoKomi& komi); 00052 00053 bool operator==(const GoKomi& komi) const; 00054 00055 bool operator!=(const GoKomi& komi) const; 00056 00057 /** Check if komi is unknown. 00058 @return true, if komi has unknown value. 00059 */ 00060 bool IsUnknown() const; 00061 00062 /** Convert komi to float. 00063 @return The komi value as a float, zero if komi is unknown. 00064 */ 00065 float ToFloat() const; 00066 00067 /** Convert komi to string. 00068 @return The komi value as a string, empty string if komi is unknown. 00069 */ 00070 std::string ToString() const; 00071 00072 private: 00073 bool m_isUnknown; 00074 00075 /** Komi value stored as integer. 00076 Corresponds to the real komi multiplied by two. 00077 */ 00078 int m_value; 00079 }; 00080 00081 inline std::ostream& operator<<(std::ostream& out, const GoKomi& komi) 00082 { 00083 out << komi.ToString(); 00084 return out; 00085 } 00086 00087 inline GoKomi::GoKomi() 00088 : m_isUnknown(true), 00089 m_value(0) 00090 { 00091 } 00092 00093 inline GoKomi::GoKomi(float komi) 00094 : m_isUnknown(false), 00095 m_value(static_cast<int>(komi > 0 ? 00096 komi * 2.f + 0.25f : komi * 2.f - 0.25f)) 00097 { 00098 } 00099 00100 inline GoKomi& GoKomi::operator=(const GoKomi& komi) 00101 { 00102 m_isUnknown = komi.m_isUnknown; 00103 m_value = komi.m_value; 00104 return *this; 00105 } 00106 00107 inline bool GoKomi::operator==(const GoKomi& komi) const 00108 { 00109 return (m_isUnknown == komi.m_isUnknown && m_value == komi.m_value); 00110 } 00111 00112 inline bool GoKomi::operator!=(const GoKomi& komi) const 00113 { 00114 return ! (*this == komi); 00115 } 00116 00117 inline bool GoKomi::IsUnknown() const 00118 { 00119 return m_isUnknown; 00120 } 00121 00122 inline float GoKomi::ToFloat() const 00123 { 00124 if (m_isUnknown) 00125 return 0.f; 00126 else 00127 return 0.5f * m_value; 00128 } 00129 00130 //---------------------------------------------------------------------------- 00131 00132 #endif // GO_KOMI_H 00133