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