The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
translation.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2006 - 2016 by Mark de Wever <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 /** @file */
16 
17 #ifndef TERRAIN_TRANSLATION_H_INCLUDED
18 #define TERRAIN_TRANSLATION_H_INCLUDED
19 
20 #include <vector>
21 #include <map>
22 #include <stdint.h>
23 #include <boost/bimap.hpp>
24 #include <boost/bimap/set_of.hpp>
25 #include <boost/bimap/multiset_of.hpp>
26 #include "exceptions.hpp"
27 
28 namespace t_translation {
29 
30  /**
31  * Return the maximum allowed map size (in either dimension),
32  * the maximum map area is, therefore, this value squared.
33  */
34  size_t max_map_size();
35 
36  typedef uint32_t t_layer;
37  const t_layer WILDCARD = 0x2A000000;
38  const t_layer NO_LAYER = 0xFFFFFFFF;
39 
40  // The definitions for a terrain
41  /**
42  * A terrain string which is converted to a terrain is a string with 1 or 2 layers
43  * the layers are separated by a caret and each group consists of 2 to 4 characters
44  * if no second layer is defined it is stored as 0xFFFFFFFF, if the second layer
45  * is empty (needed for matching) the layer has the value 0.
46  */
47  struct t_terrain {
48  t_terrain(const std::string& b, const std::string& o);
49  t_terrain(const std::string& b, t_layer o = NO_LAYER);
50  t_terrain(t_layer b, t_layer o) : base(b), overlay(o) {}
51  t_terrain() : base(0), overlay(NO_LAYER) {}
52 
53  t_layer base;
54  t_layer overlay;
55  };
57 
58  inline bool operator<(const t_terrain& a, const t_terrain& b)
59  { return a.base < b.base || (a.base == b.base && a.overlay < b.overlay); }
60 
61  inline bool operator==(const t_terrain& a, const t_terrain& b)
62  { return a.base == b.base && a.overlay == b.overlay; }
63 
64  inline bool operator!=(const t_terrain& a, const t_terrain& b)
65  { return a.base != b.base || a.overlay != b.overlay; }
66 
67  inline t_terrain operator&(const t_terrain& a, const t_terrain& b)
68  { return t_terrain(a.base & b.base, a.overlay & b.overlay); }
69 
70  inline t_terrain operator|(const t_terrain& a, const t_terrain& b)
71  { return t_terrain(a.base | b.base, a.overlay | b.overlay); }
72 
73  // operator<< is defined later
74 
75  typedef std::vector<t_terrain> t_list;
76  typedef std::vector<std::vector<t_terrain> > t_map;
77 
78  /**
79  * This structure can be used for matching terrain strings.
80  * It optimized for strings that need to be matched often,
81  * and caches the wildcard info required for matching.
82  */
83  struct t_match{
84  t_match();
85  t_match(const std::string& str, const t_layer filler = NO_LAYER);
86  t_match(const t_terrain& tcode);
87 
88  t_list terrain;
89  t_list mask;
92  bool is_empty;
93  };
94 
95  /** Contains an x and y coordinate used for starting positions in maps. */
96  /** TODO: remove this class and use map_location */
97  struct coordinate {
98  coordinate();
99  coordinate(const int x_, const int y_);
100  int x;
101  int y;
102  friend bool operator <(const coordinate&l, const coordinate&r) {
103  return l.x < r.x || (l.x == r.x && l.y < r.y);
104  }
105  };
106 
107  // Exception thrown if there's an error with the terrain.
108  // Note: atm most thrown result in a crash, but I like
109  // an uncatched exception better than an assert.
110  struct error : public game::error {
111  error(const std::string& message) : game::error(message) {}
112  };
113 
114  // Some types of terrain which must be known, and can't just
115  // be loaded in dynamically because they're special.
116  // It's asserted that there will be corresponding entries for
117  // these types of terrain in the terrain configuration file.
118  extern const t_terrain VOID_TERRAIN;
119  extern const t_terrain FOGGED;
120 
121  // On the map the user can use this type to make odd shaped maps look good.
122  extern const t_terrain OFF_MAP_USER;
123 
124  extern const t_terrain HUMAN_CASTLE;
125  extern const t_terrain HUMAN_KEEP;
126  extern const t_terrain SHALLOW_WATER;
127  extern const t_terrain DEEP_WATER;
128  extern const t_terrain GRASS_LAND;
129  extern const t_terrain FOREST;
130  extern const t_terrain MOUNTAIN;
131  extern const t_terrain HILL;
132 
133  extern const t_terrain CAVE_WALL;
134  extern const t_terrain CAVE;
135  extern const t_terrain UNDERGROUND_VILLAGE;
136  extern const t_terrain DWARVEN_CASTLE;
137  extern const t_terrain DWARVEN_KEEP;
138 
139  extern const t_terrain PLUS; // +
140  extern const t_terrain MINUS; // -
141  extern const t_terrain NOT; // !
142  extern const t_terrain STAR; // *
143  extern const t_terrain BASE; // references the base terrain in movement/defense aliases
144 
145  extern const t_match ALL_FORESTS;
146  extern const t_match ALL_HILLS;
147  extern const t_match ALL_MOUNTAINS; //excluding impassable mountains
148  extern const t_match ALL_SWAMPS;
149 
150  /**
151  * Reads a single terrain from a string.
152  *
153  * @param str The string which should contain 1 terrain code;
154  the new format of a terrain code
155  * is 2 to 4 characters in the set
156  *@verbatim
157  * [a-Z][A-Z]/|\_
158  *@endverbatim
159  * The underscore is intended for internal use.
160  * Other letters and characters are not validated but
161  * users of these letters can get nasty surprises.
162  * The * is used as wildcard in some cases.
163  * The terrain code can be two groups separated by a caret,
164  * the first group is the base terrain,
165  * the second the overlay terrain.
166  *
167  * @param filler if there's no layer this value will be used as the second layer
168  *
169  * @return A single terrain code
170  */
171  t_terrain read_terrain_code(const std::string& str, const t_layer filler = NO_LAYER);
172 
173  /**
174  * Writes a single terrain code to a string.
175  * The writers only support the new format.
176  *
177  * @param tcode The terrain code to convert to a string
178  *
179  * @return A string containing the terrain code
180  */
182  inline std::ostream &operator<<(std::ostream &s, const t_terrain &a)
183  { s << write_terrain_code(a); return s; }
184 
185  /**
186  * Reads a list of terrains from a string, when reading the
187  *
188  * @param str A string with one or more terrain codes (see read_terrain_code)
189  * @param filler If there's no layer, this value will be used as the second layer
190  *
191  * @returns A vector which contains the terrain codes found in the string
192  */
193  t_list read_list(const std::string& str, const t_layer filler = NO_LAYER);
194 
195  /**
196  * Writes a list of terrains to a string, only writes the new format.
197  *
198  * @param list A vector with one or more terrain codes
199  *
200  * @returns A string with the terrain codes, comma separated
201  * and a space behind the commas. Not padded.
202  */
203  std::string write_list(const t_list& list);
204 
205  using tstarting_positions = boost::bimaps::bimap<boost::bimaps::set_of<std::string>, boost::bimaps::multiset_of<coordinate>>;
206  /**
207  * Reads a gamemap string into a 2D vector
208  *
209  * @param str A string containing the gamemap, the following rules
210  * are stated for a gamemap:
211  * * The map is square
212  * * The map can be prefixed with one or more empty lines,
213  * these lines are ignored
214  * * The map can be postfixed with one or more empty lines,
215  * these lines are ignored
216  * * Every end of line can be followed by one or more empty
217  * lines, these lines are ignored.
218  * @deprecated NOTE it's deprecated to use this feature.
219  * * Terrain strings are separated by comma's or an end of line
220  * symbol, for the last terrain string in the row. For
221  * readability it's allowed to pad strings with either spaces
222  * or tab, however the tab is deprecated.
223  * * A terrain string contains either a terrain or a terrain and
224  * starting location. The following format is used
225  * [S ]T
226  * S = starting location a positive non-zero number
227  * T = terrain code (see read_terrain_code)
228  * @param starting_positions This parameter will be filled with the starting
229  * locations found. Starting locations can only occur once
230  * if multiple definitions occur of the same position only
231  * the last is stored. The returned value is a map:
232  * * first the starting locations
233  * * second a coordinate structure where the location was found
234  *
235  * @returns A 2D vector with the terrains found the vector data is stored
236  * like result[x][y] where x the column number is and y the row number.
237  */
238  t_map read_game_map(const std::string& str, tstarting_positions& starting_positions, coordinate border_offset = coordinate{ 0, 0 });
239 
240  /**
241  * Write a gamemap in to a vector string.
242  *
243  * @param map A terrain vector, as returned from read_game_map
244  * @param starting_positions A starting positions map, as returned from read_game_map
245  *
246  * @returns A terrain string which can be read with read_game_map.
247  * For readability the map is padded to groups of 12 chars,
248  * followed by a comma and space.
249  */
250  std::string write_game_map(const t_map& map, const tstarting_positions& starting_positions = tstarting_positions(), coordinate border_offset = coordinate{ 0, 0 });
251 
252  /**
253  * Tests whether a specific terrain matches a list of expressions.
254  * The list can use wildcard matching with *.
255  * It also has an inversion function.
256  * When a ! is found the result of the match is inverted.
257  * The matching stops at the first match (regardless of the ! found)
258  * the data is match from start to end.
259  *
260  * Example:
261  * Ww, W* does match and returns true
262  * Ww, {!, W*} does match and returns false (due to the !)
263  * WW, Ww doesn't match and return false
264  *
265  * Multilayer rules:
266  * If a terrain has multiple layers, each layer will be matched separately,
267  * returning true only if both layers match.
268  *
269  * Example:
270  * A*^* matches Abcd but also Abcd^Abcd
271  * A*^ matches Abcd but *not* Abcd^Abcd
272  * A*^Abcd does not match Abcd but matches Abcd^Abcd
273  *
274  * Note: If an expression doesn't specify a second layer (i.e. it contains
275  * no caret) the second layer will be filled in with a default value
276  * (See read_terrain_code and read_list).
277  *
278  * In the terrain building code, the second layer will default to the wildcard,
279  * so both A* and A*^* will match Abcd^Abcd
280  *
281  * @param src the value to match (may not contain wildcards)
282  * @param dest the list of expressions to match against
283  *
284  * @returns the result of the match (depending on the !'s)
285  */
286  bool terrain_matches(const t_terrain& src, const t_list& dest);
287 
288  /**
289  * Tests whether a specific terrain matches an expression,
290  * for matching rules see above.
291  *
292  * @param src the value to match (may not contain wildcards)
293  * @param dest the expression to match against
294  *
295  * @returns the result of the match (depending on the !'s)
296  */
297  bool terrain_matches(const t_terrain& src, const t_terrain& dest);
298 
299  /**
300  * Tests whether a certain terrain matches a list of expressions, for matching
301  * rules see above. The matching requires some bit mask which impose a
302  * certain overhead. This version uses a cache to cache the masks so if
303  * a list needs to be matched often this version is preferred.
304  *
305  * @param src the value to match (may not contain wildcards)
306  * @param dest the cached list of expressions to match against
307  *
308  * @returns the result of the match (depending on the !'s)
309  */
310  bool terrain_matches(const t_terrain& src, const t_match& dest);
311 
312  /**
313  * Tests whether a terrain code contains a wildcard
314  *
315  * @param tcode the terrain code to test for a wildcard
316  *
317  * @returns true if wildcard found, else false
318  */
319  bool has_wildcard(const t_terrain& tcode);
320 
321  /**
322  * Tests whether a terrain-code list contains at least
323  * one item with a wildcard
324  *
325  * @param list the list to test for a wildcard
326  *
327  * @returns true if a wildcard found, else false
328  */
329  bool has_wildcard(const t_list& list);
330 
331  // These terrain letters are in the builder format,
332  // and not usable in other parts of the engine
333  const t_layer TB_STAR = '*' << 24; // It can be assumed this is the equivalent of STAR
334  const t_layer TB_DOT = '.' << 24;
335 
336  /**
337  * Reads a builder map.
338  * A builder map differs a great deal from a normal map,
339  * hence the different functions.
340  *
341  * @param str The map data, a terrain letter is either a * or a . or a number as
342  * anchor. The star or dot are stored in the base part of the terrain
343  * and the anchor in the overlay part. If more letters are allowed as
344  * special case they will be stored in the base part.
345  * Anchor 0 is no anchor.
346  *
347  * @returns A 2D vector with the data found the vector data is stored
348  * like result[y][x] where x the column number is and y the row number.
349  */
350  t_map read_builder_map(const std::string& str);
351 
352 } // end namespace t_translation
353 
354 #endif
Contains an x and y coordinate used for starting positions in maps.
Definition: translation.hpp:97
tformula< unsigned > x_
The x coordinate of the rectangle.
Definition: canvas.cpp:682
const t_terrain STAR
const t_layer TB_DOT
boost::bimaps::bimap< boost::bimaps::set_of< std::string >, boost::bimaps::multiset_of< coordinate >> tstarting_positions
const t_terrain NOT
const t_terrain UNDERGROUND_VILLAGE
t_list read_list(const std::string &str, const t_layer filler)
Reads a list of terrains from a string, when reading the.
std::string write_game_map(const t_map &map, const tstarting_positions &starting_positions, coordinate border_offset)
Write a gamemap in to a vector string.
size_t max_map_size()
Return the maximum allowed map size (in either dimension), the maximum map area is, therefore, this value squared.
Definition: translation.cpp:36
const t_terrain HILL
error(const std::string &message)
const t_layer WILDCARD
Definition: translation.hpp:37
const t_terrain NONE_TERRAIN
Definition: translation.hpp:56
const t_terrain MOUNTAIN
boost::uint32_t uint32_t
Definition: xbrz.hpp:45
const t_terrain MINUS
std::ostream & operator<<(std::ostream &s, const t_terrain &a)
t_map read_game_map(const std::string &str, tstarting_positions &starting_positions, coordinate border_offset)
Reads a gamemap string into a 2D vector.
bool has_wildcard(const t_terrain &tcode)
Tests whether a terrain code contains a wildcard.
const t_terrain DEEP_WATER
const t_terrain FOGGED
GLenum src
Definition: glew.h:2392
const t_terrain OFF_MAP_USER
t_terrain read_terrain_code(const std::string &str, const t_layer filler)
Reads a single terrain from a string.
GLdouble l
Definition: glew.h:6966
const t_terrain HUMAN_KEEP
GLdouble GLdouble GLdouble b
Definition: glew.h:6966
std::vector< std::vector< t_terrain > > t_map
Definition: translation.hpp:76
const t_terrain BASE
const t_terrain GRASS_LAND
const t_match ALL_FORESTS
const t_terrain PLUS
std::string write_list(const t_list &list)
Writes a list of terrains to a string, only writes the new format.
const t_terrain FOREST
This structure can be used for matching terrain strings.
Definition: translation.hpp:83
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:7319
const t_terrain DWARVEN_CASTLE
bool operator!=(const t_terrain &a, const t_terrain &b)
Definition: translation.hpp:64
const t_layer TB_STAR
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...
Definition: translation.hpp:47
const t_terrain HUMAN_CASTLE
t_terrain operator&(const t_terrain &a, const t_terrain &b)
Definition: translation.hpp:67
const t_terrain CAVE
const t_match ALL_MOUNTAINS("!,*^V*,!,M*")
t_terrain(t_layer b, t_layer o)
Definition: translation.hpp:50
const t_terrain CAVE_WALL
bool operator==(const t_terrain &a, const t_terrain &b)
Definition: translation.hpp:61
bool terrain_matches(const t_terrain &src, const t_terrain &dest)
Tests whether a specific terrain matches an expression, for matching rules see above.
t_terrain operator|(const t_terrain &a, const t_terrain &b)
Definition: translation.hpp:70
tformula< unsigned > y_
The y coordinate of the rectangle.
Definition: canvas.cpp:682
friend bool operator<(const coordinate &l, const coordinate &r)
GLdouble GLdouble GLdouble r
Definition: glew.h:1374
const t_terrain DWARVEN_KEEP
std::string write_terrain_code(const t_terrain &tcode)
Writes a single terrain code to a string.
const t_layer NO_LAYER
Definition: translation.hpp:38
const t_terrain VOID_TERRAIN
Base class for all the errors encountered by the engine.
Definition: exceptions.hpp:27
bool operator<(const t_terrain &a, const t_terrain &b)
Definition: translation.hpp:58
const t_match ALL_SWAMPS("!,*^V*,*^B*,!,S*")
GLsizei GLenum GLuint GLuint GLsizei char * message
Definition: glew.h:2499
uint32_t t_layer
Definition: translation.hpp:36
const t_terrain SHALLOW_WATER
GLdouble s
Definition: glew.h:1358
GLsizei const GLcharARB ** string
Definition: glew.h:4503
t_map read_builder_map(const std::string &str)
Reads a builder map.
const t_match ALL_HILLS("!,*^V*,!,H*")
std::vector< t_terrain > t_list
Definition: translation.hpp:75