00001
00002
00003
00004
00005
00006
00007 #include "SgSystem.h"
00008 #include "GoChain.h"
00009
00010 #include <iostream>
00011 #include "GoBlock.h"
00012 #include "GoRegion.h"
00013 #include "GoRegionBoard.h"
00014 #include "SgWrite.h"
00015
00016
00017
00018 GoChain::GoChain(const GoChain* c1, const GoChain* c2,
00019 GoChainCondition* cond) :
00020 GoBlock(c1, c1->Stones() | c2->Stones(),
00021 c1->Healthy()),
00022 m_isSingleBlock(false),
00023 m_freeLiberties(c1->FreeLiberties() | c2->FreeLiberties())
00024 {
00025 ++s_alloc;
00026 SG_ASSERT(c1 != c2);
00027 m_healthy.Union(c2->Healthy());
00028 SG_ASSERT(! cond->Overlaps(m_chainConditions));
00029 m_chainConditions.PushBack(cond);
00030
00031 if (cond->UsesLibs())
00032 {
00033 SG_ASSERT(m_freeLiberties.Contains(cond->Lib1()));
00034 m_freeLiberties.Exclude(cond->Lib1());
00035 SG_ASSERT(m_freeLiberties.Contains(cond->Lib2()));
00036 m_freeLiberties.Exclude(cond->Lib2());
00037 }
00038 }
00039
00040 void GoChain::TestFor1Eye(const GoRegionBoard* ra)
00041 {
00042 SgVectorOf<GoBlock> blocks;
00043 GetBlocks(ra, &blocks);
00044 for (SgVectorIteratorOf<GoBlock> it(blocks); it; ++it)
00045 if ((*it)->Has1Eye())
00046 {
00047 m_has1Eye = true;
00048 return;
00049 }
00050
00051 for (SgVectorIteratorOf<GoRegion> it(ra->AllRegions(Color())); it; ++it)
00052 if ((*it)->GetFlag(GO_REGION_1VC) && (*it)->Chains().Contains(this))
00053 {
00054 m_has1Eye = true;
00055 return;
00056 }
00057
00058 m_has1Eye = false;
00059 }
00060
00061 void GoChain::FreeChainConditions()
00062 {
00063 for (SgVectorIteratorOf<GoChainCondition> it(m_chainConditions); it; ++it)
00064 delete *it;
00065 m_chainConditions.Clear();
00066 }
00067
00068 void GoChain::GetBlocks(const GoRegionBoard* ra,
00069 SgVectorOf<GoBlock>* blocks) const
00070 {
00071 SgBlackWhite color = Color();
00072 SgPointSet chainPts = Stones();
00073 for (SgVectorIteratorOf<GoBlock> it(ra->AllBlocks(color)); it; ++it)
00074 if (chainPts.Contains((*it)->Anchor()))
00075 blocks->PushBack(*it);
00076 }
00077
00078 bool GoChain::AllEmptyAreLiberties(const SgPointSet& area) const
00079 {
00080 return (area & m_bd.AllEmpty()).SubsetOf(Liberties());
00081 }
00082
00083 void GoChain::WriteID(std::ostream& stream) const
00084 {
00085 stream << ' '<< SgBW(Color()) << " GoChain "
00086 << SgWritePoint(Anchor());
00087 }
00088
00089 void GoChain::Fini()
00090 {
00091 SG_ASSERT(s_alloc == s_free);
00092 }
00093
00094 void GoChain::Write(std::ostream& stream) const
00095 {
00096 GoBlock::Write(stream);
00097 stream << "Chain conditions: ";
00098 for (SgVectorIteratorOf<GoChainCondition> it(ChainConditions()); it; ++it)
00099 stream << **it;
00100 if (ChainConditions().IsEmpty())
00101 stream << "none";
00102 stream << '\n';
00103 }
00104
00105
00106
00107 int GoChain::s_alloc = 0;
00108 int GoChain::s_free = 0;
00109
00110
00111
00112 std::ostream& operator<<(std::ostream& stream, const GoChain& c)
00113 {
00114 c.Write(stream);
00115 return stream;
00116 }
00117
00118
00119
00120 bool GoChainCondition::Overlaps(const GoChainCondition& condition) const
00121 {
00122 if (! UsesLibs() || ! condition.UsesLibs())
00123 return false;
00124
00125 return m_lib1 == condition.m_lib1
00126 || m_lib1 == condition.m_lib2
00127 || m_lib2 == condition.m_lib1
00128 || m_lib2 == condition.m_lib2;
00129 }
00130
00131 bool GoChainCondition::Overlaps(const SgVectorOf<GoChainCondition>&
00132 conditions) const
00133 {
00134 for (SgVectorIteratorOf<GoChainCondition> it(conditions); it; ++it)
00135 {
00136 if (Overlaps(**it))
00137 return true;
00138 }
00139 return false;
00140 }
00141
00142
00143
00144 std::ostream& operator<<(std::ostream& stream, GoChainType f)
00145 {
00146 static const char* s_string[_GO_CHAIN_COUNT] =
00147 {
00148 "GO_CHAIN_TWO_LIBERTIES_IN_REGION",
00149 "GO_CHAIN_TWO_SEPARATE_LIBERTIES",
00150 "GO_CHAIN_BY_SEARCH"
00151 };
00152
00153 stream << s_string[f];
00154 return stream;
00155 }
00156
00157
00158
00159 std::ostream& operator<<(std::ostream& stream, const GoChainCondition& c)
00160 {
00161 stream << " GoChainCondition: type = " << c.Type();
00162 if (c.UsesLibs())
00163 stream << ", lib1 = " << SgWritePoint(c.Lib1())
00164 << ", lib2 = " << SgWritePoint(c.Lib2());
00165 return stream;
00166 }
00167
00168
00169