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>
With -o, fairland doesn't add resources. This is pretty redundant;
the deity can unset resources with "edit l * i 0 g 0 f 0 c 0 u 0".
Drop the option.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
With -a, fairland makes the capital sector an airfield to "mark the
continents [...] so that you can tell them from the islands". This is
pretty redundant since commit afc0ef94e "Make fairland record the
island number in the deity territory", v4.3.31. Drop it.
The map fairland prints is not affected. The continents are clearly
visible there.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Set the application name to "Empire" to support Empire-specific
customization of readline. Use in .inputrc looks like this:
$if Empire
set bell-style audible
set history-size 500
else
set bell-style visible
$endif
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Make -H take an argument. Default it to ~/.empire_history, except in
-r restricted mode, where history is off unless you specify -H.
That's because restricted mode restricts the player's access to the
local system, and that includes the history file. If you want to
grant access to a history file, you have to do so explicitly.
Thanks to the previous commit, there is no need to suppress saving to
~/.empire_history in the test suite.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Document readline in more detail in man/empire.6.
Make @history_file local to main().
main() silently truncates the home directory name to 1000 characters
when constructing the history file name; mark FIXME.
Set @rl_already_prompted just once.
Write history file on unsuccessful exit, too.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Readline provides fancy command line editing such as <Arrow Up> for
previous commands and CTRL+A to jump to the beginning of the line.
This patch does not add any completion on <tab> key, a TODO, if you
will.
A new command line flag, -H, turns on saving the history to disk.
This may have security implications on shared computers, as all
commands are saved as-is. Thus "change re 1234" would be logged
directly to the file.
Signed-off-by: Martin Haukeli <martin.haukeli@gmail.com>
Rebase on top of preparatory work, fix a few bugs, and tidy up:
* Update the standalone client build, too.
* Fix the Windows build.
* Keep command line options sorted case-insensitively.
* Error out when $HOME is unset and getpwuid() fails, just like we do
for $LOGNAME.
* Give @input_from_rl, @has_rl_input static linkage.
* @has_rl_input is a flag, not a counter, set and test it accordingly.
* Save all input in history, not just commands. Martin's attempt to
recognize commands works only as long as the server sends prompts
faster than the user sends input. Drop that part, and update commit
message accordingly.
* Fix recv_input() not to truncate value of strlen() to int, and to
use memmove() for updating @input_from_rl in place.
* Clean up whitespace in a few places.
* Tweak commit message.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Redirections and the execute command let the user read and write files
and run programs on the local system.
Restricted mode prevents such access. This is useful when you want to
grant somebody access to just Empire, but not to the host system's
user account that runs the client.
Signed-off-by: Marisa Giancarla <fstltna@me.com>
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>
Also end URIs with '/' where appropriate.
Refrain from touching scripts/ and Stephen Crane's LWP authorship
note.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Why upgrade? I'm not a lawyer, but here's my take on the differences
to version 2:
* Software patents: better protection against abuse of patents to
prevent users from exercising the rights under the GPL. I doubt
we'll get hit with a patent suit, but it's a good move just on
general principles.
* License compatibility: compatible with more free licenses, i.e. can
"steal" more free software for use in Empire. I don't expect to steal
much, but it's nice to have the option.
* Definition of "source code": modernization of some details for today's
networked world, to make it easier to distribute the software. Not
really relevant to us now, as we normally distribute full source code.
* Tivoization: this is about putting GPL-licensed software in hardware,
then make the hardware refuse to run modified software. "Neat" trick
to effectively deny its users their rights under the GPL. Abuse was
"pioneered" by TiVo (popular digital video recorders). GPLv3 forbids
it. Unlikely to become a problem for us.
* Internationalization: more careful wording, to harden the license
outside the US. The lawyers tell us it better be done that way.
* License violations: friendlier way to deal with license violations.
This has come out of past experience enforcing the GPL.
* Additional permissions: Probably not relevant to us.
Also include myself in the list of principal authors.
Old version recognizes the first ':', which prevents use of ':' in
host names. They are used in numerical IPv6 addresses. New version
recognizes the last ':', which prevents use of ':' in service names.
Old version treats empty host or port specially (use default).
Documentation suggests ':' is required, but the code doesn't do that.
Instead, the argument is interpreted as host, even when it's empty.
New version makes the HOST: part optional. You can't specify host and
default the port. Tough. Keeps documentation and code as simple as
possible.
Compare:
old version new version
argument host port host port
"" "" default default ""
"A" "A" default default "A"
":" default default "" ""
"A:" "A" default "A" ""
":B" default "B" "" "B"
"A:B" "A" "B" "A" "B"
Three options: abort, crash-dump, nothing. crash-dump works by
aborting a fork. It isn't implemented for Windows.
The oops action is no longer tied to daemon mode, but -d still implies
-E abort for convenience.
empdump exports and imports game state as plain text. Limitations: it
currently can't export player bmaps, power report, telegrams,
announcements, message of the day, no-login message and log files.
Exported floating-point values may be inexact. Importing an exported
game state may not result in identical data files; besides the loss of
floating-point precision just mentioned, coordinates are normalized,
and characters beyond a string's terminating zero in a character array
are lost. Bug: importing resets timestamps to zero. It should set
them to the current time.
Commit 530deef2 failed to update .TH of fairland(6), files(6) and
pconfig(6).
Commit 530deef2 failed to update .TH of empire(6).
Commit eeb9d3cb created empsched(6) with the wrong .TH.
a seed for the random function.
(nightlybuild.sh): Add the -R 1 for the server.
(nightlybuild.sh): Switch to -R 1 for the fairland as 1 is safer.
Some systems might generate lousy randomness from a
zero seed.
(prng.patch): Not required anymore, -R 1 is used instead.
(main, emp_server.6): Rename -r and -R to -u and -U. "-R" is now used for random seed.
(schedulefil): New.
(set_dirs, set_paths): Rename. Initialize schedulfil.
(read_schedule): New. Can read several updates, which will be used in
later changesets.
(update_time): Change to array. Will be used in later changesets.
(update_schedule_anchor): New.
(update_init): Initialize it.
(update_get_schedule): New.
(update_init): Call it to initialize update_time[].
(update_sched): Rewrite.
(update_forced, update_wanted): Replace.
(update_reschedule): New.
(main): Call it on SIGHUP to reload the schedule.
(update_trigger, update_force, force, player_coms): Drop force's
capability to schedule updates in the future, because it's not worth
the trouble to implement again. Deities can simply edit the schedule
file to schedule updates. Remove update_force() and
update_trigger()'s parameter.
(upda): Update for new scheduler. Take care to keep output the same
as far as possible, even though it's ugly, to avoid breaking clients.
(update_policy, adj_update, update_times, hourslop, blitz_time):
econfig keys removed.
(update_demand, UPD_DEMAND_NONE, UPD_DEMAND_SCHED, UPD_DEMAND_ASYNC)
(update_demandpolicy, UDP_NORMAL, UDP_TIMES, UDP_NORMAL, UDP_BLITZ)
(UDP_MAX, UDP_DEFAULT, UDDEM_TMCHECK, UDDEM_COMSET, UDDEM_DISABLE)
(UDDEM_MAX, UDDEM_DEFAULT): econfig key and values replaced. Users
changed. wantupd.h is now empty, remove.
(demand_check): External linkage.
(update_policy_check): Now pointless, remove.
(is_daytime_near, min_to_next_daytime, regular_update_time)
(scheduled_update_time, next_scheduled_time, updatetime)
(next_update_time, next_update_check_time): Unused, Remove.
(demand_check, demandupdatecheck): Move call of demand_update_time()
from demand_check(), which controls all demand updates, to
demandupdatecheck(), which controls only unscheduled ones. Fixes
update command not to lie about the next scheduled demand update.
(demandupdatecheck): Check updates_disabled() so that zdone no longer
claims to trigger an update when it can't.
(login): New parameter utf8. If set, request option utf-8 from
server.
(expect, recvline): Split recvline() out of expect(). Replace or
remove some unhelpful diagnostics.
(eight_bit_clean): New.
(screen): If eight_bit_clean is set, highlighting is switched with
SO/SI. Else characters with MSB set are highlighted.
(main): New option -u to request UTF-8 and set eight_bit_clean.
unclear. Other programs only support -e. Remove -D.
(install_service): Remove argument datadir_set.
(main): New option -v.
(main): Exit successfully after -h.
(main): Don't print usage on unknown options, just point to -h.
(print_usage): Rewrite. Deprecate use of non-option arguments.