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


17 Jun 2010 Doxygen 1.4.7