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


17 Jun 2010 Doxygen 1.4.7