fairland: Make actual island sizes fair

The previous commit reduced the difference in island size within the
same batch of islands to at most one.  Eliminate the remaining
difference by shrinking the bigger islands by one sector.

This invalidates the precomputed exclusive zones, so recompute them.

fairland-test needs a tweak to avoid loss of test coverage.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
This commit is contained in:
Markus Armbruster 2020-08-11 16:41:20 +02:00
parent 212c7ddcef
commit 08ca6ace12
7 changed files with 1749 additions and 1743 deletions

View file

@ -65,7 +65,7 @@
* Each continent has a "sphere of influence": the set of sectors
* closer to it than to any other continent. Each island is entirely
* in one such sphere, and each sphere contains the same number of
* islands.
* islands with the same sizes.
*
* Pick an island size, and place one island's first sector into each
* sphere, randomly. Then add one sector to each island in turn,
@ -944,15 +944,17 @@ can_grow_at(int c, int x, int y)
static void
adj_land_update(int x, int y)
{
int is_land = own[x][y] != -1;
int dir, nx, ny, noff;
assert(own[x][y] != -1);
for (dir = DIR_FIRST; dir <= DIR_LAST; dir++) {
nx = new_x(x + diroff[dir][0]);
ny = new_y(y + diroff[dir][1]);
noff = XYOFFSET(nx, ny);
adj_land[noff] |= 1u << DIR_BACK(dir);
if (is_land)
adj_land[noff] |= 1u << DIR_BACK(dir);
else
adj_land[noff] &= ~(1u << DIR_BACK(dir));
}
}
@ -1117,13 +1119,17 @@ grow_islands(void)
{
int n = ni / nc;
int stunted_islands = 0;
int i, j, c, done, secs, isiz;
int xzone_valid = 0;
int i, j, c, done, secs, isiz, x, y;
xzone_init(nc);
init_spheres_of_influence();
for (i = 0; i < n; i++) {
c = nc + i * nc;
if (!xzone_valid)
xzone_init(c);
isiz = roll(is) + roll0(is);
for (j = 0; j < nc; j++) {
@ -1142,6 +1148,21 @@ grow_islands(void)
}
}
if (!done) {
secs--;
for (j = 0; j < nc; j++) {
if (isecs[c + j] != secs) {
isecs[c + j]--;
assert(isecs[c + j] == secs);
x = sectx[c + j][secs];
y = secty[c + j][secs];
own[x][y] = -1;
adj_land_update(x, y);
}
}
xzone_valid = 0;
}
for (j = 0; j < nc; j++)
stunted_islands += isecs[c + j] != isiz;