Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

HexPoint.hpp

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file HexPoint.hpp
00003  */
00004 //----------------------------------------------------------------------------
00005 
00006 #ifndef HEXPOINT_HPP
00007 #define HEXPOINT_HPP
00008 
00009 #include <map>
00010 #include <string>
00011 #include <vector>
00012 #include <utility>
00013 
00014 #include "Benzene.hpp"
00015 #include "Bitset.hpp"
00016 #include "HexAssert.hpp"
00017 #include "HexColor.hpp"
00018 
00019 _BEGIN_BENZENE_NAMESPACE_
00020 
00021 //----------------------------------------------------------------------------
00022 
00023 /** @page hexpoints HexPoints 
00024 
00025     There are three types of HexPoints: special, edges, and interior.
00026     Special points encode special moves that do not correspond to a
00027     physical location on a hex board. These are: INVALID_POINT,
00028     RESIGN, and SWAP_PIECES.  Edge points (NORTH, SOUTH, EAST, WEST)
00029     denote the edges of the board.  Internal points are the interior
00030     points of the board, the number of which is controlled by the
00031     constants MAX_WIDTH and MAX_HEIGHT.
00032 
00033     HexPoints are laid out in memory as follows:
00034 
00035     @verbatim
00036 
00037       0   INVALID_POINT
00038       1   RESIGN          
00039       2   SWAP_PIECES     
00040       3   NORTH
00041       4   EAST
00042       5   SOUTH
00043       6   WEST
00044       7   1st interior point
00045       8   2nd interior point
00046       ...
00047       ...
00048       ... FIRST_INVALID
00049     @endverbatim
00050 
00051     It is assumed that the special points (i.e. SWAP_PIECES and
00052     RESIGN) come immediately before the edge points (i.e. NORTH to
00053     WEST) which come immediately before the interior points.
00054 
00055     The interior points are laid out as follows.  The first MAX_WIDTH
00056     interior points get the name 'a1, b1, c1, ... , L1', where L is
00057     letter MAX_WIDTH-1 letters after 'a'. The next MAX_WIDTH points
00058     get a '2' suffix, then a '3' suffix, and so on, until MAX_HEIGHT
00059     is reached.
00060 
00061     This encoding allows an 11x11 hex board to fit into 128 bits if
00062     MAX_WIDTH = 11 and MAX_HEIGHT = 11.
00063 */
00064 
00065 //----------------------------------------------------------------------------
00066 
00067 /** @name Maximum dimensions.
00068 
00069     If you are going to change either of these constants, make sure to
00070     synchronize the printed names in HexPointData with the enumerated
00071     interior cell constants below.
00072 */
00073 // @{ 
00074 
00075 #if defined(SUPPORT_19x19)
00076 
00077 /** The maximum width of a valid ConstBoard. */
00078 static const int MAX_WIDTH  = 19;
00079 
00080 /** The maximum height of a valid ConstBoard. */
00081 static const int MAX_HEIGHT = 19;
00082 
00083 #elif defined(SUPPORT_14x14)
00084 
00085 /** The maximum width of a valid ConstBoard. */
00086 static const int MAX_WIDTH  = 14;
00087 
00088 /** The maximum height of a valid ConstBoard. */
00089 static const int MAX_HEIGHT = 14;
00090 
00091 #elif defined(SUPPORT_13x13)
00092 
00093 /** The maximum width of a valid ConstBoard. */
00094 static const int MAX_WIDTH  = 13;
00095 
00096 /** The maximum height of a valid ConstBoard. */
00097 static const int MAX_HEIGHT = 13;
00098 
00099 #else
00100 
00101 /** The maximum width of a valid ConstBoard. */
00102 static const int MAX_WIDTH  = 11;
00103 
00104 /** The maximum height of a valid ConstBoard. */
00105 static const int MAX_HEIGHT = 11;
00106 
00107 #endif
00108 
00109 // @}
00110 
00111 //----------------------------------------------------------------------------
00112 
00113 #if defined(SUPPORT_19x19)
00114 
00115 #include "HexPoints19x19.hpp"
00116 
00117 #elif defined(SUPPORT_14x14)
00118 
00119 #include "HexPoints14x14.hpp"
00120 
00121 #elif defined(SUPPORT_13x13)
00122 
00123 #include "HexPoints13x13.hpp"
00124 
00125 #else
00126 
00127 #include "HexPoints11x11.hpp"
00128 
00129 #endif
00130 
00131 /** The value of the first special HexPoint. */
00132 static const HexPoint FIRST_SPECIAL = RESIGN;
00133 
00134 /** The value of the first edge HexPoint. */
00135 static const HexPoint FIRST_EDGE = NORTH;
00136 
00137 /** The value of the first interior cell; this should always be A1. */
00138 static const HexPoint FIRST_CELL = HEX_CELL_A1;
00139     
00140 //---------------------------------------------------------------------------
00141 
00142 /** A map of points to points. */
00143 typedef std::map<HexPoint, HexPoint> PointToPoint;
00144 
00145 /** Pair of HexPoints. */
00146 typedef std::pair<HexPoint, HexPoint> HexPointPair;
00147 
00148 /** Set of HexPoints. */
00149 typedef std::set<HexPoint> HexPointSet;
00150 
00151 /** Map of HexPoints to bitsets. */
00152 typedef std::map<HexPoint, bitset_t> PointToBitset;
00153 
00154 /** A sequence of HexPoints. */
00155 typedef std::vector<HexPoint> PointSequence;
00156 
00157 //---------------------------------------------------------------------------
00158 
00159 /**
00160    Delta arrays.
00161  
00162    On a hex board, we can travel only in the following six directions:
00163    EAST, NORTH_EAST, NORTH, WEST, SOUTH_WEST, SOUTH.
00164  
00165    @verbatim 
00166              | /  
00167              |/
00168          --- o ---
00169             /|
00170            / |
00171    @endverbatim
00172 */
00173 enum HexDirection 
00174 { 
00175     DIR_EAST=0, 
00176     DIR_NORTH_EAST, 
00177     DIR_NORTH, 
00178     DIR_WEST, 
00179     DIR_SOUTH_WEST, 
00180     DIR_SOUTH, 
00181     NUM_DIRECTIONS 
00182 };
00183 
00184 //----------------------------------------------------------------------------
00185 
00186 /** Utilities on HexPoints: converting to/from strings, testing for edges, 
00187     converting to/from x/y coordinates, etc. */
00188 namespace HexPointUtil
00189 {
00190     /** Converts a HexPoint to a string. */
00191     std::string ToString(HexPoint p);
00192 
00193     /** Converts a pair of HexPoints to a string. */
00194     std::string ToString(const HexPointPair& p);
00195 
00196     /** Returns a space separated output of points in lst. */
00197     std::string ToString(const PointSequence& lst);
00198 
00199     /** Returns a string representation of the bitset's set bits. */
00200     std::string ToString(const bitset_t& b);
00201 
00202     /** Returns the HexPoint with the given name; INVALID_POINT otherwise. */
00203     HexPoint FromString(const std::string& name);
00204 
00205     /** Reads a PointSequence from a string of space separated
00206         points. */
00207     void FromString(const std::string& str, PointSequence& pts);
00208 
00209     /** Returns true if this point is a swap move. */
00210     bool isSwap(HexPoint c);
00211 
00212     /** Returns true if this point is an edge point. */
00213     bool isEdge(HexPoint c);
00214 
00215     /** Returns true if this point is an interior cell. */
00216     bool isInteriorCell(HexPoint c);
00217 
00218     /** Returns the edge opposite the given edge. */
00219     HexPoint oppositeEdge(HexPoint edge);
00220 
00221     /** Returns the edge to the left of the given edge. */
00222     HexPoint leftEdge(HexPoint edge);
00223 
00224     /** Returns the edge to the right of the given edge. */
00225     HexPoint rightEdge(HexPoint edge);
00226 
00227     /** Returns a color's first edge.  NORTH for VERTICAL_COLOR
00228         and EAST for !VERTICAL_COLOR. */ 
00229     HexPoint colorEdge1(HexColor color);
00230 
00231     /** Returns a color's second edge.  SOUTH for VERTICAL_COLOR
00232         and WEST for !VERTICAL_COLOR. */
00233     HexPoint colorEdge2(HexColor color);
00234 
00235     /** Returns true if cell is one of color's edges. */
00236     bool isColorEdge(HexPoint cell, HexColor color);
00237 
00238     /** Converts cell into its x and y components, where
00239         @code
00240         x = (cell-FIRST_CELL) % MAX_WIDTH;
00241         y = (cell-FIRST_CELL) / MAX_WIDTH;
00242         @endcode
00243         
00244         Does not handle cases where cell is an edge.
00245         ConstBoard has a method for that.
00246     */
00247     void pointToCoords(HexPoint cell, int& x, int& y);
00248 
00249     /** Returns the HexPoint corresponding to the given x and y coords. 
00250         @code 
00251         point =  FIRST_CELL + (y*MAX_WIDTH) + x;
00252         @endcode
00253     */
00254     HexPoint coordsToPoint(int x, int y);
00255 
00256     /** Returns the change in the x-coordinate when travelling in the
00257         given direction. */
00258     int DeltaX(int dir);
00259 
00260     /** Returns the change in the y-coordinate when travelling in the
00261         given direction. */
00262     int DeltaY(int dir);
00263 
00264 } // namespace
00265 
00266 //----------------------------------------------------------------------------
00267 
00268 inline bool HexPointUtil::isSwap(HexPoint c)
00269 {
00270     return (c==SWAP_PIECES);
00271 }
00272 
00273 inline bool HexPointUtil::isEdge(HexPoint c)
00274 { 
00275     return (c==NORTH || c==SOUTH || c==EAST || c==WEST); 
00276 }
00277 
00278 inline bool HexPointUtil::isInteriorCell(HexPoint c)
00279 {
00280     return (FIRST_CELL <= c && c < FIRST_INVALID);
00281 }
00282 
00283 inline HexPoint HexPointUtil::oppositeEdge(HexPoint edge)
00284 {
00285     HexAssert(isEdge(edge));
00286     if (edge == NORTH) return SOUTH;
00287     if (edge == SOUTH) return NORTH;
00288     if (edge == EAST)  return WEST;
00289     HexAssert(edge == WEST);
00290     return EAST;
00291 }
00292 
00293 inline HexPoint HexPointUtil::leftEdge(HexPoint edge)
00294 {
00295     HexAssert(isEdge(edge));
00296     if (edge == NORTH) return EAST;
00297     if (edge == SOUTH) return WEST;
00298     if (edge == EAST)  return SOUTH;
00299     HexAssert(edge == WEST);
00300     return NORTH;
00301 }
00302 
00303 inline HexPoint HexPointUtil::rightEdge(HexPoint edge)
00304 {
00305     HexAssert(isEdge(edge));
00306     if (edge == NORTH) return WEST;
00307     if (edge == SOUTH) return EAST;
00308     if (edge == EAST)  return NORTH;
00309     HexAssert(edge == WEST);
00310     return SOUTH;
00311 }
00312 
00313 inline HexPoint HexPointUtil::colorEdge1(HexColor color)
00314 {
00315     HexAssert(HexColorUtil::isBlackWhite(color));
00316     return (color == VERTICAL_COLOR) ? NORTH : EAST;
00317 }
00318 
00319 inline HexPoint HexPointUtil::colorEdge2(HexColor color)
00320 {
00321     HexAssert(HexColorUtil::isBlackWhite(color));
00322     return (color == VERTICAL_COLOR) ? SOUTH : WEST;
00323 }
00324 
00325 inline bool HexPointUtil::isColorEdge(HexPoint cell, HexColor color)
00326 {
00327     HexAssert(HexColorUtil::isBlackWhite(color));
00328     return (cell == colorEdge1(color) || cell == colorEdge2(color));
00329 }
00330 
00331 inline void HexPointUtil::pointToCoords(HexPoint cell, int& x, int& y)
00332 {
00333     HexAssert(FIRST_CELL <= cell && cell < FIRST_INVALID);
00334     x = (cell-FIRST_CELL) % MAX_WIDTH;
00335     y = (cell-FIRST_CELL) / MAX_WIDTH;
00336 }
00337 
00338 inline HexPoint HexPointUtil::coordsToPoint(int x, int y)
00339 {
00340     HexAssert(0 <= x && x < MAX_WIDTH);
00341     HexAssert(0 <= y && y < MAX_HEIGHT);
00342     return static_cast<HexPoint>(FIRST_CELL + (y*MAX_WIDTH) + x);
00343 }
00344 
00345 inline int HexPointUtil::DeltaX(int dir)
00346 {
00347     HexAssert(DIR_EAST <= dir && dir < NUM_DIRECTIONS);
00348     static const int dx[] = {1,  1,  0, -1, -1, 0};
00349     return dx[dir];
00350 }
00351 
00352 inline int HexPointUtil::DeltaY(int dir)
00353 {
00354     HexAssert(DIR_EAST <= dir && dir < NUM_DIRECTIONS);
00355     static const int dy[] = {0, -1, -1,  0,  1, 1};
00356     return dy[dir];
00357 }
00358 
00359 //----------------------------------------------------------------------------
00360 
00361 /** Extends standard output operator to handle HexPoints. */
00362 inline std::ostream& operator<<(std::ostream& os, HexPoint p)
00363 {
00364     return os << HexPointUtil::ToString(p);
00365 }
00366 
00367 //----------------------------------------------------------------------------
00368 
00369 _END_BENZENE_NAMESPACE_
00370 
00371 #endif // HEXPOINT_HPP


6 Jan 2011 Doxygen 1.6.3