-
Notifications
You must be signed in to change notification settings - Fork 0
/
grid.h
executable file
·169 lines (150 loc) · 4.32 KB
/
grid.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/// @file grid.h
/// @author Alberto Santagostino
#ifndef DATA_STRUCTURES_GRID_H
#define DATA_STRUCTURES_GRID_H
#include <algorithm>
#include <optional>
#include <unordered_map>
#ifdef TEST_BUILD
#include <data_structures/matrix.h>
#include <primitives/actor.h>
#else
#include <commonlib/include/data_structures/matrix.h>
#include <commonlib/include/primitives/actor.h>
#endif
namespace commonlib
{
enum class TileType
{
kTileType_Empty,
kTileType_Wall,
kTileType_Tree,
kTileType_Undefined
};
typedef std::unordered_map<std::size_t, Actor> ActorsMap;
typedef std::unordered_map<TileType, char> TilesMap;
/// @class Grid
/// @brief 2D characters grid, inherited as Matrix<char>. It holds a number of actors
class Grid : public Matrix<char>
{
public:
// Constructors
using Matrix::Matrix;
// Grid-specific setters
bool AddActor(Actor actor);
bool AddTileTypeDefinition(TileType tiletype, char character);
bool ActorExists(const std::size_t actor_id);
inline void MakeInfinite(const bool infinite) { m_infinite = infinite; }
// Grid-specific getters
inline const ActorsMap GetActors() { return m_actors; }
bool GetActor(const std::size_t actor_id);
bool GetActor(const std::size_t actor_id, Actor& actor);
const TileType GetTileType(std::size_t row, std::size_t col);
// Operators
char& operator()(std::size_t row, std::size_t col);
char const& operator()(std::size_t row, std::size_t col) const;
private:
ActorsMap m_actors;
TilesMap m_tiles;
bool m_infinite;
};
/// @brief Check if a specific actor exists
/// @param actor_id Id of the actor
bool Grid::GetActor(const std::size_t actor_id)
{
ActorsMap::const_iterator got = m_actors.find(actor_id);
return (got == m_actors.end()) ? (false) : (true);
}
/// @brief Return a specific actor
/// @param actor_id Id of the actor
/// @param actor Variable to fill with the desired actor
bool Grid::GetActor(const std::size_t actor_id, Actor& actor)
{
ActorsMap::iterator got = m_actors.find(actor_id);
if (got == m_actors.end())
{
return false;
}
else
{
actor = got->second;
return true;
}
}
/// @brief Get the tile type at the specific position
const TileType Grid::GetTileType(std::size_t row, std::size_t col)
{
auto tile_char = this->operator()(row, col);
auto it = std::find_if(m_tiles.begin(), m_tiles.end(), [tile_char](auto& p) { return p.second == tile_char; });
if (it != m_tiles.end())
{
return it->first;
}
return TileType::kTileType_Undefined;
}
/// @brief Add an actor to the grid
/// @param actor Actor to add
bool Grid::AddActor(Actor actor)
{
const std::size_t id = actor.Id();
if (!GetActor(id))
{
m_actors.insert(std::make_pair(id, actor));
return true;
}
return false;
}
/// @brief Add a tile definition (linking a tile type to a character)
/// @param tiletype Tile type to define (type: TileType)
/// @param character Character to link
bool Grid::AddTileTypeDefinition(TileType tiletype, char character)
{
if (tiletype != TileType::kTileType_Undefined)
{
std::vector<char> vals;
for (auto kv : m_tiles)
{
vals.push_back(kv.second);
}
if (!std::count(vals.begin(), vals.end(), character))
{
m_tiles.insert(std::make_pair(tiletype, character));
return true;
}
}
return false;
}
/// @brief Redefinition of operator() to take into account infinite grids
char& Grid::operator()(std::size_t row, std::size_t col)
{
if (row >= m_rows || col >= m_cols)
{
if (m_infinite)
{
return m_data[row % m_rows][col % m_cols];
}
else
{
throw std::out_of_range("Matrix<T>::operator(): Index is out of range");
}
}
return m_data[row][col];
}
/// @brief Redefinition of operator() to take into account infinite grids
char const& Grid::operator()(std::size_t row, std::size_t col) const
{
if (row >= m_rows || col >= m_cols)
{
if (m_infinite)
{
return m_data[row % m_rows][col % m_cols];
}
else
{
throw std::out_of_range("Matrix<T>::operator(): Index is out of range");
}
}
return m_data[row][col];
}
} // namespace commonlib
#endif // DATA_STRUCTURES_GRID_H