The Battle for Wesnoth  1.13.10+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
test_map_location.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2017 by Chris Beck <render787@gmail.com>
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 #define GETTEXT_DOMAIN "wesnoth-test"
16 
17 #include "utils/functional.hpp"
18 #include <boost/test/unit_test.hpp>
19 
20 #include "map/location.hpp"
21 
22 static std::vector<map_location> preset_locs;
30 
31 
32 struct MLFixture
33 {
35  {
36  va = map_location(3,4);
37  vb = map_location(10,8);
38  vc = map_location(0,9);
39  vz = map_location::ZERO();
40  vt1 = va.vector_negation();
41  vt2 = vb.vector_sum(vc);
42  vt3 = va.vector_sum(vc.vector_negation());
43 
44  vs1 = vz.get_direction(nw);
45  vs2 = vz.get_direction(n).get_direction(ne);
46  vs3 = vz.get_direction(s).get_direction(se);
47  vs4 = vz.get_direction(sw).get_direction(se);
48 
49  preset_locs.push_back(va);
50  preset_locs.push_back(vb);
51  preset_locs.push_back(vc);
52  preset_locs.push_back(vz);
53  preset_locs.push_back(vt1);
54  preset_locs.push_back(vt2);
55  preset_locs.push_back(vt3);
56  preset_locs.push_back(vs1);
57  preset_locs.push_back(vs2);
58  preset_locs.push_back(vs3);
59  preset_locs.push_back(vs4);
60  }
61 
63 };
64 
66 
67 BOOST_AUTO_TEST_SUITE ( test_map_location )
68 
69 //#define MAP_LOCATION_GET_OUTPUT
70 
71 #ifndef MAP_LOCATION_GET_OUTPUT
73 {
74  map_location ret(v1);
76  return ret;
77 }
78 #endif
79 
80 static void characterization_distance_direction (const std::vector<map_location> & locs, const std::vector<map_location::DIRECTION> & dir_answers, const std::vector<size_t> & int_answers, map_location::RELATIVE_DIR_MODE mode)
81 {
82  BOOST_CHECK_EQUAL(dir_answers.size(), int_answers.size());
83 
84  std::vector<map_location::DIRECTION>::const_iterator dir_it = dir_answers.begin();
85  std::vector<size_t>::const_iterator int_it = int_answers.begin();
86 
87  for (std::vector<map_location>::const_iterator it_a = locs.begin(); it_a != locs.end(); ++it_a) {
88  for (std::vector<map_location>::const_iterator it_b = it_a + 1; it_b != locs.end(); ++it_b) {
89  const map_location & a = *it_a;
90  const map_location & b = *it_b;
91 #ifdef MAP_LOCATION_GET_OUTPUT
92  std::cout << "(std::make_pair(" << distance_between(a,b) << ",\t\""
93  << map_location::write_direction( a.get_relative_dir(b,mode)) << "\"))" << std::endl;
94 #else
95  int expected_dist = *(int_it++);
96  map_location::DIRECTION expected_dir = *(dir_it++);
97  BOOST_CHECK_EQUAL( expected_dist, distance_between(a,b) );
98  BOOST_CHECK_EQUAL( expected_dist, distance_between(b,a) );
99  BOOST_CHECK_EQUAL( expected_dir, a.get_relative_dir(b, mode) );
100  //Note: This is not a valid assertion. get_relative_dir has much symmetry but not radial.
101  if (mode == map_location::RADIAL_SYMMETRY) {
102  BOOST_CHECK_EQUAL( map_location::get_opposite_dir(expected_dir), b.get_relative_dir(a,mode) );
103  }
104  BOOST_CHECK_EQUAL( a.vector_sum(b), b.vector_sum(a));
105  map_location temp1 = a;
106  temp1.vector_difference_assign(b);
107  map_location temp2 = b;
108  temp2.vector_difference_assign(a);
109  BOOST_CHECK_EQUAL( temp1, temp2.vector_negation());
110  BOOST_CHECK_EQUAL( a, a.vector_negation().vector_negation());
111 
112  for (std::vector<map_location>::const_iterator it_c = it_b + 1; it_c != locs.end(); ++it_c) {
113  const map_location & c = *it_c;
114  BOOST_CHECK_EQUAL(a.vector_sum(b.vector_sum(c)) , a.vector_sum(b).vector_sum(c));
115  BOOST_CHECK_EQUAL(a.vector_sum(vector_difference(b,c)) , vector_difference(a.vector_sum(b),c));
116  BOOST_CHECK_EQUAL(vector_difference(a,b.vector_sum(c)) , vector_difference(vector_difference(a,b),c));
117  //TODO: Investigate why this doesn't work
118  if (mode == map_location::RADIAL_SYMMETRY) {
119  BOOST_CHECK_EQUAL(expected_dir, (a.vector_sum(c)).get_relative_dir(b.vector_sum(c),mode));
120  }
121  }
122 #endif
123  }
124  }
125 
126  BOOST_CHECK_MESSAGE( dir_it == dir_answers.end(), "Did not exhaust answers list.");
127  BOOST_CHECK_MESSAGE( int_it == int_answers.end(), "Did not exhaust answers list.");
128 }
129 
130 static size_t get_first (std::pair<size_t, std::string> arg) {return arg.first; }
131 static map_location::DIRECTION get_second (std::pair<size_t, std::string> arg) {return map_location::parse_direction(arg.second); }
132 
133 /* This has to be recomputed, I'm commenting out the test so that it doesn't fail in the meantime. --iceiceice
134 
135 BOOST_AUTO_TEST_CASE ( map_location_characterization_test_default_mode )
136 {
137  std::vector<std::pair<size_t, std::string> > generated_answers = boost::assign::list_of(std::make_pair(7, "se"))
138 (std::make_pair(6, "s"))
139 (std::make_pair(6, "nw"))
140 (std::make_pair(12, "n"))
141 (std::make_pair(16, "s"))
142 (std::make_pair(9, "n"))
143 (std::make_pair(7, "nw"))
144 (std::make_pair(7, "n"))
145 (std::make_pair(4, "n"))
146 (std::make_pair(5, "nw"))
147 (std::make_pair(10, "sw"))
148 (std::make_pair(13, "nw"))
149 (std::make_pair(19, "nw"))
150 (std::make_pair(9, "s"))
151 (std::make_pair(16, "n"))
152 (std::make_pair(14, "nw"))
153 (std::make_pair(14, "nw"))
154 (std::make_pair(11, "nw"))
155 (std::make_pair(12, "nw"))
156 (std::make_pair(9, "n"))
157 (std::make_pair(15, "n"))
158 (std::make_pair(13, "se"))
159 (std::make_pair(15, "n"))
160 (std::make_pair(10, "n"))
161 (std::make_pair(11, "n"))
162 (std::make_pair(8, "n"))
163 (std::make_pair(8, "n"))
164 (std::make_pair(6, "n"))
165 (std::make_pair(22, "s"))
166 (std::make_pair(6, "n"))
167 (std::make_pair(1, "nw"))
168 (std::make_pair(2, "n"))
169 (std::make_pair(2, "se"))
170 (std::make_pair(1, "s"))
171 (std::make_pair(28, "s"))
172 (std::make_pair(6, "se"))
173 (std::make_pair(5, "s"))
174 (std::make_pair(5, "se"))
175 (std::make_pair(8, "s"))
176 (std::make_pair(7, "s"))
177 (std::make_pair(25, "n"))
178 (std::make_pair(23, "n"))
179 (std::make_pair(23, "n"))
180 (std::make_pair(20, "n"))
181 (std::make_pair(21, "n"))
182 (std::make_pair(6, "sw"))
183 (std::make_pair(4, "s"))
184 (std::make_pair(7, "s"))
185 (std::make_pair(7, "s"))
186 (std::make_pair(2, "ne"))
187 (std::make_pair(3, "se"))
188 (std::make_pair(2, "s"))
189 (std::make_pair(3, "s"))
190 (std::make_pair(3, "s"))
191 (std::make_pair(1, "sw")).to_container(generated_answers);
192 
193  std::vector<size_t> ans1;
194  std::vector<map_location::DIRECTION> ans2;
195  std::transform(generated_answers.begin(), generated_answers.end(), back_inserter(ans1), &get_first);
196  std::transform(generated_answers.begin(), generated_answers.end(), back_inserter(ans2), &get_second);
197 
198  characterization_distance_direction(preset_locs, ans2, ans1, map_location::DEFAULT);
199 }*/
200 
201 BOOST_AUTO_TEST_CASE ( map_location_characterization_test_radial_mode )
202 {
203  std::vector<std::pair<size_t, std::string> > generated_answers {
204 std::make_pair(7, "se"),
205 std::make_pair(6, "sw"),
206 std::make_pair(6, "n"),
207 std::make_pair(12, "n"),
208 std::make_pair(16, "s"),
209 std::make_pair(9, "n"),
210 std::make_pair(7, "nw"),
211 std::make_pair(7, "n"),
212 std::make_pair(4, "n"),
213 std::make_pair(5, "nw"),
214 std::make_pair(10, "sw"),
215 std::make_pair(13, "nw"),
216 std::make_pair(19, "nw"),
217 std::make_pair(9, "s"),
218 std::make_pair(16, "n"),
219 std::make_pair(14, "nw"),
220 std::make_pair(14, "nw"),
221 std::make_pair(11, "nw"),
222 std::make_pair(12, "nw"),
223 std::make_pair(9, "n"),
224 std::make_pair(15, "n"),
225 std::make_pair(13, "se"),
226 std::make_pair(15, "n"),
227 std::make_pair(10, "n"),
228 std::make_pair(11, "n"),
229 std::make_pair(8, "n"),
230 std::make_pair(8, "n"),
231 std::make_pair(6, "n"),
232 std::make_pair(22, "s"),
233 std::make_pair(6, "ne"),
234 std::make_pair(1, "nw"),
235 std::make_pair(2, "ne"),
236 std::make_pair(2, "s"),
237 std::make_pair(1, "s"),
238 std::make_pair(28, "s"),
239 std::make_pair(6, "se"),
240 std::make_pair(5, "s"),
241 std::make_pair(5, "se"),
242 std::make_pair(8, "s"),
243 std::make_pair(7, "s"),
244 std::make_pair(25, "n"),
245 std::make_pair(23, "n"),
246 std::make_pair(23, "n"),
247 std::make_pair(20, "n"),
248 std::make_pair(21, "n"),
249 std::make_pair(6, "sw"),
250 std::make_pair(4, "sw"),
251 std::make_pair(7, "s"),
252 std::make_pair(7, "s"),
253 std::make_pair(2, "ne"),
254 std::make_pair(3, "se"),
255 std::make_pair(2, "s"),
256 std::make_pair(3, "s"),
257 std::make_pair(3, "s"),
258 std::make_pair(1, "nw")};
259 
260  std::vector<size_t> ans1;
261  std::vector<map_location::DIRECTION> ans2;
262  std::transform(generated_answers.begin(), generated_answers.end(), back_inserter(ans1), &get_first);
263  std::transform(generated_answers.begin(), generated_answers.end(), back_inserter(ans2), &get_second);
264 
266 }
267 
268 static std::pair<map_location , map_location> mirror_walk( std::pair<map_location,map_location> p, map_location::DIRECTION d)
269 {
270  p.first = p.first.get_direction(d);
271  p.second = p.second.get_direction(map_location::get_opposite_dir(d));
272  BOOST_CHECK_EQUAL(p.first, p.second.vector_negation());
273  return p;
274 }
275 
276 BOOST_AUTO_TEST_CASE ( reality_check_vector_negation )
277 {
278  std::pair<map_location, map_location> p(vz,vz);
279 
280  p = mirror_walk(p, n);
281  p = mirror_walk(p, n);
282  p = mirror_walk(p, ne);
283  p = mirror_walk(p, nw);
284  p = mirror_walk(p, s);
285  p = mirror_walk(p, nw);
286  p = mirror_walk(p, se);
287  p = mirror_walk(p, sw);
288  p = mirror_walk(p, n);
289  p = mirror_walk(p, n);
290  p = mirror_walk(p, sw);
291  p = mirror_walk(p, sw);
292  p = mirror_walk(p, sw);
293 }
294 
296 {
297  map_location lz(vz.get_direction(d));
298 
299  map_location temp(loc.vector_sum(lz));
300  BOOST_CHECK_EQUAL(temp, loc.get_direction(d));
301  BOOST_CHECK(tiles_adjacent(loc,temp));
302  BOOST_CHECK(tiles_adjacent(temp,loc));
303  BOOST_CHECK_EQUAL(distance_between(loc,temp), 1);
304 }
305 
306 BOOST_AUTO_TEST_CASE ( reality_check_get_direction )
307 {
308  map_location a(3,4);
309  map_location b(6,5);
310 
317 
324 }
325 
327 {
328  switch (d) {
329  case map_location::NORTH:
330  return map_location::SOUTH;
335  case map_location::SOUTH:
336  return map_location::NORTH;
342  default:
344  }
345 }
346 
347 BOOST_AUTO_TEST_CASE ( check_get_opposite_dir_refactor )
348 {
349  for (unsigned int i = 0; i < 7; i++ ) {
351  BOOST_CHECK_EQUAL ( map_location::get_opposite_dir(d), legacy_get_opposite_dir(d) );
352  }
353 }
354 
355 BOOST_AUTO_TEST_CASE ( check_rotate )
356 {
359 
362 
365 
368 
371 
374 
375 
376  for (unsigned int i = 0; i < 7; i++ ) {
378  BOOST_CHECK_EQUAL ( map_location::get_opposite_dir(d), map_location::rotate_right(d,3) );
379  BOOST_CHECK_EQUAL ( map_location::rotate_right(d,-2), map_location::rotate_right(d,4) );
380  }
381 }
382 
383 static void rotate_around_centers ( const std::vector<map_location> & locs )
384 {
385  for (std::vector<map_location>::const_iterator it_a = locs.begin(); it_a != locs.end(); ++it_a) {
386  for (std::vector<map_location>::const_iterator it_b = it_a + 1; it_b != locs.end(); ++it_b) {
387  const map_location & a = *it_a;
388  const map_location & b = *it_b;
389 
396  }
397  }
398 }
399 
400 BOOST_AUTO_TEST_CASE ( check_rotate_around_center )
401 {
402  rotate_around_centers(preset_locs);
403 }
404 
405 /**
406  * This commented block was used to visualize the output of get_relative_dir
407  * and to help derive the implementation in commit
408  * 829b74c2beaa18eda42710c364b12c987f9caed5
409  */
410 
411 /*
412 static std::string dir_to_terrain (const map_location::DIRECTION dir)
413 {
414  switch(dir) {
415  case map_location::NORTH: return "Gg";
416  case map_location::SOUTH: return "Ai";
417  case map_location::SOUTH_EAST: return "Gs^Fp";
418  case map_location::SOUTH_WEST: return "Ss";
419  case map_location::NORTH_EAST: return "Hd";
420  case map_location::NORTH_WEST: return "Md";
421  default: return "Xv";
422  }
423 }
424 
425 static std::string visualize_helper ( int x , int y, const map_location & c )
426 {
427  map_location temp(x,y);
428  return dir_to_terrain(c.get_relative_dir(temp));
429 }
430 
431 BOOST_AUTO_TEST_CASE ( visualize_get_relative_dir )
432 {
433  map_location c7(7,8), c8(8,8);
434 
435  std::cout << "***" << std::endl;
436  int x;
437  int y;
438  for (y = 0; y < 16; y++) {
439  for (x = 0; x < 15; x++) {
440  std::cout << visualize_helper(x,y,c7) << ", ";
441  }
442  std::cout << visualize_helper(x,y,c7) << std::endl;
443  }
444 
445  std::cout << "***" << std::endl;
446  for (y = 0; y < 16; y++) {
447  for (x = 0; x < 15; x++) {
448  std::cout << visualize_helper(x,y,c8) << ", ";
449  }
450  std::cout << visualize_helper(x,y,c8) << std::endl;
451  }
452 
453  std::cout << "***" << std::endl;
454 }*/
455 
456 BOOST_AUTO_TEST_SUITE_END()
static DIRECTION parse_direction(const std::string &str)
Definition: location.cpp:64
static map_location va
static map_location vs1
map_location rotate_right_around_center(const map_location &center, int k) const
Definition: location.cpp:305
#define a
static const map_location & ZERO()
Old implementation:
Definition: location.hpp:215
static map_location vt2
static void rotate_around_centers(const std::vector< map_location > &locs)
map_location & vector_difference_assign(const map_location &a)
Definition: location.hpp:244
static map_location::DIRECTION legacy_get_opposite_dir(map_location::DIRECTION d)
static std::vector< map_location > preset_locs
DIRECTION get_relative_dir(const map_location &loc, map_location::RELATIVE_DIR_MODE mode) const
Definition: location.cpp:225
#define d
static map_location vb
static map_location vector_difference(const map_location &v1, const map_location &v2)
#define b
static void characterization_distance_direction(const std::vector< map_location > &locs, const std::vector< map_location::DIRECTION > &dir_answers, const std::vector< size_t > &int_answers, map_location::RELATIVE_DIR_MODE mode)
bool tiles_adjacent(const map_location &a, const map_location &b)
Function which tells if two locations are adjacent.
Definition: location.hpp:339
static void reality_check_get_direction_helper(const map_location &loc, const map_location::DIRECTION d)
static map_location vc
size_t distance_between(const map_location &a, const map_location &b)
Function which gives the number of hexes between two tiles (i.e.
Definition: location.hpp:382
map_location vector_sum(const map_location &a) const
Definition: location.hpp:231
static map_location vt1
static DIRECTION get_opposite_dir(DIRECTION d)
Definition: location.hpp:188
static map_location vs3
static map_location::DIRECTION se
Encapsulates the map of the game.
Definition: location.hpp:40
static map_location::DIRECTION get_second(std::pair< size_t, std::string > arg)
static map_location vs2
static DIRECTION rotate_right(DIRECTION d, unsigned int k=1u)
Inlined bodies.
Definition: location.hpp:180
mock_party p
static map_location::DIRECTION s
#define i
DIRECTION
Valid directions which can be moved in our hexagonal world.
Definition: location.hpp:42
static map_location::DIRECTION sw
static map_location vs4
BOOST_GLOBAL_FIXTURE(MLFixture)
static map_location::DIRECTION nw
static size_t get_first(std::pair< size_t, std::string > arg)
map_location get_direction(DIRECTION d, unsigned int n=1u) const
Definition: location.hpp:257
map_location vector_negation() const
Inline vector ops.
Definition: location.hpp:226
static map_location::DIRECTION ne
static map_location vt3
static std::pair< map_location, map_location > mirror_walk(std::pair< map_location, map_location > p, map_location::DIRECTION d)
BOOST_AUTO_TEST_CASE(map_location_characterization_test_radial_mode)
mock_char c
static map_location::DIRECTION n
static std::string write_direction(DIRECTION dir)
Definition: location.cpp:139
static map_location vz