Map Location: reimplement rotate_right as rotate_direction

Since rotate_right_around_center rotates a location, this makes it clear we're getting a rotated direction instead. Also made it constexpr
This commit is contained in:
Charles Dang 2024-10-10 15:54:28 -04:00
parent f04e19934f
commit c815e1d23a
3 changed files with 31 additions and 25 deletions

View file

@ -116,9 +116,9 @@ map_location::direction map_location::parse_direction(const std::string& str)
if (end != std::string::npos) {
const std::string rel_dir = str.substr(end + 1);
if (rel_dir == "cw") {
dir = rotate_right(dir, 1);
dir = rotate_direction(dir, 1);
} else if (rel_dir == "ccw") {
dir = rotate_right(dir, -1);
dir = rotate_direction(dir, -1);
} else {
return direction::indeterminate;
}

View file

@ -56,19 +56,25 @@ struct map_location {
static std::vector<direction> all_directions();
static direction rotate_right(direction d, unsigned int k = 1u)
/** Returns the direction one would face having taken @a steps clockwise around an undefined center. */
static constexpr direction rotate_direction(direction d, int steps = 1)
{
return d == direction::indeterminate ? direction::indeterminate : direction{(static_cast<int>(d) + (k % 6u)) % 6u};
if(d == direction::indeterminate) {
return direction::indeterminate;
}
// Compensate for weirdness with the C++ % operator.
// The plain formula (d + (steps % 6)) % 6 works for almost every case, but it returns incorrect
// results for a counterclockwise rotation on direction::north. Instead, for any negative steps,
// cancel out the sign and scale by the highest possible direction value (viz., 5). This has the
// effect of a clockwise rotation ending at the same value as the specified counter-clockwise op.
int adjusted_steps = steps >= 0 ? steps : steps * -5;
return direction{(static_cast<int>(d) + (adjusted_steps % 6)) % 6};
}
static direction rotate_right(direction d, signed int k)
static constexpr direction get_opposite_direction(direction d)
{
return (k>=0) ? rotate_right(d, static_cast<unsigned int> (k)) : rotate_right(d, (static_cast<unsigned int>(-k) % 6u) * 5u);
}
static direction get_opposite_direction(direction d)
{
return rotate_right(d,3u);
return rotate_direction(d, 3);
}
static direction parse_direction(const std::string& str);

View file

@ -353,29 +353,29 @@ BOOST_AUTO_TEST_CASE ( check_get_opposite_dir_refactor )
BOOST_AUTO_TEST_CASE ( check_rotate )
{
BOOST_CHECK_EQUAL ( map_location::rotate_right(map_location::direction::north) , map_location::direction::north_east );
BOOST_CHECK_EQUAL ( map_location::rotate_right(map_location::direction::north_east,-1) , map_location::direction::north);
static_assert(map_location::rotate_direction(map_location::direction::north) == map_location::direction::north_east);
static_assert(map_location::rotate_direction(map_location::direction::north_east, -1) == map_location::direction::north);
BOOST_CHECK_EQUAL ( map_location::rotate_right(map_location::direction::north_east) , map_location::direction::south_east );
BOOST_CHECK_EQUAL ( map_location::rotate_right(map_location::direction::south_east,-1) , map_location::direction::north_east );
static_assert(map_location::rotate_direction(map_location::direction::north_east) == map_location::direction::south_east);
static_assert(map_location::rotate_direction(map_location::direction::south_east, -1) == map_location::direction::north_east);
BOOST_CHECK_EQUAL ( map_location::rotate_right(map_location::direction::south_east) , map_location::direction::south );
BOOST_CHECK_EQUAL ( map_location::rotate_right(map_location::direction::south, -1) , map_location::direction::south_east );
static_assert(map_location::rotate_direction(map_location::direction::south_east) == map_location::direction::south);
static_assert(map_location::rotate_direction(map_location::direction::south, -1) == map_location::direction::south_east);
BOOST_CHECK_EQUAL ( map_location::rotate_right(map_location::direction::south), map_location::direction::south_west);
BOOST_CHECK_EQUAL ( map_location::rotate_right(map_location::direction::south_west,-1) , map_location::direction::south );
static_assert(map_location::rotate_direction(map_location::direction::south) == map_location::direction::south_west);
static_assert(map_location::rotate_direction(map_location::direction::south_west, -1) == map_location::direction::south);
BOOST_CHECK_EQUAL ( map_location::rotate_right(map_location::direction::south_west), map_location::direction::north_west);
BOOST_CHECK_EQUAL ( map_location::rotate_right(map_location::direction::north_west,-1) , map_location::direction::south_west );
static_assert(map_location::rotate_direction(map_location::direction::south_west) == map_location::direction::north_west);
static_assert(map_location::rotate_direction(map_location::direction::north_west, -1) == map_location::direction::south_west);
BOOST_CHECK_EQUAL ( map_location::rotate_right(map_location::direction::north_west), map_location::direction::north);
BOOST_CHECK_EQUAL ( map_location::rotate_right(map_location::direction::north,-1) , map_location::direction::north_west );
static_assert(map_location::rotate_direction(map_location::direction::north_west) == map_location::direction::north);
static_assert(map_location::rotate_direction(map_location::direction::north, -1) == map_location::direction::north_west);
for (unsigned int i = 0; i < 7; i++ ) {
map_location::direction d = static_cast<map_location::direction> (i);
BOOST_CHECK_EQUAL ( map_location::get_opposite_direction(d), map_location::rotate_right(d,3) );
BOOST_CHECK_EQUAL ( map_location::rotate_right(d,-2), map_location::rotate_right(d,4) );
BOOST_CHECK_EQUAL ( map_location::get_opposite_direction(d), map_location::rotate_direction(d,3) );
BOOST_CHECK_EQUAL ( map_location::rotate_direction(d,-2), map_location::rotate_direction(d,4) );
}
}