grid.hxx
Go to the documentation of this file.
1 /*===========================================================================================================
2  *
3  * HUL - Hurna Lib
4  *
5  * Copyright (c) Michael Jeulin-Lagarrigue
6  *
7  * Licensed under the MIT License, you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * https://github.com/Hurna/Hurna-Lib/blob/master/LICENSE
11  *
12  * Unless required by applicable law or agreed to in writing, software distributed under the License is
13  * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and limitations under the License.
15  *
16  * The above copyright notice and this permission notice shall be included in all copies or
17  * substantial portions of the Software.
18  *
19  *=========================================================================================================*/
20 #ifndef MODULE_DS_GRID_HXX
21 #define MODULE_DS_GRID_HXX
22 
23 // STD
24 #include <memory>
25 #include <vector>
26 #include <set>
27 
28 namespace huc
29 {
32  struct CellInfoBase
33  {
34  CellInfoBase() : isVisited(false) {}
35  bool isVisited;
36  };
37 
43  template <typename CellInfo = CellInfoBase>
44  class Grid
45  {
46  public:
52  explicit Grid(uint32_t width, uint32_t height, bool isConnected = false)
53  { Init(width, height, isConnected); }
54 
56  struct Point
57  {
58  Point(uint32_t x = 0, uint32_t y = 0) : x(x), y(y) {}
59  uint32_t x;
60  uint32_t y;
61  };
62 
65  class Cell {
66  public:
67  Cell(uint32_t x, uint32_t y) : x(x), y(y) {}
68 
69  const uint32_t x; // X coordinate
70  const uint32_t y; // Y coordinate
71 
72  std::set<std::weak_ptr<Cell>, std::owner_less<std::weak_ptr<Cell>>>
73  connectedCells; // Direct connections from this cell (!do not use shared_ptr to avoid cycle!)
74  CellInfo info; // Use to store extra information
75 
76  private:
77  Cell operator=(Cell&); // Not Implemented
78  };
79 
81  class Edge {
82  public:
83  Edge(std::shared_ptr<Cell> first, std::shared_ptr<Cell> second) : first(first), second(second) {}
84 
85  const std::shared_ptr<Cell> first; // First Cell
86  const std::shared_ptr<Cell> second; // Second Cell
87 
88  bool operator<(const Edge& a) const
89  { return this->first->x < a.first->x || this->first->y < a.first->y ||
90  this->second->x < a.second->x || this->second->y < a.second->y; }
91 
92  private:
93  Edge operator=(Edge&); // Not Implemented
94  };
95 
102  void Connect(const std::shared_ptr<Cell> first, const std::shared_ptr<Cell> second)
103  {
104  first->connectedCells.insert(second);
105  second->connectedCells.insert(first);
106  }
107 
114  void Connect(const std::shared_ptr<Cell> root, const std::vector<std::shared_ptr<Cell>>& neighbours)
115  {
116  if (neighbours.size() < 1)
117  return;
118 
119  for (auto it = neighbours.begin(); it != neighbours.end(); ++it)
120  {
121  root->connectedCells.insert(*it);
122  (*it)->connectedCells.insert(root);
123  }
124  }
125 
132  void Disconnect(const std::shared_ptr<Cell> first, const std::shared_ptr<Cell> second)
133  {
134  first->connectedCells.erase(second);
135  second->connectedCells.erase(first);
136  }
137 
150  void DisconnectCol(const Point& origin, const uint32_t idx, const uint32_t height, const uint32_t pathIdx)
151  {
152  if (origin.x + idx >= this->Width() - 1 || origin.y >= this->Height())
153  return;
154 
155  for (uint32_t y = 0; y < std::min(height, this->Height() - origin.y); ++y)
156  {
157  if (y == pathIdx)
158  continue;
159 
160  this->Disconnect(this->data[origin.x + idx][origin.y + y],
161  this->data[origin.x + idx + 1][origin.y + y]);
162  }
163  }
164 
177  void DisconnectRow(const Point& origin, const uint32_t idx, const uint32_t width, const uint32_t pathIdx)
178  {
179  if (origin.y + idx >= this->Height() - 1 || origin.x >= this->Width())
180  return;
181 
182  for (uint32_t x = 0; x < std::min(width, this->Width() - origin.x); ++x)
183  {
184  if (x == pathIdx)
185  continue;
186 
187  this->Disconnect(this->data[origin.x + x][origin.y + idx],
188  this->data[origin.x + x][origin.y + idx + 1]);
189  }
190  }
191 
192  uint32_t Width() const { return data.size(); }
193  uint32_t Height() const { return (data.size() > 0) ? data[0].size() : 0; }
194 
195  // Accessors
196  std::vector<std::shared_ptr<Cell>>& operator[] (size_t n) { return this->data[n]; }
197  const std::vector<std::shared_ptr<Cell>>& operator[] (size_t n) const { return this->data[n]; }
198 
199  private:
200  Grid operator=(Grid&); // Not Implemented
201  std::vector<std::vector<std::shared_ptr<Cell>>> data; // Grid wrapper
202 
203  void Init(uint32_t width, uint32_t height, bool isConneccted)
204  {
205  // Generate the Grid
206  this->data.resize(width);
207  for (uint32_t x = 0; x < width; ++x)
208  {
209  this->data[x].reserve(height);
210  for (uint32_t y = 0; y < height; ++y)
211  {
212  this->data[x].push_back(std::shared_ptr<Cell>(new Cell(x, y)));
213 
214  // Connect West
215  if (isConneccted && x > 0)
216  this->Connect(this->data[x][y], this->data[x-1][y]);
217  // Connect North
218  if (isConneccted && y > 0)
219  this->Connect(this->data[x][y], this->data[x][y-1]);
220  }
221  }
222  }
223  };
224 }
225 #endif // MODULE_DS_GRID_HXX
void Disconnect(const std::shared_ptr< Cell > first, const std::shared_ptr< Cell > second)
Definition: grid.hxx:132
Grid(uint32_t width, uint32_t height, bool isConnected=false)
Definition: grid.hxx:52
void DisconnectCol(const Point &origin, const uint32_t idx, const uint32_t height, const uint32_t pathIdx)
Definition: grid.hxx:150
Edge struct is a convenient struct use to store two cell pointers connected by a link/edge.
Definition: grid.hxx:81
std::set< std::weak_ptr< Cell >, std::owner_less< std::weak_ptr< Cell > > > connectedCells
Definition: grid.hxx:73
uint32_t Width() const
Definition: grid.hxx:192
CellInfo info
Definition: grid.hxx:74
const uint32_t y
Definition: grid.hxx:70
uint32_t x
Definition: grid.hxx:59
void Init(uint32_t width, uint32_t height, bool isConneccted)
Definition: grid.hxx:203
Cell(uint32_t x, uint32_t y)
Definition: grid.hxx:67
const std::shared_ptr< Cell > first
Definition: grid.hxx:85
Edge(std::shared_ptr< Cell > first, std::shared_ptr< Cell > second)
Definition: grid.hxx:83
void Connect(const std::shared_ptr< Cell > root, const std::vector< std::shared_ptr< Cell >> &neighbours)
Definition: grid.hxx:114
bool operator<(const Edge &a) const
Definition: grid.hxx:88
Point(uint32_t x=0, uint32_t y=0)
Definition: grid.hxx:58
uint32_t Height() const
Definition: grid.hxx:193
void DisconnectRow(const Point &origin, const uint32_t idx, const uint32_t width, const uint32_t pathIdx)
Definition: grid.hxx:177
void Connect(const std::shared_ptr< Cell > first, const std::shared_ptr< Cell > second)
Definition: grid.hxx:102
std::vector< std::vector< std::shared_ptr< Cell > > > data
Definition: grid.hxx:201
bool isVisited
Definition: grid.hxx:35
Point struct is a convenient struct use to represent a 2D point for a grid (index position)...
Definition: grid.hxx:56
const std::shared_ptr< Cell > second
Definition: grid.hxx:86
const uint32_t x
Definition: grid.hxx:69
uint32_t y
Definition: grid.hxx:60