ConstBoard.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006 #include "ConstBoard.hpp"
00007 #include "BoardUtils.hpp"
00008 #include "BitsetIterator.hpp"
00009
00010 using namespace benzene;
00011
00012
00013
00014 namespace {
00015
00016
00017
00018 int DistanceToEdge(const ConstBoard& brd, HexPoint from, HexPoint edge)
00019 {
00020 HexAssert(HexPointUtil::isEdge(edge));
00021
00022 if (HexPointUtil::isEdge(from))
00023 {
00024 if (from == edge) return 0;
00025 if (HexPointUtil::oppositeEdge(from) != edge) return 1;
00026 if (edge == NORTH || edge == SOUTH) return brd.Height();
00027 return brd.Width();
00028 }
00029
00030 int r, c;
00031 HexPointUtil::pointToCoords(from, c, r);
00032 switch(edge)
00033 {
00034 case NORTH: return r + 1;
00035 case SOUTH: return brd.Height() - r;
00036 case EAST: return brd.Width() - c;
00037 default: return c + 1;
00038 }
00039 }
00040
00041
00042
00043 }
00044
00045
00046
00047 ConstBoard& ConstBoard::Get(int size)
00048 {
00049 return Get(size, size);
00050 }
00051
00052 ConstBoard& ConstBoard::Get(int width, int height)
00053 {
00054
00055
00056
00057 static std::vector<ConstBoard*> s_brds;
00058 for (std::size_t i=0; i<s_brds.size(); ++i) {
00059 if (s_brds[i]->Width() == width && s_brds[i]->Height() == height)
00060 return *s_brds[i];
00061 }
00062 s_brds.push_back(new ConstBoard(width, height));
00063 return *s_brds.back();
00064 }
00065
00066
00067
00068 ConstBoard::ConstBoard(int size)
00069 : m_width(size),
00070 m_height(size)
00071 {
00072 HexAssert(1 <= m_width && m_width <= MAX_WIDTH);
00073 HexAssert(1 <= m_height && m_height <= MAX_HEIGHT);
00074 Init();
00075 }
00076
00077 ConstBoard::ConstBoard(int width, int height)
00078 : m_width(width),
00079 m_height(height)
00080 {
00081 HexAssert(1 <= m_width && m_width <= MAX_WIDTH);
00082 HexAssert(1 <= m_height && m_height <= MAX_HEIGHT);
00083 Init();
00084 }
00085
00086 ConstBoard::~ConstBoard()
00087 {
00088 }
00089
00090
00091
00092 bool ConstBoard::Adjacent(HexPoint p1, HexPoint p2) const
00093 {
00094 for (BoardIterator it(Nbs(p1)); it; ++it)
00095 if (*it == p2)
00096 return true;
00097 return false;
00098 }
00099
00100 int ConstBoard::Distance(HexPoint x, HexPoint y) const
00101 {
00102 HexAssert(IsValid(x));
00103 HexAssert(IsValid(y));
00104
00105 if (HexPointUtil::isEdge(y))
00106 return DistanceToEdge(*this, x, y);
00107 else if (HexPointUtil::isEdge(x))
00108 return DistanceToEdge(*this, y, x);
00109
00110 int r1, c1, r2, c2;
00111 HexPointUtil::pointToCoords(x, r1, c1);
00112 HexPointUtil::pointToCoords(y, r2, c2);
00113 int dr = r1 - r2;
00114 int dc = c1 - c2;
00115
00116 return (dr*dc >= 0)
00117 ? std::abs(dr) + std::abs(dc)
00118 : std::max(std::abs(dr), std::abs(dc));
00119 }
00120
00121
00122
00123 void ConstBoard::Init()
00124 {
00125 LogFine() << "--- ConstBoard"
00126 << " (" << Width() << " x " << Height() << ")" << '\n';
00127 ComputePointList();
00128 CreateIterators();
00129 ComputeValid();
00130 ComputeNeighbours();
00131 }
00132
00133 void ConstBoard::ComputePointList()
00134 {
00135
00136
00137
00138
00139
00140 for (int p = FIRST_SPECIAL; p < FIRST_CELL; ++p)
00141 m_points.push_back(static_cast<HexPoint>(p));
00142
00143 for (int y = 0; y < Height(); y++)
00144 for (int x = 0; x < Width(); x++)
00145 m_points.push_back(HexPointUtil::coordsToPoint(x, y));
00146
00147 m_points.push_back(INVALID_POINT);
00148 }
00149
00150 void ConstBoard::CreateIterators()
00151 {
00152 int p = 0;
00153 while (m_points[p] != FIRST_SPECIAL) p++;
00154 m_all_index = p;
00155
00156 while (m_points[p] != FIRST_EDGE) p++;
00157 m_locations_index = p;
00158
00159 while (m_points[p] != FIRST_CELL) p++;
00160 m_cells_index = p;
00161 }
00162
00163 void ConstBoard::ComputeValid()
00164 {
00165 m_valid.reset();
00166 for (BoardIterator i(AllValid()); i; ++i)
00167 m_valid.set(*i);
00168
00169 m_locations.reset();
00170 for (BoardIterator i(EdgesAndInterior()); i; ++i)
00171 m_locations.set(*i);
00172
00173 m_cells.reset();
00174 for (BoardIterator i(Interior()); i; ++i)
00175 m_cells.set(*i);
00176 }
00177
00178 void ConstBoard::ComputeNeighbours()
00179 {
00180
00181 for (BoardIterator i(Interior()); i; ++i)
00182 {
00183 int x, y;
00184 HexPoint cur = *i;
00185 HexPointUtil::pointToCoords(cur, x, y);
00186 for (int a = 0; a < NUM_DIRECTIONS; a++)
00187 {
00188 int fwd = a;
00189 int lft = (a + 2) % NUM_DIRECTIONS;
00190 int x1 = x + HexPointUtil::DeltaX(fwd);
00191 int y1 = y + HexPointUtil::DeltaY(fwd);
00192 for (int r = 1; r <= Pattern::MAX_EXTENSION; r++)
00193 {
00194 int x2 = x1;
00195 int y2 = y1;
00196 for (int t = 0; t < r; t++)
00197 {
00198 HexPoint p = BoardUtils::CoordsToPoint(*this, x2, y2);
00199 if (p != INVALID_POINT)
00200 {
00201
00202
00203 for (int v=r; v <= Pattern::MAX_EXTENSION; v++)
00204 {
00205 std::vector<HexPoint>::iterator result;
00206
00207 result = find(m_neighbours[cur][v].begin(),
00208 m_neighbours[cur][v].end(), p);
00209 if (result == m_neighbours[cur][v].end())
00210 m_neighbours[cur][v].push_back(p);
00211
00212 result = find(m_neighbours[p][v].begin(),
00213 m_neighbours[p][v].end(), cur);
00214 if (result == m_neighbours[p][v].end())
00215 m_neighbours[p][v].push_back(cur);
00216 }
00217 }
00218 x2 += HexPointUtil::DeltaX(lft);
00219 y2 += HexPointUtil::DeltaY(lft);
00220 }
00221 x1 += HexPointUtil::DeltaX(fwd);
00222 y1 += HexPointUtil::DeltaY(fwd);
00223 }
00224 }
00225 }
00226
00227
00228
00229
00230
00231 for (BoardIterator i(EdgesAndInterior()); i; ++i)
00232 {
00233 if (!HexPointUtil::isEdge(*i))
00234 continue;
00235 for (int r = 1; r <= Pattern::MAX_EXTENSION; r++)
00236 {
00237
00238 m_neighbours[*i][r].push_back(HexPointUtil::leftEdge(*i));
00239 m_neighbours[*i][r].push_back(HexPointUtil::rightEdge(*i));
00240 }
00241 }
00242
00243 for (BoardIterator i(EdgesAndInterior()); i; ++i)
00244 for (int r = 1; r <= Pattern::MAX_EXTENSION; r++)
00245 m_neighbours[*i][r].push_back(INVALID_POINT);
00246 }
00247
00248