00001
00002
00003
00004
00005
00006
00007 #ifndef GO_BLOCK_H
00008 #define GO_BLOCK_H
00009
00010 #include <iosfwd>
00011 #include "GoBoard.h"
00012 #include "GoBoardUtil.h"
00013 #include "SgBlackWhite.h"
00014 #include "SgDebug.h"
00015 #include "SgPoint.h"
00016 #include "SgVector.h"
00017
00018 class GoRegion;
00019
00020
00021
00022
00023
00024
00025
00026 class GoBlock
00027 {
00028 public:
00029
00030
00031
00032
00033
00034
00035 GoBlock(SgBlackWhite color, SgPoint anchor, const GoBoard& board)
00036 : m_has1Eye(false),
00037 m_bd(board),
00038 m_color(color),
00039 m_anchor(anchor),
00040 m_isSafe(false)
00041 {
00042 ++s_alloc;
00043 for (GoBoard::StoneIterator it(board, anchor); it; ++it)
00044 m_stones.Include(*it);
00045 }
00046
00047
00048 virtual ~GoBlock(){ ++s_free;}
00049
00050
00051 void CheckConsistency() const;
00052
00053
00054 virtual void Write(std::ostream& out) const;
00055
00056
00057 virtual void WriteID(std::ostream& out) const;
00058
00059
00060 SgBlackWhite Color() const
00061 {
00062 return m_color;
00063 }
00064
00065
00066 SgPoint Anchor() const
00067 {
00068 return m_anchor;
00069 }
00070
00071
00072 const SgPointSet& Stones() const
00073 {
00074 return m_stones;
00075 }
00076
00077
00078 int NuLiberties() const
00079 {
00080 return m_bd.NumLiberties(m_anchor);
00081 }
00082
00083
00084
00085
00086 SgPointSet Liberties() const
00087 {
00088 return m_stones.Border(m_bd.Size()) & m_bd.AllEmpty();
00089 }
00090
00091
00092 bool IsSafe() const
00093 {
00094 return m_isSafe;
00095 }
00096
00097
00098 virtual bool AllEmptyAreLiberties(const SgPointSet& area) const;
00099
00100
00101 bool HasLiberty(SgPoint lib) const
00102 {
00103 return m_bd.IsLibertyOfBlock(lib, m_anchor);
00104 }
00105
00106
00107 bool Has1Eye() const
00108 {
00109 return m_has1Eye;
00110 }
00111
00112
00113 void SetToSafe()
00114 {
00115 m_isSafe = true;
00116 }
00117
00118
00119 void TestFor1Eye(const GoRegion* r);
00120
00121
00122 virtual void ReInitialize()
00123 {
00124 m_isSafe = false;
00125 m_has1Eye = false;
00126 m_healthy.Clear();
00127 }
00128
00129
00130 void AddStone(SgPoint stone);
00131
00132
00133 void RemoveStone(SgPoint stone);
00134
00135
00136 void AddHealthy(GoRegion* r)
00137 {
00138 if (! m_healthy.Contains(r))
00139 m_healthy.PushBack(r);
00140 #ifndef NDEBUG
00141 else
00142
00143
00144
00145 SgDebug() << "DOUBLE ADD " << r << '\n';
00146 #endif
00147 }
00148
00149
00150 void RemoveRegion(GoRegion* r)
00151 {
00152 m_healthy.Exclude(r);
00153 }
00154
00155
00156
00157 bool ContainsHealthy(const GoRegion* r) const
00158 {
00159 return m_healthy.Contains(r);
00160 }
00161
00162
00163 const SgVectorOf<GoRegion>& Healthy() const
00164 {
00165 return m_healthy;
00166 }
00167
00168
00169 static void Fini();
00170
00171 protected:
00172
00173 SgVectorOf<GoRegion> m_healthy;
00174
00175
00176 bool m_has1Eye;
00177
00178
00179 const GoBoard& m_bd;
00180
00181
00182
00183
00184 GoBlock(const GoBlock* b, const SgPointSet& stones,
00185 const SgVectorOf<GoRegion>& healthy)
00186 : m_healthy(healthy),
00187 m_has1Eye(false),
00188 m_bd(b->m_bd),
00189 m_color(b->Color()),
00190 m_stones(stones),
00191 m_anchor(SG_NULLPOINT),
00192 m_isSafe(false)
00193
00194 {
00195 ++s_alloc;
00196 }
00197
00198 private:
00199
00200 SgBlackWhite m_color;
00201
00202
00203 SgPointSet m_stones;
00204
00205
00206 SgPoint m_anchor;
00207
00208
00209 bool m_isSafe;
00210
00211
00212 static int s_alloc, s_free;
00213
00214 };
00215
00216 std::ostream& operator<<(std::ostream& stream, const GoBlock& b);
00217
00218
00219
00220 #endif // GO_BLOCK_H