fairland: Fail when island can't be placed, for fairness

The previous commit made island distribution more fair by placing
islands close to a continent in turn.  This is still unfair when
fairland can't place all the islands.

Make grow_islands() fail when it can't place all islands, and main()
start over then, just like it does when grow_continents() fails.

Deities can no longer fill the world with islands by asking for a
impossibly high number of islands.  Tolerable loss, I think.

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:16:30 +02:00
parent 74bc8adb63
commit 18687315ac
5 changed files with 1112 additions and 1090 deletions

View file

@ -65,11 +65,14 @@
* Each continent has a "sphere of influence": the set of sectors * Each continent has a "sphere of influence": the set of sectors
* closer to it than to any other continent. Each island is entirely * closer to it than to any other continent. Each island is entirely
* in one such sphere, and each sphere contains the same number of * in one such sphere, and each sphere contains the same number of
* islands (except when island placement fails for lack of room). * islands.
* *
* Place and grow islands in spheres in turn. Place the first sector * Place and grow islands in spheres in turn. Place the first sector
* randomly, pick an island size, then grow the island to that size. * randomly, pick an island size, then grow the island to that size.
* *
* If placement fails due to lack of room, start over, just like for
* continents.
*
* Growing works as for continents, except the minimum distance for * Growing works as for continents, except the minimum distance for
* additional islands applies, and growing simply stops when there is * additional islands applies, and growing simply stops when there is
* no room. * no room.
@ -186,8 +189,11 @@ static const char *outfile = DEFAULT_OUTFILE_NAME;
#define new_x(newx) (((newx) + WORLD_X) % WORLD_X) #define new_x(newx) (((newx) + WORLD_X) % WORLD_X)
#define new_y(newy) (((newy) + WORLD_Y) % WORLD_Y) #define new_y(newy) (((newy) + WORLD_Y) % WORLD_Y)
static int ctot; /* total number of continents and islands grown */ /*
static int *isecs; /* array of how large each island is */ * Island sizes
* isecs[i] is the size of the i-th island.
*/
static int *isecs;
static int *capx, *capy; /* location of the nc capitals */ static int *capx, *capy; /* location of the nc capitals */
@ -265,7 +271,7 @@ static void set_coastal_flags(void);
static void print_vars(void); static void print_vars(void);
static void fl_move(int); static void fl_move(int);
static void grow_islands(void); static int grow_islands(void);
/* Debugging aids: */ /* Debugging aids: */
void print_own_map(void); void print_own_map(void);
@ -344,15 +350,17 @@ main(int argc, char *argv[])
qprint("unstable drift\n"); qprint("unstable drift\n");
qprint("growing continents...\n"); qprint("growing continents...\n");
done = grow_continents(); done = grow_continents();
if (!done)
continue;
qprint("growing islands:");
done = grow_islands();
} while (!done && ++try < NUMTRIES); } while (!done && ++try < NUMTRIES);
if (!done) { if (!done) {
fprintf(stderr, "%s: world not large enough to hold continents\n", fprintf(stderr, "%s: world not large enough for this much land\n",
program_name); program_name);
exit(1); exit(1);
} }
qprint("growing islands:"); qprint("elevating land...\n");
grow_islands();
qprint("\nelevating land...\n");
create_elevations(); create_elevations();
qprint("writing to sectors file...\n"); qprint("writing to sectors file...\n");
@ -1032,7 +1040,6 @@ grow_continents(void)
int done = 1; int done = 1;
int c, secs; int c, secs;
ctot = 0;
xzone_init(0); xzone_init(0);
for (c = 0; c < nc; ++c) { for (c = 0; c < nc; ++c) {
@ -1064,7 +1071,6 @@ grow_continents(void)
if (!done) if (!done)
qprint("Only managed to grow %d out of %d sectors.\n", qprint("Only managed to grow %d out of %d sectors.\n",
secs - 1, sc); secs - 1, sc);
ctot = nc;
return done; return done;
} }
@ -1100,10 +1106,11 @@ place_island(int c)
return n; return n;
} }
/* Grow all the islands /*
*/ * Grow the additional islands.
* Return 1 on success, 0 on error.
static void */
static int
grow_islands(void) grow_islands(void)
{ {
int stunted_islands = 0; int stunted_islands = 0;
@ -1113,6 +1120,8 @@ grow_islands(void)
init_spheres_of_influence(); init_spheres_of_influence();
for (c = nc; c < nc + ni; ++c) { for (c = nc; c < nc + ni; ++c) {
isecs[c] = 0;
if (!place_island(c)) { if (!place_island(c)) {
qprint("\nNo room for island #%d", c - nc + 1); qprint("\nNo room for island #%d", c - nc + 1);
break; break;
@ -1128,12 +1137,17 @@ grow_islands(void)
find_coast(c); find_coast(c);
qprint(" %d(%d)", c - nc + 1, secs); qprint(" %d(%d)", c - nc + 1, secs);
ctot++;
} }
qprint("\n");
if (c < nc + ni)
return 0;
if (stunted_islands) if (stunted_islands)
qprint("\n%d stunted island%s", qprint("%d stunted island%s\n",
stunted_islands, splur(stunted_islands)); stunted_islands, splur(stunted_islands));
return 1;
} }
/**************************************************************************** /****************************************************************************
@ -1195,7 +1209,7 @@ elevate_land(void)
int i, mountain_search, k, c, total, ns, nm, highest, where, h, newk, int i, mountain_search, k, c, total, ns, nm, highest, where, h, newk,
r, dk; r, dk;
for (c = 0; c < ctot; ++c) { for (c = 0; c < nc + ni; ++c) {
total = 0; total = 0;
ns = isecs[c]; ns = isecs[c];
nm = (pm * ns) / 100; nm = (pm * ns) / 100;

View file

@ -17,7 +17,7 @@ $empdump -x >sandbox/plain.xdump
cmp_out plain.xdump plain-newcap_script cmp_out plain.xdump plain-newcap_script
$files -f >/dev/null $files -f >/dev/null
run_and_cmp stunted $fairland -s sandbox/stunted-newcap_script -R 1 8 37 24 15 0 0 5 2 run_and_cmp stunted $fairland -s sandbox/stunted-newcap_script -R 1 8 35 16 15 0 0 5 2
$empdump -x >sandbox/stunted.xdump $empdump -x >sandbox/stunted.xdump
cmp_out stunted.xdump stunted-newcap_script cmp_out stunted.xdump stunted-newcap_script

View file

@ -1,17 +1,17 @@
add 1 1 1 p add 1 1 1 p
newcap 1 62,16 newcap 1 1,11
add 2 2 2 p add 2 2 2 p
newcap 2 5,5 newcap 2 43,7
add 3 3 3 p add 3 3 3 p
newcap 3 45,7 newcap 3 24,10
add 4 4 4 p add 4 4 4 p
newcap 4 51,27 newcap 4 3,1
add 5 5 5 p add 5 5 5 p
newcap 5 12,24 newcap 5 34,20
add 6 6 6 p add 6 6 6 p
newcap 6 22,12 newcap 6 28,0
add 7 7 7 p add 7 7 7 p
newcap 7 29,31 newcap 7 48,28
add 8 8 8 p add 8 8 8 p
newcap 8 38,18 newcap 8 4,22
add 9 visitor visitor v add 9 visitor visitor v

View file

@ -1,8 +1,8 @@
Creating a planet with: Creating a planet with:
8 continents 8 continents
continent size: 37 continent size: 35
number of islands: 24 number of islands: 16
average size of islands: 15 average size of islands: 15
spike: 0% spike: 0%
0% of land is mountain (each continent will have 0 mountains) 0% of land is mountain (each continent will have 0 mountains)
@ -15,78 +15,86 @@ World dimensions: 64x32
seed is 1 seed is 1
placing capitals... placing capitals...
growing continents... growing continents...
Only managed to grow 36 out of 37 sectors. growing islands: 1(5) 2(7) 3(2) 4(10) 5(12) 6(5) 7(5) 8(1) 9(1) 10(2) 11(7) 12(1) 13(3) 14(1)
No room for island #15
try #2 (out of 10)... try #2 (out of 10)...
placing capitals... placing capitals...
growing continents... growing continents...
Only managed to grow 32 out of 37 sectors. growing islands: 1(17) 2(6) 3(2) 4(9) 5(2) 6(2) 7(3) 8(6) 9(2) 10(1) 11(2) 12(1) 13(1)
No room for island #14
try #3 (out of 10)... try #3 (out of 10)...
placing capitals... placing capitals...
growing continents... growing continents...
Only managed to grow 30 out of 37 sectors. Only managed to grow 32 out of 35 sectors.
try #4 (out of 10)... try #4 (out of 10)...
placing capitals... placing capitals...
growing continents... growing continents...
Only managed to grow 33 out of 37 sectors. growing islands: 1(3) 2(20) 3(2) 4(12) 5(9) 6(2) 7(2) 8(4) 9(1) 10(6) 11(1) 12(1) 13(2) 14(2)
No room for island #15
try #5 (out of 10)... try #5 (out of 10)...
placing capitals... placing capitals...
growing continents... growing continents...
Only managed to grow 35 out of 37 sectors. Only managed to grow 33 out of 35 sectors.
try #6 (out of 10)... try #6 (out of 10)...
placing capitals... placing capitals...
growing continents... growing continents...
Only managed to grow 34 out of 37 sectors. Only managed to grow 33 out of 35 sectors.
try #7 (out of 10)... try #7 (out of 10)...
placing capitals... placing capitals...
growing continents... growing continents...
Only managed to grow 29 out of 37 sectors. Only managed to grow 29 out of 35 sectors.
try #8 (out of 10)... try #8 (out of 10)...
placing capitals... placing capitals...
growing continents... growing continents...
growing islands: 1(2) 2(7) 3(16) 4(11) 5(1) 6(2) 7(4) 8(2) 9(1) 10(1) 11(1) growing islands: 1(4) 2(9) 3(5) 4(8) 5(2) 6(2) 7(3) 8(7) 9(2) 10(8) 11(10) 12(2)
No room for island #12 No room for island #13
11 stunted islands
try #9 (out of 10)...
placing capitals...
growing continents...
growing islands: 1(9) 2(1) 3(2) 4(3) 5(9) 6(4) 7(2) 8(7) 9(3) 10(4) 11(2) 12(2) 13(7) 14(2) 15(1) 16(1)
16 stunted islands
elevating land... elevating land...
writing to sectors file... writing to sectors file...
. . # # # # # . . . . . . # # a a # # . . . . . % . . . . . . . . . . . . . . . . . . % % % . . . . . . . . . . . . . . . . . .
. # # # # # # # . . . . . # # # # # . . . . . . % . . . . . . . # # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. # # h h # # . . . % . . . . # # # . . . . . . . . . . . . . . # # # # # # . . % % . . . . . . . . . . . . . . . . . . . . . .
# # # # # . . . . % . . . . . # # . . . . . . . . . . . . . . . # # # # # # . . % . . % % . . # # # # # # # # . . % . . % . . #
# # # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . # e e # # # . . % . . % % . . # # # # # # # # # . . . . % . . #
# # # # . . . . . . . . . . . . . . . . . # # # # # # . . . . . # # # # # . . % % . . % % . . . # # # # # # # . . . . % % . . #
. . . # . . . . . . . . . . . . % % . . . # # # # # # . . . . . # # # # . . . % . . . . . % . . . # h h # # # . . . . . % % . .
. . . . . . . . . # # # . . . . . . . . # # # # # # . . . . . . . . # . . . . . . . . . . . . . . . # # # . . . . . . . % % . .
. . . . . . . . # # # # # . . . . . . . # # e e # # . . . . . . . . . . . . . . . . . . . . . . . . . # # . . . . . % . . . % .
. . . . . . . # # # # # # # . . % . . . # # # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % . . . . .
. . % . . . . # # # # # # # . . % . . . . # # # # . . . . . . . . . . . . . . . # # # # # . . . . . . . . . . . . . % . . . . .
. . % . . . # # # d d # # . . % % . . . . # # # . . . . . # # # . . . % . . # # # # # # . . . % % . . . . . % % . . . . . . . .
# . . % . . . . # # # # # # . . % % . . . . # . . . . . . # # # . . . % . . # # g g # # # . . . . . . . . . . . % . . . # # # #
. . . % . . . . . . # # . . . % . . . % . . . . . . . . # # # # . . . . . # # # # # # # . . . . . . . . . . . . . . . # # # # #
# # . . . . . . . . . . . . . % . . . . . . . . . . . . # # # # # . . . . . # # # # # # . . . . . # # # # # # . . . . . # # # #
# . . . . . . . . . . . . % % . . . . . . . . . . . . # # # g g # . . . . . # # # # . . . . . . # # # # # . . . . % . . # # # #
# # . . . % % % . . . . . % . . . . . . . % % . . . . # # # # # # # . . . . . . . . . . . . . . # # # # # # . . . % . . # # f f
# . . . . . . % % . . . . . . . . . # . . . % % . . . # # # # # # . . . . . . . . . . % . . . # # d d # # # . . . . . . # # # #
# . . . . . . . . % % % . . . . . # # # . . . . % . . . . . . . # . . . % . . . . . . . . . . . # # # # # # . . . . . . . . # #
. . . . . # . . . . % % . . . . # # # # # . . . % . . . . . . . . . . . . . . . . . . . . . . . # # # # # . . . % % . . . . # #
. . . . . # # # . . . % . . . . # # # # # # # . . % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . # # # # # . . % . . . # # # b b # # # . . . . . . . . . . . . . # # # # # # . . . . . . . . . . . . . . . . . . . . . .
. % . . # # # # # # . . % . . . # # # # # # # . . . . . . . . . . . . . # # # # # # . . . % % . . . . . . . . . . # . . . . . .
. . . # # # c c # . . . % . . . # # # # # # . . . . . # # . . . . . . # # b b # # . . . % . . . . . . . . . . . . # # . . . . .
. . . . . # # # # # # . . % . . . . . . . . . . . . . # # # # . . . . . # # # # # # . . . . . . . . . . . . . . . . # # . . . .
. . . . # # # # # # # . . % . . . . . . . . . . . . # # # # . . . . . . # # # # # . . . . . # # # # # # # . . . . . # # # # # .
. . . . . . . . . # # . . . . . . . . . . . % . . . # # # # # . . . . . . # # # # . . . . . # # # # # # # . . . . . # # c c # #
. . . . . . . . . # . . . . . . . . . . . . . . . # # # # # # . . . . . . . # # . . . . . # # # a a # # . . . . . # # # # # # #
. . . . . . . . . . . . . . . . . . . . . . . . . # # f f # . . . . % . . . . . . . . % . . # # # # # # # . . . . . # # # # . .
. . . . . . . . . . . . . . # # # # # # . . . . . # # # # # . . . % . . . . . . . . . % . . # # # # # # # . . . . . # # # . . .
. . . . . . . . . . . . . . # # # # # # # . . . . . # # # # . . . . . . . . % % % . . % % . . . . . . . . . . . . . # # # . . .
. . # # # # . . . . % . . # # # # # # # # . . . . . # # . . . . . . . . . . . . % . . % % . . . . . . . . . . . . . # # . . . .
A script for adding all the countries can be found in "sandbox/stunted-newcap_script". A script for adding all the countries can be found in "sandbox/stunted-newcap_script".

File diff suppressed because it is too large Load diff