cc: fix get_distance, and add unit tests

This commit is contained in:
Crypto City 2019-11-08 21:16:20 +00:00
parent 1d765e5689
commit b2ce755525
2 changed files with 73 additions and 7 deletions

View File

@ -50,13 +50,31 @@ namespace cc
static inline uint32_t get_distance(uint32_t ax0, uint32_t ay0, uint32_t ax1, uint32_t ay1, uint32_t bx0, uint32_t by0, uint32_t bx1, uint32_t by1)
{
const uint32_t x0 = std::max(ax1, bx1);
const uint32_t x1 = std::min(ax0, bx0);
const uint32_t y0 = std::max(ay1, by1);
const uint32_t y1 = std::min(ay0, by0);
if (x0 >= x1 || y0 >= y1)
return 0;
return std::min(x1-x0, y1-y0);
const unsigned int left = ax1 < bx0;
const unsigned int right = ax0 > bx1;
const unsigned int top = ay1 < by0;
const unsigned int bottom = ay0 > by1;
if (left)
{
if (top)
return std::max(bx0 - ax1, by0 - ay1);
if (bottom)
return std::max(bx0 - ax1, ay0 - by1);
return bx0 - ax1;
}
if (right)
{
if (top)
return std::max(ax0 - bx1, by0 - ay1);
if (bottom)
return std::max(ax0 - bx1, ay0 - by1);
return ax0 - bx1;
}
if (top)
return by0 - ay1;
if (bottom)
return ay0 - by1;
return 0;
}
static inline uint32_t intersection_squares(uint32_t ax0, uint32_t ay0, uint32_t ax1, uint32_t ay1, uint32_t bx0, uint32_t by0, uint32_t bx1, uint32_t by1)

View File

@ -2131,6 +2131,54 @@ TEST(cc, staff)
ASSERT_GE(cc::get_staff(buildings + 1), cc::get_staff(buildings));
}
TEST(cc, distance)
{
/* 0 1 2 3 4
* 0 x x x x x
* 1 x x x x x
* 2 x x x x x
* 3 x x x x x
* 4 x x x x x
*/
ASSERT_EQ(2, cc::get_distance(0, 0, 1, 1, 3, 3, 4, 4));
ASSERT_EQ(2, cc::get_distance(3, 3, 4, 4, 0, 0, 1, 1));
ASSERT_EQ(0, cc::get_distance(0, 0, 4, 4, 1, 1, 3, 3));
ASSERT_EQ(0, cc::get_distance(1, 1, 3, 3, 0, 0, 4, 4));
ASSERT_EQ(1, cc::get_distance(0, 0, 1, 1, 2, 2, 4, 4)); // top left
ASSERT_EQ(1, cc::get_distance(1, 0, 3, 1, 1, 2, 3, 4)); // top
ASSERT_EQ(1, cc::get_distance(3, 0, 4, 1, 0, 2, 2, 4)); // top right
ASSERT_EQ(1, cc::get_distance(0, 1, 1, 3, 2, 1, 4, 3)); // left
ASSERT_EQ(1, cc::get_distance(3, 1, 4, 3, 0, 1, 2, 3)); // right
ASSERT_EQ(1, cc::get_distance(0, 3, 1, 4, 2, 0, 4, 2)); // bottom left
ASSERT_EQ(1, cc::get_distance(1, 3, 3, 4, 1, 0, 3, 2)); // bottom
ASSERT_EQ(1, cc::get_distance(3, 3, 4, 4, 0, 0, 2, 2)); // bottom right
ASSERT_EQ(0, cc::get_distance(0, 0, 2, 2, 2, 2, 4, 4)); // top left
ASSERT_EQ(0, cc::get_distance(1, 0, 3, 2, 1, 2, 3, 4)); // top
ASSERT_EQ(0, cc::get_distance(2, 0, 4, 2, 0, 2, 2, 4)); // top right
ASSERT_EQ(0, cc::get_distance(0, 1, 2, 3, 2, 1, 4, 3)); // left
ASSERT_EQ(0, cc::get_distance(2, 1, 4, 3, 0, 1, 2, 3)); // right
ASSERT_EQ(0, cc::get_distance(0, 2, 2, 2, 2, 0, 4, 2)); // bottom left
ASSERT_EQ(0, cc::get_distance(1, 2, 3, 4, 1, 0, 3, 2)); // bottom
ASSERT_EQ(0, cc::get_distance(2, 2, 4, 4, 0, 0, 2, 2)); // bottom right
}
TEST(cc, distance_percentage)
{
ASSERT_EQ(0, cc::get_distance_percentage(0, 1));
ASSERT_EQ(0, cc::get_distance_percentage(0, 1000));
ASSERT_EQ(100, cc::get_distance_percentage(1, 1));
ASSERT_EQ(100, cc::get_distance_percentage(1000, 1000));
ASSERT_EQ(200, cc::get_distance_percentage(2000, 1000));
ASSERT_EQ(50, cc::get_distance_percentage(500, 1000, 50));
ASSERT_EQ(100, cc::get_distance_percentage(500, 1000, 100));
ASSERT_EQ(220, cc::get_distance_percentage(2200, 1000));
ASSERT_EQ(221, cc::get_distance_percentage(2201, 1000));
ASSERT_EQ(221, cc::get_distance_percentage(2209, 1000));
ASSERT_EQ(221, cc::get_distance_percentage(2210, 1000));
}
TEST(cc_influence, monotonic)
{
static const uint8_t potential[] = {0, 80, 105, 180, 255};