Algorithms Library Toolkit
A toolkit for algorithms, especially for algorithms on formal languages
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Concepts
SquareGrid.hpp
Go to the documentation of this file.
1
6// Copyright (c) 2017 Czech Technical University in Prague | Faculty of Information Technology. All rights reserved.
7
8#pragma once
9
10#include <alib/vector>
11#include <alib/set>
12#include <alib/pair>
13#include <alib/map>
14#include <alib/tuple>
15#include <cmath>
16#include <functional>
17#include <object/Object.h>
18#include <core/normalize.hpp>
19
20#include <common/Normalize.hpp>
23#include <grid/GridFeatures.hpp>
25
26namespace grid {
27
28template<typename TCoordinate, typename TEdge>
29class SquareGrid : public GridInterface<TCoordinate, TEdge> {
30// ---------------------------------------------------------------------------------------------------------------------
31
32 public:
33 using coordinate_type = TCoordinate;
34 using edge_type = TEdge;
37
38// ---------------------------------------------------------------------------------------------------------------------
39
40 protected:
41 TCoordinate m_height;
42 TCoordinate m_width;
44
45// =====================================================================================================================
46// Constructor, Destructor, Operators
47 public:
48 explicit SquareGrid(TCoordinate height, TCoordinate width);
49
50// ---------------------------------------------------------------------------------------------------------------------
51
52 const ext::set<node_type> &getObstacleList() const &;
53 ext::set<node_type> &&getObstacleList() &&;
54
55// ---------------------------------------------------------------------------------------------------------------------
56
57// =====================================================================================================================
58// GridBase interface
59 public:
60
61 void operator>>(ext::ostream &ostream) const override;
62
63// =====================================================================================================================
64// SquareGrid interface
65
66 public:
67 TCoordinate getHeight() const;
68 TCoordinate getWidth() const;
69 virtual void resize(TCoordinate height, TCoordinate width);
70
71// ---------------------------------------------------------------------------------------------------------------------
72
73 virtual void addObstacle(const node_type &n);
74 virtual void addObstacle(node_type &&n);
75 virtual void addObstacle(TCoordinate &&x, TCoordinate &&y);
76
77// ---------------------------------------------------------------------------------------------------------------------
78
79 virtual ext::pair<bool, node_type> step(const node_type &n, direction_type direction) const;
80 virtual ext::pair<bool, TEdge> stepEdge(const node_type &n, direction_type direction) const;
81
82// ---------------------------------------------------------------------------------------------------------------------
83
84 virtual bool isObstacle(const node_type &n) const;
85 virtual bool isNode(const node_type &n) const;
86
87// ---------------------------------------------------------------------------------------------------------------------
88
89 virtual bool isValidDirection(direction_type direction) const = 0;
90
91// ---------------------------------------------------------------------------------------------------------------------
92
93 virtual std::string toStringAs(const ext::map<node_type, char> &map) const;
94
95// ---------------------------------------------------------------------------------------------------------------------
96
97 protected:
98 virtual bool checkCoordinates(const node_type &coordinate) const;
99 virtual void throwCoordinates(const node_type &coordinate) const;
100
101// ---------------------------------------------------------------------------------------------------------------------
102
103 virtual TEdge createEdge(const node_type &a, const node_type &b) const = 0;
104
105// ---------------------------------------------------------------------------------------------------------------------
106
107// =====================================================================================================================
108// GraphInterface interface
109
110 public:
111 size_t nodeCount() const override;
112 size_t edgeCount() const override;
113
114// ---------------------------------------------------------------------------------------------------------------------
115
116 ext::set<node_type> getNodes() const override;
117 ext::vector<TEdge> getEdges() const override;
118
119// ---------------------------------------------------------------------------------------------------------------------
120
121 ext::set<node_type> successors(const node_type &n) const override;
122 ext::vector<TEdge> successorEdges(const node_type &n) const override;
123 ext::set<node_type> predecessors(const node_type &n) const override;
124 ext::vector<TEdge> predecessorEdges(const node_type &n) const override;
125
126
127// ---------------------------------------------------------------------------------------------------------------------
128
129};
130
131// =====================================================================================================================
132
133template<typename TCoordinate, typename TEdge>
134SquareGrid<TCoordinate, TEdge>::SquareGrid(TCoordinate height, TCoordinate width)
135 : m_height(height), m_width(width), m_obstacles(ext::set<node_type>()) {
136}
137
138// ---------------------------------------------------------------------------------------------------------------------
139
140template<typename TCoordinate, typename TEdge>
142 TEdge>::getObstacleList() const &{
143 return m_obstacles;
144}
145
146template<typename TCoordinate, typename TEdge>
149 return std::move(m_obstacles);
150}
151
152// ---------------------------------------------------------------------------------------------------------------------
153
154template<typename TCoordinate, typename TEdge>
156 return m_height;
157}
158
159template<typename TCoordinate, typename TEdge>
161 return m_width;
162}
163
164// ---------------------------------------------------------------------------------------------------------------------
165
166template<typename TCoordinate, typename TEdge>
167void SquareGrid<TCoordinate, TEdge>::resize(TCoordinate height, TCoordinate width) {
168 if (m_width <= width && m_height <= height) {
169 m_width = width;
170 m_height = height;
171 return;
172 }
173
174 m_width = width;
175 m_height = height;
176
177 ext::set<node_type> new_obstacles;
178
179 for (auto i: m_obstacles) {
180 if (checkCoordinates(i)) {
181 new_obstacles.insert(std::move(i));
182 }
183 }
184
185 m_obstacles = new_obstacles;
186}
187
188// ---------------------------------------------------------------------------------------------------------------------
189
190template<typename TCoordinate, typename TEdge>
193 m_obstacles.insert(n);
194}
195
196template<typename TCoordinate, typename TEdge>
199
200 m_obstacles.insert(std::forward<node_type>(n));
201}
202
203template<typename TCoordinate, typename TEdge>
204void SquareGrid<TCoordinate, TEdge>::addObstacle(TCoordinate &&x, TCoordinate &&y) {
205 addObstacle(ext::make_pair(std::forward<TCoordinate>(x), std::forward<TCoordinate>(y)));
206}
207
208// ---------------------------------------------------------------------------------------------------------------------
209
210template<typename TCoordinate, typename TEdge>
213 SquareGrid::direction_type direction) const {
214 node_type v = GridFunction::squareGridDirectionVector<TCoordinate>(direction);
215 node_type tmp(n.first + v.first, n.second + v.second);
216 bool validity = checkCoordinates(tmp) && !isObstacle(tmp) && isValidDirection(direction);
217
218 return ext::make_pair(validity, tmp); // Bool if node is in grid
219}
220
221template<typename TCoordinate, typename TEdge>
224 SquareGrid::direction_type direction) const {
225 node_type v = GridFunction::squareGridDirectionVector<TCoordinate>(direction);
226 node_type tmp(n.first + v.first, n.second + v.second);
227 bool validity = checkCoordinates(tmp) && !isObstacle(tmp) && isValidDirection(direction);
228
229 return ext::make_pair(validity, createEdge(n, tmp)); // Bool if node is in grid
230}
231
232// ---------------------------------------------------------------------------------------------------------------------
233
234template<typename TCoordinate, typename TEdge>
236 return m_obstacles.find(n) != m_obstacles.end();
237}
238
239// ---------------------------------------------------------------------------------------------------------------------
240
241template<typename TCoordinate, typename TEdge>
243 return !isObstacle(n);
244}
245
246// ---------------------------------------------------------------------------------------------------------------------
247
248template<typename TCoordinate, typename TEdge>
250 char> &map) const {
251 std::string os;
252
253 os += '+';
254 for (TCoordinate i = 0; i < m_width; ++i) {
255 os += "—";
256 }
257 os += "+\n";
258
259 for (TCoordinate i = 0; i < m_height; ++i) {
260 os += '|';
261
262 for (TCoordinate j = 0; j < m_width; ++j) {
263 node_type tmp = ext::make_pair(i, j);
264
265 if (m_obstacles.find(tmp) != m_obstacles.end()) {
266 os += "#";
267 } else {
268
269 if (map.find(tmp) != map.end()) {
270 os += map.at(tmp);
271 } else {
272 os += ".";
273 }
274 }
275
276 }
277
278 os += "|\n";
279 }
280
281 os += '+';
282 for (TCoordinate i = 0; i < m_width; ++i) {
283 os += "—";
284 }
285 os += "+\n";
286
287 return os;
288}
289
290// ---------------------------------------------------------------------------------------------------------------------
291
292template<typename TCoordinate, typename TEdge>
294 return coordinate.first >= 0 &&
295 coordinate.first < m_height &&
296 coordinate.second >= 0 &&
297 coordinate.second < m_width;
298}
299
300template<typename TCoordinate, typename TEdge>
302 if (!checkCoordinates(coordinate)) {
303 throw std::out_of_range("Coordinates are out of range");
304 }
305}
306
307// ---------------------------------------------------------------------------------------------------------------------
308
309template<typename TCoordinate, typename TEdge>
311 return m_height * m_width - m_obstacles.size();
312}
313
314template<typename TCoordinate, typename TEdge>
316 unsigned long cnt = 0;
317
320 directions.insert(SquareGridDirections::south_east);
321 }
322
324 directions.insert(SquareGridDirections::south_west);
325 }
326
327 for (TCoordinate i = 0; i < m_height; ++i) {
328 for (TCoordinate j = 0; j < m_width; ++j) {
329 node_type n = ext::make_pair(i, j);
330
331 for (const auto &direction : directions) {
332 node_type v = GridFunction::squareGridDirectionVector<TCoordinate>(direction);
333 node_type tmp = ext::make_pair(n.first + v.first, n.second + v.second);
334
335 if (checkCoordinates(tmp) && !isObstacle(tmp)) {
336 ++cnt;
337 }
338 }
339
340 }
341 }
342 return cnt;
343}
344
345// ---------------------------------------------------------------------------------------------------------------------
346
347template<typename TCoordinate, typename TEdge>
351
352 for (TCoordinate i = 0; i < m_height; ++i) {
353 for (TCoordinate j = 0; j < m_width; ++j) {
354 node_type tmp = ext::make_pair(i, j);
355
356 if (!isObstacle(tmp)) {
357 set.insert(std::move(tmp));
358 }
359 }
360 }
361
362 return set;
363}
364
365template<typename TCoordinate, typename TEdge>
368
371 directions.insert(SquareGridDirections::south_east);
372 }
373
375 directions.insert(SquareGridDirections::south_west);
376 }
377
378 for (TCoordinate i = 0; i < m_height; ++i) {
379 for (TCoordinate j = 0; j < m_width; ++j) {
380 node_type n = ext::make_pair(i, j);
381
382 for (const auto &direction : directions) {
383 node_type v = GridFunction::squareGridDirectionVector<TCoordinate>(direction);
384 node_type tmp = ext::make_pair(n.first + v.first, n.second + v.second);
385
386 if (checkCoordinates(tmp) && !isObstacle(tmp)) {
387 vec.push_back(createEdge(n, tmp));
388 }
389 }
390
391 }
392 }
393
394 return vec;
395}
396
397// ---------------------------------------------------------------------------------------------------------------------
398
399template<typename TCoordinate, typename TEdge>
401SquareGrid<TCoordinate,
402 TEdge>::successors(const SquareGrid::node_type &n) const {
404
406
407 if (m_obstacles.find(n) != m_obstacles.end()) {
408 return set;
409 }
410
411 for (const auto &direction : SQUARE_GRID_DIRECTIONS) {
412 if (!isValidDirection(direction)) continue;
413
414 node_type v = GridFunction::squareGridDirectionVector<TCoordinate>(direction);
415 node_type tmp = ext::make_pair(n.first + v.first, n.second + v.second);
416
417 if (checkCoordinates(tmp) && !isObstacle(tmp)) {
418 set.insert(std::move(tmp));
419 }
420 }
421
422 return set;
423}
424
425template<typename TCoordinate, typename TEdge>
429
431
432 if (m_obstacles.find(n) != m_obstacles.end()) {
433 return vec;
434 }
435
436 for (const auto &direction : SQUARE_GRID_DIRECTIONS) {
437 if (!isValidDirection(direction)) continue;
438 node_type v = GridFunction::squareGridDirectionVector<TCoordinate>(direction);
439 node_type tmp = ext::make_pair(n.first + v.first, n.second + v.second);
440
441 if (checkCoordinates(tmp) && !isObstacle(tmp)) {
442 vec.push_back(createEdge(n, tmp));
443 }
444 }
445
446 return vec;
447}
448
449template<typename TCoordinate, typename TEdge>
452 return this->successors(n);
453}
454
455template<typename TCoordinate, typename TEdge>
458 return this->successorEdges(n);
459}
460
461// ---------------------------------------------------------------------------------------------------------------------
462
463template<typename TCoordinate, typename TEdge>
465 ostream << "(" << this->name() << std::endl;
466 ostream << '+';
467 for (TCoordinate i = 0; i < m_width; ++i) {
468 ostream << "—";
469 }
470 ostream << "+\n";
471
472 for (TCoordinate i = 0; i < m_height; ++i) {
473 ostream << '|';
474
475 for (TCoordinate j = 0; j < m_width; ++j) {
476 node_type tmp = ext::make_pair(i, j);
477
478 if (m_obstacles.find(tmp) != m_obstacles.end()) {
479 ostream << "#";
480 } else {
481 ostream << ".";
482 }
483
484 }
485
486 ostream << "|\n";
487 }
488
489 ostream << '+';
490 for (TCoordinate i = 0; i < m_width; ++i) {
491 ostream << "—";
492 }
493 ostream << "+\n";
494
495 ostream << ")";
496}
497
498// ---------------------------------------------------------------------------------------------------------------------
499
500// =====================================================================================================================
501
502} // namespace grid
Class extending the map class from the standard library. Original reason is to allow printing of the ...
Definition: map.hpp:48
Definition: ostream.h:14
Class extending the pair class from the standard library. Original reason is to allow printing of the...
Definition: pair.hpp:43
Definition: set.hpp:44
Class extending the vector class from the standard library. Original reason is to allow printing of t...
Definition: vector.hpp:45
Definition: GridInterface.hpp:20
TCoordinate coordinate_type
Definition: GridInterface.hpp:23
TEdge edge_type
Definition: GridInterface.hpp:24
virtual std::string name() const =0
Definition: SquareGrid.hpp:29
TCoordinate getHeight() const
Definition: SquareGrid.hpp:155
ext::vector< TEdge > getEdges() const override
Definition: SquareGrid.hpp:366
SquareGrid(TCoordinate height, TCoordinate width)
Definition: SquareGrid.hpp:134
size_t nodeCount() const override
Definition: SquareGrid.hpp:310
TCoordinate getWidth() const
Definition: SquareGrid.hpp:160
ext::set< node_type > predecessors(const node_type &n) const override
Definition: SquareGrid.hpp:451
size_t edgeCount() const override
Definition: SquareGrid.hpp:315
ext::set< node_type > getNodes() const override
Definition: SquareGrid.hpp:349
TCoordinate m_height
Definition: SquareGrid.hpp:41
virtual ext::pair< bool, node_type > step(const node_type &n, direction_type direction) const
Definition: SquareGrid.hpp:212
virtual bool checkCoordinates(const node_type &coordinate) const
Definition: SquareGrid.hpp:293
virtual bool isNode(const node_type &n) const
Definition: SquareGrid.hpp:242
void operator>>(ext::ostream &ostream) const override
Definition: SquareGrid.hpp:464
TCoordinate m_width
Definition: SquareGrid.hpp:42
virtual bool isValidDirection(direction_type direction) const =0
virtual void addObstacle(const node_type &n)
Definition: SquareGrid.hpp:191
ext::vector< TEdge > predecessorEdges(const node_type &n) const override
Definition: SquareGrid.hpp:457
ext::set< node_type > m_obstacles
Definition: SquareGrid.hpp:43
virtual void throwCoordinates(const node_type &coordinate) const
Definition: SquareGrid.hpp:301
ext::set< node_type > successors(const node_type &n) const override
Definition: SquareGrid.hpp:402
virtual TEdge createEdge(const node_type &a, const node_type &b) const =0
const ext::set< node_type > & getObstacleList() const &
Definition: SquareGrid.hpp:142
virtual ext::pair< bool, TEdge > stepEdge(const node_type &n, direction_type direction) const
Definition: SquareGrid.hpp:223
virtual std::string toStringAs(const ext::map< node_type, char > &map) const
Definition: SquareGrid.hpp:249
virtual bool isObstacle(const node_type &n) const
Definition: SquareGrid.hpp:235
ext::vector< TEdge > successorEdges(const node_type &n) const override
Definition: SquareGrid.hpp:427
virtual void resize(TCoordinate height, TCoordinate width)
Definition: SquareGrid.hpp:167
int i
Definition: AllEpsilonClosure.h:118
Definition: sigHandler.cpp:20
constexpr auto make_pair(T1 &&x, T2 &&y)
Definition: pair.hpp:79
Definition: GridDirection.hpp:12
const ext::set< SquareGridDirections > SQUARE_GRID_DIRECTIONS
Definition: GridDirection.hpp:28
SquareGridDirections
Definition: GridDirection.hpp:16
Definition: FordFulkerson.hpp:16