00001 //---------------------------------------------------------------------------- 00002 /** @file GoChain.cpp 00003 See GoChain.h. */ 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; // AR needs some other check. 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