The previous commit's interpolation tables reproduce the historical
linear functions faithfully. This exact fit requires an awkward data
point in each of the tables for iron fertility and oil. Drop them.
No double-valued data points remain. Adjust struct resource_point
member @res to int.
This results in slightly less rural iron (33 elevations down one
point), fertility (10 elevations down one point) and oil (14
elevations down one point, 5 down two points). Only resource values
less than 100 are affected.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
The functions mapping elevation to resources are piecewise linear,
except for set_oil(), which randomly adds 1 to sea oil, and
set_gold(), which is isn't linear for mountains, but very close.
Drop the random oil bit, and replace the non-liner gold function by a
linear one. Both resources decrease at most by one point.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Land elevation is computed by first placing mountains, then elevating
land to fit.
Mountains placement is a weighted random sampling. A sector's weight
is its distance to sea capped at five and squared.
Non-mountain, non-capital sectors get assigned equidistant elevations
from 1 up to 97 rounded to integer in an order that depends on
distance to mountain and distance to sea, both capped at 5. Mountains
get equidistant elevations starting at 98 (see recent commit
"fairland: Fair mountain resources"). Capitals get 36.
Sea elevation is randomly chosen from a range that depends on the
sector's distance to land. The range increases from [-27,-1] next to
land to [-127,-1] for distance 5 and up.
Without mountains, the result is boring: elevation increases pretty
much linearly with the distance from the coast, i.e. each islands is a
single cone. With mountains, we get one cone per mountain. The sea
sea elevations are basically noise.
Worse, it's buggy: mountain placement can place fewer mountains than
requested. The weighted random sampling assigns weights even to
sectors that cannot be picked (capitals and sectors that have been
picked already). When the dice land on such a sector, it instead
picks the next one (in island growth order) that can be picked. If
there is no next one, the mountain is not placed. This is a fairness
issue.
Impact varies with fairland parameters. For 60 sector islands with 5%
mountains, around one in 10000 islands is short one mountain in my
testing. For 10 sector islands with 50% mountains, some 760 out of
10000 islands are short one sector, 80 short two, and five short
three. The numbers get worse as spikiness increases.
Undocumented misfeature: the placement loop is limited to 1000
iterations, supposedly to catch a runaway loop. Since the loop
iterates exactly once per mountain, all this accomplishes it limiting
mountains to 1000 per island.
When too few mountains are placed, the loop assigning elevations to
non-mountain, non-capital decrements elevations below 1. Since
Chainsaw 3, such elevations then get mapped to 1, plastering over the
bug. We get non-mountain sectors with elevation 1 instead of
mountains.
Rewrite as follows.
Use a simple random hill algorithm to assign raw elevations:
initialize elevation to zero, then randomly raise circular hills on
land / lower circular depressions at sea. Their size and height
depends on the distance to the coast, capped at 3. After a sufficient
number of iterations, the resulting terrain has a "natural" look.
This is elevate_prep().
elevate_land() then sorts non-capital sectors by raw elevation. The
highest become mountains. Sectors get assigned the same equidistant
elevations as before, just in raw elevation order.
elevate_sea() simply normalizes raw elevation to [-127,-1].
Elevations now show a nice undulating pattern independent of mountain
percentage.
Implementation detail: replace elev[x][y] by elev[XYOFFSET(x, y)], and
narrow the element type from int to short. Takes a fourth the space.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
elevate_land() computes the sequence of elevations 97, 97 - delta,
... in fixed point with a scaling factor of 100. Switch to
floating-point, because it's simpler. Elevations (and thus resources)
change slightly due to reduced rounding errors.
Note that we map elevations less than 1 to 1 both before and after the
patch. Odd. Turns out this mitigates a bug: mountain placement can
place fewer mountains than it should, and when that happens,
elevations go below 1 here. The next commit will fix this.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Elevations 34 and 35 are reserved for coastal mountains. When an
elevation computed for a non-mountain falls in that band, it's
adjusted to 36.
This is unnecessary since the previous commit; drop. Test output
shows the dropped elevation adjustment.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
For fairness, fairland aims to make islands of the same size consist
of the exact same sectors, just individually arranged.
It fails to achieve its aim for mountains: their elevation is random,
34 or 35 for coastal mountains, and between 98 and 254 (two dice) for
non-coastal ones. Elevation determines resources. Mountains get 89
gold on average (between 80 and 93), except for coastal mountains,
which get none. It didn't really matter until Empire 3 made mountains
produce gold dust. Since then, it's unfair.
Set mountain elevation to 98 + i * delta, where i is the mountain
number (starting at zero), delta is (127 - 98) / max_mn, and max_mn is
the maximum number of mountains an island could have. This puts the
highest mountains on the largest islands.
Non-coastal mountains have slightly less gold than before, coastal
mountains have much more.
Mountains can still be unfair, because fairland can screw up their
number. To be fixed soon.
Avoid elevations 34 and 35 for non-mountain, non-capital sectors
doesn't make sense anymore. The next commit will get rid of it.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
When an island gets placed too close to the edge of the sphere of
influence, its side facing the edge will likely be formed by the edge.
Looks unnatural, and can give a clue on the location of the other
continent.
Make place_island() prefer sectors away from the edge: instead of
picking one of the admissible sectors with equal probability, reduce
the probability as we get closer to the edge.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Planned island sizes are random with an expected value that matches
the average size requested by the user. Can be off quite a bit when
the number of islands is small. Also, actual island size can be
smaller than planned size when space is tight.
Instead of picking random island sizes independently, pick a random
split of their requested total size.
To reduce the probability of islands not growing to their planned
size, grow large islands before smaller ones.
To compensate for inability to grow, carry the difference over to the
next island size.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
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>
The previous commits changed grow_island() to create islands in
batches consisting of one island per continent, all of the same
planned size. grow_island() still places and grows one island after
the other. When an island can't grow to the actual size, the others
in the same batch are not affected. Island size can therefore differ
a lot within the same batch.
Change grow_island() to interleave the work on a batch's island: first
place them all, then add one sector to each in turn. Stop after all
reached the planned size, or one or more could not be grown further.
This is similar to how we grow continents: drift() places them all,
and grow_continent() adds one sector to each continent in turn.
Island size within the same batch can now differ at most by one
sector. The next commit will eliminate that remaining difference.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
The previous two commits put the same number of islands closest to
each continent. This one makes their planned sizes match: instead of
rolling dice separately for each island's size, we roll dice only for
the first continent's islands. The other continent's islands get the
same sizes.
Actual island sizes still differ when islands can't be grown to their
planned size. To be addressed next.
fairland-test needs a tweak to avoid loss of test coverage.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
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>
fairland places islands of random size in random places, subject to
minimum distances. Results are often less than fair, in particular
when the number of islands per continent is low: some continents have
more land nearby than others. Increasing distances between islands
doesn't help much. Deities commonly run fairland until they find the
result acceptable.
The next few commits will tackle this issue. As a first step, this
one places islands closest to continents in turn, so that each
continent is closest to the same number of islands. A continent is
closest to an island when it is closest to each of its sectors.
The number of islands must be a multiple of the number of continents
now.
Since fairland may be unable to place all islands, a continent may
still get fewer islands than it should. The next commit will address
that.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
grow_one_sector() picks a coastal start sector, then moves along the
coast trying to add an adjacent sector to the island.
It operates in spiking mode with a chance of @sp percent.
When spiking, the neighbors with sea on both sides are preferred. For
instance, when the area around the sector being considered looks like
this
- .
- - .
- .
then the neighbor in direction j is preferred, because it has sea in
directions u and n. No other neighbor is preferred.
The start sector is the first coastal sector found in a linear search
in growth order, starting at the last sector grown when spiking, or
else at a random sector. This is new_try().
grow_one_sector() tries adding a neighbor in clockwise order, starting
with a random direction. When spiking, it goes around the clock two
times, trying only preferred sectors in the first round.
When it can't add a neighbor, it moves to the next coastal sector with
next_coast().
Taken together, this randomly picks one element from the set of
pairs (S, D) where the sector in direction D off base sector S can be
added to the island. How does the probability distribution look like?
Bias: a sector's probability to be added to the island land increases
with the number of base sectors it is adjacent to. This tends to fill
in bays and lakes, which is fine.
Bias: coastal sectors following runs of non-coastal ones are more
likely to be picked as start sector. Perhaps less of an issue when
spiking, where the pick is not intended to be random.
Bias: a pair (S, D) is more likely to be picked when base sector S
follows a run of coastal sectors that aren't base sectors, or
direction D follows a a run of directions that don't permit growth.
The impact of these two biases is not obvious. I suspect they are the
reason behind the tendency of large islands to curve around obstacles
in a counterclockwise direction. This can result in multiple islands
wrapping around a central one like layers of an onion.
Bug: the move along the coast is broken. next_coast() searches for
the first adjacent sea in clockwise order, starting in direction g,
then from there clockwise for a sector belonging to the island.
Amazingly, this does move along the coast in a clockwise direction.
It can get caught in a loop, though. Consider this island:
-
- - -
-
If we start at the central sector (marked 0), the search along the
coast progresses like this:
1
- 0 2
-
It reaches the central sector again after three moves (to 1, to 2,
back to 0), and stops without having reached the two sectors on the
left.
If we start with the leftmost sector, the search loops: 0, 1, 2, 3, 1,
...
2
0 1 3
-
grow_one_sector() ensures termination by giving up after 200 moves.
Nuts!
Because of this, grow_one_sector() can fail when it shouldn't, either
because the search along the coast stops early, or goes into a loop,
or simply because there's too much coast. The latter should not
happen in common usage, where island sizes are in the tens, not the
hundreds.
Clean up this hot mess by rewriting grow_one_sector() to pick a sector
adjacent to the island with a clearly defined probability, as follows.
Use weighted random sampling to pick one sector from the set of
possible adjacent sectors.
When spiking, a sector's weight increases with number of adjacent sea
sectors. This directs the growth away from land, resulting in spikes.
When not spiking, the weight increases with the number of adjacent
land sectors. This makes the island more rounded.
To visit the adjacent sectors, grow_one_sector() iterates over the
neighbors of all island sectors, skipping neighbors that have been
visited already.
This produces comparable results for low spike percentages. The weird
onions are gone, though.
Noticeable differences emerge as the spike percentage grows. Whereas
the old one produces long snakes that tend to curve into themselves,
the new one produces shorter spikes extending from a core, a bit like
tentacles. Moreover, islands are more centered on their first sector
now. The probability for coastal capitals is lower, in particular for
moderate spike percentages.
I consider this improvements.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
A sector is admissible for island placement when land can be grown in
every sector within a certain distance.
place_island() picks a random start sector, then searches linearly for
an admissible sector. If it finds one, it places the island there.
Else, it reduces the distance by one and tries again. It fails when
none is found even for distance zero.
Trying with extra distance is obviously meant to reduce the risk of
islands from running into each other without need. Initial distance
is @di, the minimum distance between continents, which doesn't really
make sense, and is undocumented.
Bug: place_island() never tries the start sector.
Bias: placement probability is higher for sectors immediately
following inadmissible sectors. Because of that, islands are more
often placed to the right of existing islands. Players could exploit
that to guide their search for land.
Rewrite place_island() to pick sectors with equal probability,
dropping the undocumented extra distance feature. If it's missed, we
can bring it back.
The new code visits each sector once. The old code visits only one
sector in the best case, but each sector several times in the worst
case. fairland performance improves measurably for crowded setups
with large @di, else it suffers. For instance, Hvy Fever example
given in the commit before previous runs seven times faster for me.
With @di reduced to 2, its run time more than doubles. Not that it
matters.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
fairland can create fewer and smaller islands than the user requested.
Report like this:
No room for island #13
6 stunted islands
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
"fairland: unstable drift -- try increasing DRIFT_MAX" is confusing:
it looks like an error, but isn't, and increasing DRIFT_MAX requires a
recompile. I'm not sure it can happen. Replace by just "unstable
drift".
"fairland: error -- continent %c had no room to grow!" is pretty
redundant: it's always followed by "Only managed to grow %d out of %d
sectors." and then "ERROR: World not large enough to hold
continents". All it adds is which of the continents failed to grow,
and that's not actionable. Drop the message.
The message sequence "designating sectors...", "adding resources...",
"setting coastal flags...", and "writing to sectors file..." is a bit
of a lie as these four tasks aren't actually done one after the other.
Replace by just "writing to sectors file..."
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Reduce number of islands in fairland run "plain" so there's plenty of
space for them. Scarce space is still covered by run "stunted".
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Rename the existing fairland run to "plain".
New run "stunted" to cover larger minimal distances, islands
that can't fully grow, and islands that can't be placed.
New run "no-spike" to cover 0% spike.
New run "spike" to cover high spike percentage, mountains and -i.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
The map fairland shows has absolute 0,0 in the top-left corner, while
POGO's map * has it in the center. Shift fairland's map to match
POGO's.
The map shows sea as '.', island sectors as '%', capitals as '#',
mountains as '^', and other continental sectors as a letter or digit
that encodes the continent number modulo 62. When a continent has no
"other" sectors, its continent number is not shown. Remove this
pathological case by using letter/digit for capitals, and '#' for
other continental sectors.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Relations state is relatively bulky: it's a big chunk of struct
natstr, and adds 200 bytes per country to xdump nat.
Relations change rarely. Rewriting it to disk on every nation update
and retransmitting it in every xdump nat is wasteful.
To avoid this waste, move relations state to its own struct relatstr.
This is of course an xdump compatibility break. We're not maintaining
xdump compatibility in this release.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
New struct relatstr is basically empty so far. The next commit will
move relations state from struct natstr to struct relatstr.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Reject state is relatively bulky: it's a big chunk of struct natstr,
and adds almost 200 bytes per country to xdump nat.
Reject state changes rarely. Rewriting it to disk on every nation
update and retransmitting it in every xdump nat is wasteful.
To avoid this waste, move reject state to its own struct rejectstr.
This is of course an xdump compatibility break. We're not maintaining
xdump compatibility in this release.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
New struct rejectstr is basically empty so far. The next commit will
move reject state from struct natstr to struct rejectstr.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Contact state is relatively bulky: it's a big chunk of struct natstr,
and adds almost 200 bytes per country to xdump nat for deities.
Contact changes rarely. Since we avoid unnecessary updates, it
doesn't change at all unless option HIDDEN is enabled. Rewriting it
to disk on every nation update and retransmitting it in every deity
xdump nat is wasteful.
To avoid this waste, move contact state to its own struct contactstr.
This is of course an xdump compatibility break. We're not maintaining
xdump compatibility in this release.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
New struct contactstr is basically empty so far. The next commit will
move contact state from struct natstr to struct contactstr.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
A country must always be in contact of itself when option HIDDEN is
enabled. The code ensures this by establishing contact whenever a
player logs in, in init_nats(). This is not the proper place. Game
state should be initialized in empfile's oninit() callback, in this
case nat_oninit(). Do that, and drop the putcontact() from
init_nats().
Note that option LOSE_CONTACT only affects contact to other countries:
agecontact() doesn't age the country's contact to itself.
Use the opportunity to initialize contact so that getcontact() works
even when HIDDEN is disabled. Just cleanup, it isn't actually called
then.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
We maintain a few sector invariants in sct_prewrite(). Since the
update bypasses sct_prewrite(), it needs to maintain them itself. The
two should be consistent.
sct_prewrite() resets work percentage of owned sectors to 100% when
there are no civilians. The update's populace() resets it for unowned
sectors as well, if they have military.
Change sct_prewrite() to reset sct_work = 100 regardless of owner.
Also change sct_oninit() to initialize sct_work = 100, so it doesn't
change on first write. Update tests/smoke/fairland.xdump for the same
reason.
The massive test output differences are all due to sct_work.
Inconsistencies with the update remain. They will be fixed next.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
SAIL has issues:
* Sail orders are executed at the update. Crafty players can use them
to get around the update window.
* The route is fixed at command time. You can't let the update find
the best route, like it does for distribution.
* The info pages documenting it amount to almost 100 non-blank lines
formatted. They claim you can follow friendly ships. This is
wrong. They also show incorrect follow syntax. Unlikely to be the
only errors.
* Few players use it. Makes it a nice hidey-hole for bugs. Here are
two nice ones:
- If follow's second argument is negative, the code attempts to
follow an uninitialized ship. Could well be a remote hole.
- If ship #1 follows #2 follows #3 follows #2, the update goes into
an infinite loop.
* It's more than 500 lines of rather crufty code nobody wants to
touch. Thanks to a big effort in Empire 2, it shares some code with
the navigation command. It still duplicates other navigation code.
The sharing complicates fixing the bugs demonstrated by
navi-march-test.
Reviewing, fixing and testing this mess isn't worth the opportunity
cost. Remove it instead. Drop commands follow, mquota, sail and
unsail. Drop ship selectors mquota, path, follow.
struct shpstr shrinks some more, on my system from 160 to 120 bytes.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
The autonavigation feature has issues:
* Autonavigation orders are executed at the update. Crafty players
can use them to get around the update window.
* Usability is poor:
- The order command is overly complex, not least because it can do
five different things: clear, suspend, resume, declare route, set
cargo levels.
- Unlike every other command involving movement, order does not let
you specify routes, only destination sectors.
- Setting cargo levels can silently swap start and end point of a
circular route, because "this keeps the load_it() procedure
happy". Maybe it does, but it surely keeps players confused.
- Setting "start" cargo levels actually sets the "end" levels, and
vice versa. Has always been broken that way.
- Predicting what exactly autonavigation will do at the update isn't
easy.
* The info pages documenting it amount to almost 400 non-blank lines
formatted. They claim only merchant ships can be given orders.
This is wrong. Unlikely to be the only error.
* Few players use it, and its workings at the update a fairly opaque.
Makes it a nice hidey-hole for bugs. Here are two:
- Unlike the scuttle command, autonavigation happily scuttles trade
ships while they're on the trading block.
- Unlike the load command, autonavigation can load in friendly and
allied sectors.
* It's more than 700 lines of rather crufty code nobody wants to
touch. Thanks to a big effort in Empire 2, it shares code with the
navigation command. It still duplicates load code. The sharing
complicates fixing the bugs demonstrated by navi-march-test.
Reviewing, fixing and testing this mess isn't worth the opportunity
cost. Remove it instead. Drop commands order, qorder and sorder.
Drop ship selectors xstart, xend, ystart, yend, cargostart, cargoend,
amtstart, amtend, autonav.
xdump ship sheds almost half its columns. struct shpstr shrinks, on
my system from 200 to 160 bytes.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Cuts size of export files in test suite by a factor of four. Not a
big deal for disk usage, as export files compress very well, and disk
space is cheap anyway. Export files are simply easier to work with
when they aren't full of redundant crap.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
New helper run_and_cmp to automate the job: run a program capturing
its standard output, standard error and exit status, then compare the
actual with the expected results.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
TREATIES has issues:
* Treaties can cover attack, assault, paradrop, board, lboard, fire,
build (s|p|l|n) and enlist, but not bomb, launch, torpedo and
enlistment centers.
* Usability is very poor. While a treaty is in effect, every player
action that violates a treaty condition triggers a prompt like this:
This action is in contravention of treaty #0 (with Curmudgeon)
Do you wish to go ahead anyway? [yn]
If you decline, the action is not executed. If you accept, it is.
In both cases, your decision is reported in the news.
You cannot get rid of these prompts until the treaty expires.
* Virtually nobody uses them.
* Virtually unused code is buggy code. There is at least one race
condition: multifire() reads the firing sector, ship or land unit
before the treaty prompt, and writes it back after, triggering a
generation oops. Any updates made by other threads while trechk()
waits for input are wiped out, triggering a seqno mismatch oops.
* The treaty prompts could confuse smart clients that aren't prepared
for them. WinACE isn't, but is reported to work anyway at least
common usage. Ron Koenderink (the WinACE maintainer) suspects there
could be a few situations where it will fail.
This feature is not earning its keep. Remove it. Drop command
treaty, consider treaty, offer treaty, xdump treaty, reject treaties.
Output of accept changed, obviously.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
The other test output files have fixed names, and having just one with
a name that varies with the test name complicates things with no gain.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Island size is randomly chosen from the interval [1..2*is+1], with
expected value is. Use two dice to roll the size instead of one.
This makes extreme sizes much less likely.
As long as symbol_by_value(), show_capab() and togg() support only
int, flags need to fit into int.
Not a problem in practice, because no machine capable of running
Empire has int narrower than 32 bits, and 32 bits suffice.
Some flags members are long instead of int: struct lchrstr member
l_flags, struct natstr member nat_flags, struct mchrstr member m_flags
are long. Waste of space on machines with long wider than int.
Change them to int.
Rearrange struct lchrstr and struct natstr to avoid holes.
random() may yield different pseudo-random number sequences for the
same seed on another system. For instance, at least some versions of
MinGW provide a random() in -liberty that differs from traditional BSD
(see commit c8231b12). Rather inconvenient for regression testing.
MT19937 Mersenne Twister is a proven, high-quality PRNG. Actual code
is reference code provided by the inventors[*]. Quick tests show
performance comparable to random().
Like random(), MT is not cryptographically secure: observing enough of
its output permits guessing its state, and thus its future output. I
don't think players can do that.
Drop the copy of BSD random() we added for Windows.
Like the previous commit, this changes the server's die rolls, and
makes fairland create a different random map for the same seed. Update
expected smoke test results accordingly.
[*] mt19937ar.sep.tgz downloaded from
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html
"random() % n" is sound only when n is a power of two. The error is
hardly relevant in Empire, because random() yields 31 bits, and our n
are always much smaller than 2^31. Fix it anyway.
Use smallest the 2^m >= n instead of n, and discard numbers exceeding
n.
Bonus: faster for me even in the worst case n = 2^m+1.
Like the recent change to damage(), this changes some of the server's
die rolls, only this time the effect is pretty pervasive. Worse,
fairland now creates a completely different random map for the same
seed. Update expected smoke test results accordingly.