Index   Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

GoBlock.h

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file GoBlock.h
00003     A block contained in a GoRegionBoard. */
00004 //----------------------------------------------------------------------------
00005 
00006 #ifndef GO_BLOCK_H
00007 #define GO_BLOCK_H
00008 
00009 #include <iosfwd>
00010 #include "GoBoard.h"
00011 #include "GoBoardUtil.h"
00012 #include "SgBlackWhite.h"
00013 #include "SgDebug.h"
00014 #include "SgPoint.h"
00015 #include "SgVector.h"
00016 
00017 class GoRegion;
00018 
00019 //----------------------------------------------------------------------------
00020 
00021 /** A block augmented by a list of its healthy regions.
00022     Used together with GoRegion in GoRegionBoard.
00023     @todo Avoid cyclic dependency with GoBlock */
00024 class GoBlock
00025 {
00026 public:
00027     /** GoBlock Constructor
00028         Parameters:
00029         color: color of block
00030         anchor: stone identifying block
00031         board: the board we are on */
00032     GoBlock(SgBlackWhite color, SgPoint anchor, const GoBoard& board)
00033         : m_has1Eye(false),
00034           m_bd(board),
00035           m_color(color),
00036           m_anchor(anchor),
00037           m_isSafe(false)
00038     {
00039         ++s_alloc;
00040         for (GoBoard::StoneIterator it(board, anchor); it; ++it)
00041             m_stones.Include(*it);
00042     }
00043 
00044     /** Destructor */
00045     virtual ~GoBlock(){ ++s_free;}
00046 
00047     /** For debugging */
00048     void CheckConsistency() const;
00049 
00050     /** Write data for block */
00051     virtual void Write(std::ostream& out) const;
00052 
00053     /** Write short identifier for block */
00054     virtual void WriteID(std::ostream& out) const;
00055 
00056     // Accessors
00057     SgBlackWhite Color() const
00058     {
00059         return m_color;
00060     }
00061 
00062     /** The unique stone with smallest number identifying a block */
00063     SgPoint Anchor() const
00064     {
00065         return m_anchor;
00066     }
00067 
00068     /** set of all stones */
00069     const SgPointSet& Stones() const
00070     {
00071         return m_stones;
00072     }
00073 
00074     /** number of liberties */
00075     int NuLiberties() const
00076     {
00077         return m_bd.NumLiberties(m_anchor);
00078     }
00079 
00080     /** set of all liberties
00081         @todo slow */
00082     SgPointSet Liberties() const
00083     {
00084         return m_stones.Border(m_bd.Size()) & m_bd.AllEmpty();
00085     }
00086 
00087     /** is block proven safe? */
00088     bool IsSafe() const
00089     {
00090         return m_isSafe;
00091     }
00092 
00093     /** Are all empty points in area our liberties? */
00094     virtual bool AllEmptyAreLiberties(const SgPointSet& area) const;
00095 
00096     /** is lib our liberty? */
00097     bool HasLiberty(SgPoint lib) const
00098     {
00099         return m_bd.IsLibertyOfBlock(lib, m_anchor);
00100     }
00101 
00102     /** Does block have a simple eye? */
00103     bool Has1Eye() const
00104     {
00105         return m_has1Eye;
00106     }
00107 
00108     /** Mark block as proven safe */
00109     void SetToSafe()
00110     {
00111         m_isSafe = true;
00112     }
00113 
00114     /** compute if block has 1 clear eye, if yes set the m_has1Eye flag */
00115     void TestFor1Eye(const GoRegion* r);
00116 
00117     /** Clear previous computation */
00118     virtual void ReInitialize()
00119     {
00120         m_isSafe = false;
00121         m_has1Eye = false;
00122         m_healthy.Clear();
00123     }
00124 
00125     /** For incremental computation: add stone to block */
00126     void AddStone(SgPoint stone);
00127 
00128     /** For undo: remove added stone */
00129     void RemoveStone(SgPoint stone);
00130 
00131     /** r is healthy for this */
00132     void AddHealthy(GoRegion* r)
00133     {
00134         if (! m_healthy.Contains(r))
00135             m_healthy.PushBack(r);
00136 #ifndef NDEBUG
00137         else
00138             // @todo debug me! see case 1540-1550 in uct_move.tst
00139             // seems to happen after same position recomputed with second
00140             // color.
00141             SgDebug() << "DOUBLE ADD " << r << '\n';
00142 #endif
00143     }
00144 
00145     /** For incremental computation: r is no longer a neighbor region */
00146     void RemoveRegion(GoRegion* r)
00147     {
00148         m_healthy.Exclude(r);
00149     }
00150     // @todo keep all regions stored.
00151 
00152     /** is r in our healthy list? */
00153     bool ContainsHealthy(const GoRegion* r) const
00154     {
00155         return m_healthy.Contains(r);
00156     }
00157 
00158     /** list of healthy regions */
00159     const SgVectorOf<GoRegion>& Healthy() const
00160     {
00161         return m_healthy;
00162     }
00163 
00164     /** class finalization */
00165     static void Fini();
00166 
00167 protected:
00168     /** list of healthy regions */
00169     SgVectorOf<GoRegion> m_healthy;
00170 
00171     /** does block have one eye? */
00172     bool m_has1Eye;
00173 
00174     /** board */
00175     const GoBoard& m_bd;
00176 
00177     /** This constructor used only in GoChain constructor
00178         Stones is set to the union of the merged chains. */
00179     GoBlock(const GoBlock* b, const SgPointSet& stones,
00180            const SgVectorOf<GoRegion>& healthy)
00181         : m_healthy(healthy),
00182           m_has1Eye(false),
00183           m_bd(b->m_bd),
00184           m_color(b->Color()),
00185           m_stones(stones),
00186           m_anchor(SG_NULLPOINT),
00187           m_isSafe(false)
00188 
00189     {
00190         ++s_alloc;
00191     }
00192 
00193 private:
00194     /** Color of block */
00195     SgBlackWhite m_color;
00196 
00197     /** Stones of block */
00198     SgPointSet m_stones;
00199 
00200     /** Anchor*/
00201     SgPoint m_anchor;
00202 
00203     /** Is block marked as safe? */
00204     bool m_isSafe;
00205 
00206     /** Bookkeeping for debugging */
00207     static int s_alloc, s_free;
00208     // AR add m_healthy2 for 2 sure liberty regions?
00209 };
00210 
00211 std::ostream& operator<<(std::ostream& stream, const GoBlock& b);
00212 
00213 //----------------------------------------------------------------------------
00214 
00215 #endif // GO_BLOCK_H


Sun Mar 13 2011 Doxygen 1.7.1