00001 //---------------------------------------------------------------------------- 00002 /** @file GoBlock.cpp 00003 See GoBlock.h. 00004 */ 00005 //---------------------------------------------------------------------------- 00006 00007 #include "SgSystem.h" 00008 #include "GoBlock.h" 00009 00010 #include <iostream> 00011 #include "GoRegion.h" 00012 #include "SgPointSetUtil.h" 00013 #include "SgWrite.h" 00014 00015 //---------------------------------------------------------------------------- 00016 00017 static const bool CHECK = SG_CHECK && true; 00018 static const bool HEAVYCHECK = SG_HEAVYCHECK && CHECK && false; 00019 00020 //---------------------------------------------------------------------------- 00021 00022 int GoBlock::s_alloc = 0; 00023 int GoBlock::s_free = 0; 00024 00025 void GoBlock::AddStone(SgPoint stone) 00026 { 00027 if (HEAVYCHECK) 00028 SG_ASSERT(! m_stones.Contains(stone)); 00029 m_stones.Include(stone); 00030 if (stone < m_anchor) 00031 { 00032 if (HEAVYCHECK) 00033 SG_ASSERT(stone == m_bd.Anchor(m_anchor)); 00034 m_anchor = stone; 00035 } 00036 } 00037 00038 void GoBlock::RemoveStone(SgPoint stone) 00039 { 00040 if (HEAVYCHECK) 00041 SG_ASSERT(m_stones.Contains(stone)); 00042 m_stones.Exclude(stone); 00043 if (stone == m_anchor) 00044 m_anchor = m_bd.Anchor(m_stones.PointOf()); 00045 } 00046 00047 bool GoBlock::AllEmptyAreLiberties(const SgPointSet& area) const 00048 { 00049 const SgPoint anchor = Anchor(); 00050 for (SgSetIterator it(area); it; ++it) 00051 if ( m_bd.IsEmpty(*it) 00052 && ! m_bd.IsLibertyOfBlock(*it, anchor) 00053 ) 00054 return false; 00055 return true; 00056 } 00057 00058 void GoBlock::TestFor1Eye(const GoRegion* r) 00059 { 00060 if (r->GetFlag(GO_REGION_SMALL) && r->Blocks().IsLength(1)) 00061 // @todo what if more than one block? 00062 { 00063 m_has1Eye = true; 00064 } 00065 } 00066 00067 void GoBlock::CheckConsistency() const 00068 { 00069 SG_ASSERT(Stones().SubsetOf(m_bd.All(Color()))); 00070 SgPoint anchor = Anchor(); 00071 SG_ASSERT(m_bd.Anchor(anchor) == Anchor()); 00072 SgPointSet stones; 00073 for (GoBoard::StoneIterator it(m_bd, anchor); it; ++it) 00074 stones.Include(*it); 00075 SG_ASSERT(Stones() == stones); 00076 } 00077 00078 void GoBlock::Fini() 00079 { 00080 SG_ASSERT(s_alloc == s_free); 00081 } 00082 00083 void GoBlock::Write(std::ostream& stream) const 00084 { 00085 WriteID(stream); 00086 stream << '\n' 00087 << SgWritePointSet(Stones(), "Stones: ") 00088 << "\nhealthy: " << Healthy().Length() 00089 << "\nisSafe: " << SgWriteBoolean(IsSafe()) 00090 << "\nhas1Eye: " << SgWriteBoolean(Has1Eye()) 00091 << "\n"; 00092 } 00093 00094 void GoBlock::WriteID(std::ostream& stream) const 00095 { 00096 stream << ' ' << SgBW(Color()) 00097 << " Block " << SgWritePoint(Anchor()); 00098 } 00099 00100 //---------------------------------------------------------------------------- 00101 00102 std::ostream& operator<<(std::ostream& stream, const GoBlock& b) 00103 { 00104 b.Write(stream); 00105 return stream; 00106 } 00107 00108 //----------------------------------------------------------------------------