00001
00002
00003
00004
00005
00006
00007 #ifndef GO_CHAIN_H
00008 #define GO_CHAIN_H
00009
00010 #include <iosfwd>
00011 #include "GoBlock.h"
00012 #include "GoBoard.h"
00013 #include "SgBlackWhite.h"
00014 #include "SgPoint.h"
00015 #include "SgVector.h"
00016
00017
00018
00019 class GoRegionBoard;
00020
00021
00022
00023
00024 enum GoChainType
00025 {
00026 GO_CHAIN_TWO_LIBERTIES_IN_REGION,
00027 GO_CHAIN_TWO_SEPARATE_LIBERTIES,
00028 GO_CHAIN_BY_SEARCH,
00029 _GO_CHAIN_COUNT
00030 };
00031
00032 std::ostream& operator<<(std::ostream& stream, GoChainType f);
00033
00034
00035
00036
00037 class GoChainCondition
00038 {
00039 public:
00040
00041
00042 GoChainCondition(GoChainType type)
00043 : m_type(type),
00044 m_lib1(SG_NULLPOINT),
00045 m_lib2(SG_NULLPOINT)
00046 {
00047 SG_ASSERT(type==GO_CHAIN_BY_SEARCH);
00048 }
00049
00050
00051 GoChainCondition(GoChainType type, SgPoint lib1, SgPoint lib2)
00052 : m_type(type),
00053 m_lib1(lib1),
00054 m_lib2(lib2)
00055 {
00056 SG_ASSERT(type == GO_CHAIN_TWO_LIBERTIES_IN_REGION);
00057
00058 }
00059
00060
00061 bool Overlaps(const GoChainCondition& condition) const;
00062
00063
00064 bool Overlaps(const SgVectorOf<GoChainCondition>& conditions) const;
00065
00066
00067 bool UsesLibs() const {return m_type != GO_CHAIN_BY_SEARCH;}
00068
00069 GoChainType Type() const {return m_type;}
00070
00071
00072 SgPoint Lib1() const
00073 {
00074 SG_ASSERT(m_type != GO_CHAIN_BY_SEARCH);
00075 return m_lib1;
00076 }
00077
00078
00079 SgPoint Lib2() const
00080 {
00081 SG_ASSERT(m_type != GO_CHAIN_BY_SEARCH);
00082 return m_lib2;
00083 }
00084
00085 private:
00086
00087 GoChainType m_type;
00088
00089
00090 SgPoint m_lib1, m_lib2;
00091 };
00092
00093 std::ostream& operator<<(std::ostream& stream, const GoChainCondition& c);
00094
00095
00096
00097
00098 class GoChain : public GoBlock
00099 {
00100 public:
00101
00102
00103 GoChain(const GoBlock* b, const GoBoard& board)
00104 : GoBlock(b->Color(), b->Anchor(), board),
00105 m_isSingleBlock(true),
00106 m_freeLiberties(b->Liberties())
00107 { ++s_alloc;
00108 if (b->IsSafe()) SetToSafe();
00109 }
00110
00111
00112 GoChain(const GoChain* c1, const GoChain* c2,
00113 GoChainCondition* cond);
00114
00115
00116 virtual ~GoChain()
00117 {
00118 FreeChainConditions();
00119 ++s_free;
00120 }
00121
00122
00123 void CheckConsistency(const GoBoard& bd) const;
00124
00125
00126 void Write(std::ostream& out) const;
00127
00128
00129 void WriteID(std::ostream& out) const;
00130
00131
00132 virtual bool AllEmptyAreLiberties(const SgPointSet& area) const;
00133
00134
00135 bool IsSingleBlock() const
00136 {
00137 return m_isSingleBlock;
00138 }
00139
00140
00141 void TestFor1Eye(const GoRegionBoard* ra);
00142
00143
00144 const SgPointSet& FreeLiberties() const {return m_freeLiberties;}
00145
00146
00147 const SgVectorOf<GoChainCondition>& ChainConditions() const
00148 {
00149 return m_chainConditions;
00150 }
00151
00152
00153 void GetBlocks(const GoRegionBoard* ra,
00154 SgVectorOf<GoBlock>* blocks) const;
00155
00156
00157 static void Fini();
00158 private:
00159
00160 void FreeChainConditions();
00161
00162
00163 bool m_isSingleBlock;
00164
00165
00166 SgPointSet m_freeLiberties;
00167
00168
00169 SgVectorOf<GoChainCondition> m_chainConditions;
00170
00171
00172 static int s_alloc, s_free;
00173 };
00174
00175 std::ostream& operator<<(std::ostream& stream, const GoChain& c);
00176
00177
00178
00179 #endif // GO_CHAIN_H