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