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