Algorithms Library Toolkit
A toolkit for algorithms, especially for algorithms on formal languages
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