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