Index   Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

SgBoardConst.h

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file SgBoardConst.h
00003     Constant data for a given board size. */
00004 //----------------------------------------------------------------------------
00005 
00006 #ifndef SG_BOARDCONST_H
00007 #define SG_BOARDCONST_H
00008 
00009 #include <boost/shared_ptr.hpp>
00010 #include "SgArray.h"
00011 #include "SgNbIterator.h"
00012 #include "SgPoint.h"
00013 #include "SgPointArray.h"
00014 #include "SgPointIterator.h"
00015 #include "SgPointSet.h"
00016 
00017 //----------------------------------------------------------------------------
00018 
00019 /** Constant data for a given board size for games with square boards.
00020     All boards created with the same board size share the same
00021     data to reduce memory consumption and increase cache hits. */
00022 class SgBoardConst
00023 {
00024 public:
00025     SgBoardConst(SgGrid size);
00026 
00027     /** Change the information for this object to another size.
00028         Does nothing if 'newSize' is the same. */
00029     void ChangeSize(SgGrid newSize);
00030 
00031     /** Get board size. */
00032     SgGrid Size() const;
00033 
00034     /** Distance from the nearest border point.
00035         Points on the edge of the board have distance 1;
00036         border (off-board) points have distance 0. */
00037     SgGrid Line(SgPoint p) const;
00038 
00039     /** The distance to the second-closest border point.
00040         Points on the edge of the board have distance 1;
00041         border (off-board) points have distance 0. */
00042     SgGrid Pos(SgPoint p) const;
00043 
00044     /** Offset for neighboring point away from edge of board.
00045         @todo: the following seems weird, remove?
00046         Can also be a diagonal neighbor if no direct up-neighbor exists.
00047         If no up-neighbor exists at all, returns offset of 0. */
00048     int Up(SgPoint p) const;
00049 
00050     /** Offset for neighbor to the left, when looking in Up() direction */
00051     int Left(SgPoint p) const;
00052 
00053     /**  */
00054     int Right(SgPoint p) const;
00055 
00056     /** @todo */
00057     int Side(SgPoint p, int i) const;
00058 
00059     /** Set of points in corners of the board.
00060         On 12x12 boards and larger, this includes 5x5 area from corner
00061         except the 5,5 point itself (the classical opening moves and below).
00062         See SgBoardConst::BoardConstImpl::BoardConstImpl for details.
00063         On smaller boards, includes the 4x4 area except the 4,4 point itself. */
00064     const SgPointSet& Corners() const;
00065 
00066     /** Set of points on edge but not in corners of the board.
00067         On 12x12 boards and larger, this includes points on lines 1-4.
00068         On smaller boards, lines 1 to 3. */
00069     const SgPointSet& Edges() const;
00070 
00071     /** All points on board not in Corners() or Edges() */
00072     const SgPointSet& Centers() const;
00073 
00074     /** Points for standard side extensions on lines 2 to 4. */
00075     const SgPointSet& SideExtensions() const;
00076 
00077     /** Set of all points on given line. */
00078     const SgPointSet& LineSet(SgGrid line) const;
00079 
00080     /** Upper left corner of the board.
00081         Using FirstBoardPoint and LastBoardPoint the board points can be
00082         traversed with a for-loop. This avoids the border points before and
00083         after the board, but not the ones to the side of the board;
00084         one must still check for border fields within the loop. */
00085     int FirstBoardPoint() const;
00086 
00087     /** See FirstBoardPoint */
00088     int LastBoardPoint() const;
00089 
00090     /** List of on-board neighbor points terminated by SG_ENDPOINT.
00091         Points are sorted from low to high. */
00092     const SgPoint* NeighborIterAddress(SgPoint p) const;
00093 
00094     const SgPoint* BoardIterAddress() const;
00095 
00096     const SgPoint* BoardIterEnd() const;
00097 
00098     const SgPoint* LineIterAddress(SgGrid line) const;
00099 
00100     const SgPoint* CornerIterAddress() const;
00101 
00102 private:
00103     struct BoardConstImpl
00104     {
00105         BoardConstImpl(SgGrid size);
00106 
00107         /** Size */
00108         SgGrid m_size;
00109 
00110         int m_firstBoardPoint;
00111 
00112         int m_lastBoardPoint;
00113 
00114         SgPointArray<SgGrid> m_gridToLine;
00115 
00116         SgPointArray<SgGrid> m_gridToPos;
00117 
00118         /** See SgBoardConst::Neighbors() */
00119         SgPoint m_neighbors[SG_MAXPOINT][5];
00120 
00121         SgPointArray<int> m_up;
00122 
00123         SgPointSet m_corners;
00124 
00125         SgPointSet m_edges;
00126 
00127         SgPointSet m_centers;
00128 
00129         SgPointSet m_sideExtensions;
00130 
00131         SgPoint m_cornerIter[4 + 1];
00132 
00133         SgPointSet m_line[(SG_MAX_SIZE / 2) + 1];
00134 
00135         SgPoint* m_lineIterAddress[(SG_MAX_SIZE / 2) + 1];
00136 
00137         SgPoint m_boardIter[SG_MAX_ONBOARD + 1];
00138 
00139         SgPoint* m_boardIterEnd;
00140 
00141         SgPoint m_lineIter[SG_MAX_SIZE * SG_MAX_SIZE + (SG_MAX_SIZE / 2) + 1];
00142 
00143         int m_side[2][2 * (SG_NS + SG_WE) + 1];
00144     };
00145 
00146     typedef SgArray<boost::shared_ptr<BoardConstImpl>,SG_MAX_SIZE + 1>
00147         BoardConstImplArray;
00148 
00149     boost::shared_ptr<BoardConstImpl> m_const;
00150 
00151     void Create(SgGrid size);
00152 
00153     static BoardConstImplArray s_const;
00154 };
00155 
00156 inline SgGrid SgBoardConst::Size() const
00157 {
00158     return m_const->m_size;
00159 }
00160 
00161 inline SgGrid SgBoardConst::Line(SgPoint p) const
00162 {
00163     return m_const->m_gridToLine[p];
00164 }
00165 
00166 inline const SgPoint* SgBoardConst::NeighborIterAddress(SgPoint p) const
00167 {
00168     return m_const->m_neighbors[p];
00169 }
00170 
00171 inline SgGrid SgBoardConst::Pos(SgPoint p) const
00172 {
00173     return m_const->m_gridToPos[p];
00174 }
00175 
00176 inline int SgBoardConst::Up(SgPoint p) const
00177 {
00178     return m_const->m_up[p];
00179 }
00180 
00181 inline int SgBoardConst::Left(SgPoint p) const
00182 {
00183     return m_const->m_side[0][m_const->m_up[p] + (SG_NS + SG_WE)];
00184 }
00185 
00186 inline int SgBoardConst::Right(SgPoint p) const
00187 {
00188     return m_const->m_side[1][m_const->m_up[p] + (SG_NS + SG_WE)];
00189 }
00190 
00191 inline int SgBoardConst::Side(SgPoint p, int i) const
00192 {
00193     return m_const->m_side[i][m_const->m_up[p] + (SG_NS + SG_WE)];
00194 }
00195 
00196 inline const SgPointSet& SgBoardConst::Corners() const
00197 {
00198     return m_const->m_corners;
00199 }
00200 
00201 inline const SgPointSet& SgBoardConst::Edges() const
00202 {
00203     return m_const->m_edges;
00204 }
00205 
00206 inline const SgPointSet& SgBoardConst::Centers() const
00207 {
00208     return m_const->m_centers;
00209 }
00210 
00211 inline const SgPointSet& SgBoardConst::SideExtensions() const
00212 {
00213     return m_const->m_sideExtensions;
00214 }
00215 
00216 inline const SgPointSet& SgBoardConst::LineSet(SgGrid line) const
00217 {
00218     return m_const->m_line[line - 1];
00219 }
00220 
00221 inline int SgBoardConst::FirstBoardPoint() const
00222 {
00223     return m_const->m_firstBoardPoint;
00224 }
00225 
00226 inline int SgBoardConst::LastBoardPoint() const
00227 {
00228     return m_const->m_lastBoardPoint;
00229 }
00230 
00231 inline const SgPoint* SgBoardConst::BoardIterAddress() const
00232 {
00233     return m_const->m_boardIter;
00234 }
00235 
00236 inline const SgPoint* SgBoardConst::BoardIterEnd() const
00237 {
00238     return m_const->m_boardIterEnd;
00239 }
00240 
00241 inline const SgPoint* SgBoardConst::LineIterAddress(SgGrid line) const
00242 {
00243     return m_const->m_lineIterAddress[line - 1];
00244 }
00245 
00246 inline const SgPoint* SgBoardConst::CornerIterAddress() const
00247 {
00248     return m_const->m_cornerIter;
00249 }
00250 
00251 //----------------------------------------------------------------------------
00252 
00253 /** Iterate through all points on a specific line on the given board.
00254     e.g. all points on the third line. */
00255 class SgLineIterator
00256     : public SgPointIterator
00257 {
00258 public:
00259     SgLineIterator(const SgBoardConst& boardConst, SgGrid line)
00260         : SgPointIterator(boardConst.LineIterAddress(line))
00261     { }
00262 };
00263 
00264 //----------------------------------------------------------------------------
00265 
00266 /** Iterate through all four corner point of the given board. */
00267 class SgCornerIterator
00268     : public SgPointIterator
00269 {
00270 public:
00271     SgCornerIterator(const SgBoardConst& boardConst)
00272         : SgPointIterator(boardConst.CornerIterAddress())
00273     { }
00274 };
00275 
00276 //----------------------------------------------------------------------------
00277 
00278 /** Iterate through the two directions along the sides for the given point.
00279     Returns the offset to the left (clockwise) first, then to the right. */
00280 class SgSideIterator
00281 {
00282 public:
00283     SgSideIterator(const SgBoardConst& boardConst, SgPoint p)
00284         : m_boardConst(boardConst),
00285           m_p(p),
00286           m_index(0)
00287     {
00288         SG_ASSERT(m_boardConst.Side(m_p, 0) != 0);
00289     }
00290 
00291     /** Advance the state of the iteration to the next element. */
00292     void operator++()
00293     {
00294         ++m_index;
00295     }
00296 
00297     /** Return the value of the current element. */
00298     int operator*() const
00299     {
00300         return m_boardConst.Side(m_p, m_index);
00301     }
00302 
00303     /** Return true if iteration is valid, otherwise false. */
00304     operator bool() const
00305     {
00306         return m_index <= 1;
00307     }
00308 
00309 private:
00310     const SgBoardConst& m_boardConst;
00311 
00312     SgPoint m_p;
00313 
00314     int m_index;
00315 
00316     /** Not implemented. */
00317     SgSideIterator(const SgSideIterator&);
00318 
00319     /** Not implemented. */
00320     SgSideIterator& operator=(const SgSideIterator&);
00321 };
00322 
00323 //----------------------------------------------------------------------------
00324 
00325 /** Iterate over all on-board neighbor points.
00326     The points are iterated in sorted order (from low to high). */
00327 class SgNbIterator
00328     : public SgPointIterator
00329 {
00330 public:
00331     SgNbIterator(const SgBoardConst& boardConst, SgPoint p);
00332 };
00333 
00334 inline SgNbIterator::SgNbIterator(const SgBoardConst& boardConst, SgPoint p)
00335     : SgPointIterator(boardConst.NeighborIterAddress(p))
00336 {
00337 }
00338 
00339 //----------------------------------------------------------------------------
00340 
00341 #endif // SG_BOARDCONST_H


Sun Mar 13 2011 Doxygen 1.7.1