Index   Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

GoRegionBoard.h

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file GoRegionBoard.h
00003     A GoRegionBoard provides the connected components of a GoBoard. */
00004 //----------------------------------------------------------------------------
00005 
00006 #ifndef GO_REGIONBOARD_H
00007 #define GO_REGIONBOARD_H
00008 
00009 #include "GoBoard.h"
00010 #include "GoRegion.h"
00011 
00012 class GoBlock;
00013 class GoChain;
00014 
00015 //----------------------------------------------------------------------------
00016 
00017 /** GoRegionBoard provides GoRegion, GoBlock and optionally GoChain.
00018     To keep it updated during search, call OnExecutedMove
00019     (or OnExecutedUncodedMove) and OnUndoneMove when Executing/Undoing a move.
00020 
00021     A GoRegionBoard depends on a GoBoard (supplied at construction)
00022     for keeping the low-level board state, Go rules etc.
00023 
00024     There is a certain amount of duplication between the private blocks of a
00025     GoBoard and the GoBlock's in a GoRegionBoard.
00026 
00027     GoChain's are not updated automatically for performance reasons
00028     - call GenChains() to update them. */
00029 class GoRegionBoard
00030 {
00031 public:
00032 
00033     /** Constructor */
00034     explicit GoRegionBoard(const GoBoard& board);
00035 
00036     /** release memory. Calls Clear() */
00037     virtual ~GoRegionBoard();
00038 
00039     /** delete all blocks and regions, set board size */
00040     void Clear();
00041 
00042     /** For debugging */
00043     void CheckConsistency() const;
00044 
00045     /** Have blocks and regions been computed for current board position? */
00046     bool UpToDate() const
00047     {
00048         return    ! m_invalid
00049                && m_boardSize == m_board.Size()
00050                && m_code == Board().GetHashCode();
00051     }
00052     
00053     bool ComputedHealthy() const
00054     {
00055         return m_computedHealthy;
00056     }
00057 
00058     /** Have chains been computed for current board position? */
00059     bool ChainsUpToDate() const
00060     {
00061         return UpToDate() && m_chainsCode == Board().GetHashCode();
00062     }
00063 
00064     /** MUST call before playing move on GoBoard */
00065     void ExecuteMovePrologue();
00066 
00067     /** Called after a move or added stone has been successfully executed.
00068         The board is guaranteed to be in a legal state. */
00069     void OnExecutedMove(GoPlayerMove playerMove);
00070 
00071     /** Similar to OnExecutedMove, but move is not coded into one int. */
00072     void OnExecutedUncodedMove(int move, SgBlackWhite moveColor);
00073 
00074     /** Called after a move has been undone.
00075         The board is guaranteed to be in a legal state. */
00076     void OnUndoneMove();
00077 
00078     /** All GoBlock's of given color */
00079     SgVectorOf<GoBlock>& AllBlocks(SgBlackWhite color)
00080     {
00081         return m_allBlocks[color];
00082     }
00083 
00084     /** All GoBlock's of given color */
00085     const SgVectorOf<GoBlock>& AllBlocks(SgBlackWhite color) const
00086     {
00087         return m_allBlocks[color];
00088     }
00089 
00090     /** All GoChain's of given color */
00091     SgVectorOf<GoChain>& AllChains(SgBlackWhite color)
00092     {
00093         return m_allChains[color];
00094     }
00095 
00096     /** All GoChain's of given color */
00097     const SgVectorOf<GoChain>& AllChains(SgBlackWhite color) const
00098     {
00099         return m_allChains[color];
00100     }
00101 
00102     /** All GoRegion's of given color */
00103     SgVectorOf<GoRegion>& AllRegions(SgBlackWhite color)
00104     {
00105         return m_allRegions[color];
00106     }
00107 
00108     /** All GoRegion's of given color */
00109     const SgVectorOf<GoRegion>& AllRegions(SgBlackWhite color) const
00110     {
00111         return m_allRegions[color];
00112     }
00113 
00114     /** See GoBoard::All */
00115     const SgPointSet& All(SgBlackWhite color) const
00116     {
00117         return Board().All(color);
00118     }
00119 
00120     /** See GoBoard::AllEmpty */
00121     const SgPointSet& AllEmpty() const {return Board().AllEmpty();}
00122 
00123     /** See GoBoard::AllPoints */
00124     const SgPointSet& AllPoints() const {return Board().AllPoints();}
00125 
00126     /** See GoBoard::IsColor */
00127     bool IsColor(SgPoint p, int c) const {return Board().IsColor(p, c);}
00128 
00129     /** write information on all GoBlock's */
00130     void WriteBlocks(std::ostream& stream) const;
00131 
00132     /** write information on all GoRegion's */
00133     void WriteRegions(std::ostream& stream) const;
00134 
00135     /** generate all blocks and regions */
00136     void GenBlocksRegions();
00137 
00138     /** Compute all GoChain's
00139         @todo currently this only creates 1 chain for each block.
00140         The merging is only done in GoSafetySolver::GenBlocksRegions()
00141         and must be moved here. */
00142     void GenChains();
00143 
00144     /** Clear all flags etc. to recompute regions and blocks */
00145     void ReInitializeBlocksRegions();
00146 
00147     /** mark all regions that the given attribute has been computed */
00148     void SetComputedFlagForAll(GoRegionFlag flag);
00149 
00150     const GoBoard& Board() const
00151     {
00152         return m_board;
00153     }
00154 
00155     /** Searches the list of all blocks for the block.
00156         Boundary must belong to a single block. */
00157     GoBlock* GetBlock(const SgPointSet& boundary,
00158                          SgBlackWhite color) const;
00159 
00160     /** For incremental update, region where stone was just played */
00161     GoRegion* PreviousRegionAt(SgPoint p, SgBlackWhite color) const
00162     {
00163         SG_ASSERT(Board().Occupied(p));
00164         SG_ASSERT(m_region[color][p] != 0);
00165         return m_region[color][p];
00166     }
00167 
00168     /** Region of color at point p */
00169     GoRegion* RegionAt(SgPoint p, SgBlackWhite color) const
00170     {
00171         SG_ASSERT(UpToDate());
00172         SG_ASSERT(! Board().IsColor(p, color));
00173         SG_ASSERT(m_region[color][p] != 0);
00174         return m_region[color][p];
00175     }
00176 
00177     /** Region of color in area */
00178     void RegionsAt(const SgPointSet& area, SgBlackWhite color,
00179                             SgVectorOf<GoRegion>* regions) const;
00180 
00181     /** Region of color adjacent to points */
00182     void AdjacentRegions(const SgVector<SgPoint>& points, SgBlackWhite color,
00183                             SgVectorOf<GoRegion>* regions) const;
00184 
00185     /** Return GoBlock's just captured on last move, before update.
00186         For incremental update.
00187         Can be called for any empty point.
00188         returns 0 if no previous block there. */
00189     void PreviousBlocksAt(const SgVector<SgPoint>& area, SgBlackWhite color,
00190                             SgVectorOf<GoBlock>* captures) const;
00191 
00192     /** GoBlock at point p*/
00193     GoBlock* BlockAt(SgPoint p) const
00194     {
00195         SG_ASSERT(m_block[p] != 0);
00196         return m_block[p];
00197     }
00198 
00199     /** GoChain at point p*/
00200     GoChain* ChainAt(SgPoint p) const;
00201 
00202     /** Is block at point p marked as safe?*/
00203     bool IsSafeBlock(SgPoint p) const;
00204 
00205     /** Set safe flag for block at p*/
00206     void SetToSafe(SgPoint p) const;
00207 
00208     /** Set safe flags for all blocks in safe*/
00209     void SetSafeFlags(const SgBWSet& safe);
00210 
00211     /** Set m_computedHealthy flag to true */
00212     void SetComputedHealthy();
00213     
00214     /** class initialization */
00215     static bool Init();
00216 
00217     /** class finalization */
00218     static void Fini();
00219 
00220 private:
00221 
00222     // Compute from scratch helpers
00223     /** Generate blocks */
00224     void GenBlocks();
00225 
00226     /** Set the m_has1Eye flag for all blocks with 1 eye */
00227     void FindBlocksWithEye();
00228 
00229     // Execute move helpers
00230     /** Generate the block with given anchor */
00231     GoBlock* GenBlock(SgPoint anchor, SgBlackWhite color);
00232 
00233     /** Generate a region of color in area */
00234     GoRegion* GenRegion(const SgPointSet& area, SgBlackWhite color);
00235 
00236     /** incremental update of block after move */
00237     void UpdateBlock(int move, SgBlackWhite moveColor);
00238 
00239     /** Sets m_region elements to point to r */
00240     void SetRegionArrays(GoRegion* r);
00241 
00242     /** add block to GoRegionBoard */
00243     void AddBlock(GoBlock* b, bool isExecute = true);
00244 
00245     /** remove block from GoRegionBoard */
00246     void RemoveBlock(GoBlock* b, bool isExecute, bool removeFromRegions);
00247 
00248     /** add region to GoRegionBoard */
00249     void AddRegion(GoRegion* r, bool isExecute = true);
00250 
00251     /** remove region from GoRegionBoard */
00252     void RemoveRegion(GoRegion* r, bool isExecute = true);
00253 
00254     /** For all captured stones: merge its adjacent previous regions into one.
00255         then for all captured stones: add their area to its single adjacent
00256         region. */
00257     void MergeAdjacentAndAddBlock(SgPoint move, SgBlackWhite capturedColor);
00258 
00259     /** Merge all regions and the captured area into new large region */
00260     GoRegion* MergeAll(const SgVectorOf<GoRegion>& regions,
00261                       const SgPointSet& captured, SgBlackWhite color);
00262 
00263     // Undo move helpers
00264     /** stores incremental state changes for execute/undo moves */
00265     SgIncrementalStack m_stack;
00266 
00267     /** push on m_stack */
00268     void PushRegion(int type, GoRegion* r);
00269 
00270     /** push on m_stack */
00271     void PushStone(GoRegion* r, SgPoint move);
00272 
00273     /** push on m_stack */
00274     void PushBlock(int type, GoBlock* b);
00275 
00276     /** add stome to b and push information on m_stack */
00277     void AppendStone(GoBlock* b, SgPoint move);
00278 
00279     // data members
00280 
00281     const GoBoard& m_board;
00282 
00283     /** pointer to region, defined only at anchor of region */
00284     SgBWArray<SgPointArray<GoRegion*> > m_region;
00285 
00286     /** pointer from stone to block, 0 if empty point */
00287     SgPointArray<GoBlock*> m_block;
00288 
00289     /** All blocks on board */
00290     SgBWArray<SgVectorOf<GoBlock> > m_allBlocks;
00291 
00292     /** All chains on board */
00293     SgBWArray<SgVectorOf<GoChain> > m_allChains;
00294 
00295     /** All regions on board */
00296     SgBWArray<SgVectorOf<GoRegion> > m_allRegions;
00297 
00298     /** Code for last time block and region information was computed */
00299     SgHashCode m_code;
00300 
00301     /** Code for last time chain information was computed */
00302     SgHashCode m_chainsCode;
00303 
00304     /** does block and region data match current board? */
00305     bool m_invalid;
00306     
00307     /** has healthy count been computed for all blocks?
00308         @todo in fully incremental mode, this should be determined locally
00309         for each block, not globally. */
00310     bool m_computedHealthy;
00311     
00312     /** Boardsize is needed to avoid problems with resizing an empty board */
00313     int m_boardSize;
00314 
00315     /** debugging bookkeeping. @todo do it in debug only */
00316     static int s_alloc, s_free;
00317 
00318 };
00319 
00320 //----------------------------------------------------------------------------
00321 
00322 #endif // GO_REGIONBOARD_H


Sun Mar 13 2011 Doxygen 1.7.1