*** ANTS *** by WTN (version 260518)
====================================

[Changes for the 260518 fbdos version included in-line and at the end.]

This program implements a variation of "Langton's Ant", invented in 1986
by Christopher Langton. For lots of information see the Wikipedia page at
https://en.wikipedia.org/wiki/Langton%27s_ant or search for it, numerous
research papers have been written about it and there are several websites
with interactive demos and interesting rules to try.

This is one of those things that demonstrate that life-like and sometimes
even semi-intelligent behavior can be exhibited by simple systems. Usually
cellular automata have rules which are applied to all the cells simultaneously,
such as Conway's Game of Life, but this one is different and not sure how I
missed it as I've been following the field since the early '80's. Rather than
the cells themselves being the simulated semi-living things, in this simulation
the cells are the environment and an "ant" travels through the sea of cells
interacting with and changing the cell states. The first time I saw it in
action I was slightly freaked out - the ants build stuff, especially when
they interact with the trails left by other ants or prearranged patterns.

The original version of the algorithm was run on a 2-dimensional grid of
cells, each of which can be in state 0 or state 1. If the cell underneath
the ant is a 0 then change it to a 1, rotate left and move to the next cell.
If the cell underneath the ant is a 1 then change it to a 0, rotate right
and move to the next cell. From these simple rules emerges complex behavior,
when executed on a grid with all cells state 0, for the first few thousand
moves it traces increasingly chaotic moves then after around 10,000 moves it
suddenly starts building a highway to infinity. When the algorithm is ran on
a grid of existing states besides all-zero then the results are mostly
unpredictable without actually running the algorithm but the original
ant always ends up building a highway given room to do so.

My version (like many others) extends this idea to multiple states,
multiple ants, and additional moves. Here's the opening screen which
explains what my version is about...

---------------------------------------------------------------------
*** ANTS *** (version 260518)

This program implements a version of Langton's Ant with up to 16
states, more moves and multiple ants running the same or different
rules. New rules can be run without clearing the screen so that new
ants can interact with the trails left from previous ants. The ants
can be randomly positioned, or the position and starting direction
of each ant can be specified. The behavior of the ants are specified
by a string of L, R, F, and B letters which specify how to move for
each cell state, states are incremented through all specified states.
For multiple rules separate each rule with a colon, i.e. "LR:LLR:FL".
Numbers for LR-only rules can be entered, set up below. The color shift
setting determines the colors used for states, and also determines if
previous trails are visible to a new ant - if an ant encounters a state
greater than its max state (after undoing the shift) it is treated as
an empty state. Press enter with an empty rule string for options...
History allows runs to be saved, loaded and replayed, New clears the
screen, Rerun returns here, P and D enable and disable prompting for
for position and pause conditions, C enables and adjusts the cleansing
feature which periodically decrements all states, and St.pattern goes
to a submenu for defining a starting pattern. When paused can access
History, enter a Rule to overlay previous runs, or clear the screen
and enter a New rule. If New is inadvertently selected press enter
at the rule prompt and select UnNew to replay.

Press R to change rule number mode (currently rule 235 = RRRLRLRR)
Press S to change screen size (currently set to 640 by 480)
Press any other key to start
---------------------------------------------------------------------

The program allows screen sizes of 640x480, 800x600, 1024x768 or 1280x1024
corresponding to FreeBASIC's modes 18-21. The rule number mode setting
changes how it interprets numbers entered at the rule prompt, the default
setting works with the patterns found at: https://muurahainen.art/gallery

[the fbdos version defaults to a 800x600 screen and cycles between
 640x480 and 800x600 as those are the only sizes that work with JS-DOS.]

By default the ant positions and directions are random and the simulation
continues with wrapping at the edges until manually paused. If desired it
can be set to prompt for the initial positions and directions, and whether
to pause after an ant hits a wall or to pause after a specified number of
iterations. The logic here is a bit tricky, prompts for pause on wall hit
only if all the ant positions are specified, and prompts for iteration to
pause at only if not already pausing on a wall hit. In either case continuing
locks out any further programmed pauses and wraparound is always in effect.
Random positioning or prompts can be changed at any time.

New ants running new rules can be specified without clearing the screen,
overlaying and interacting with previous runs according to the color shift
setting. The program records the starting configuration and the number of
iterations of each run, so that the history can be saved, loaded and
replayed. The replay can be stopped at any point and truncated to permit
taking the run in a different direction. Because the cell states are stored
only in the screen memory, after loading a history file it is replayed at
the highest speed possible to restore the state.

Traditionally new runs start with a blank screen with all cells in the
zero state but if desired a starting pattern consisting of points, lines
and fills can be specified using a simple drawing interface. Starting
patterns can be saved and reloaded as separate files, and are embedded
in saved history files, which always contains everything needed to
reproduce a run.


Program Operation
-----------------

After running the program it initializes a graphics screen set to
640 by 480 by default (FreeBASIC screen mode 18) and prints a description
of what the program does then shows key options for changing how numbered
rules are interpreted and for changing the screen size. Press any other
key to go to the rule prompt with an empty screen.

The program is written in QBasic-like code which dates back to the DOS
days so as a result has a few warts compared to modern programs, besides
being very DOS-like (although to me that is a desirable feature). I mostly
use FreeBASIC for compiling QBasic stuff, which is awesome but has limited
support for windowed operating systems. In particular when the user clicks
the X in the corner to close the window it is exposed to the program as the
characters null plus k and can only be detected using the INKEY$ function.
When the program is running, paused or otherwise waiting for a single
keystroke then clicking the close button displays an "Are you sure" message
to confirm, type Y or click the close button again to close the window, but
when entering rules or numeric data clicking the close button has no effect.
I could fix that by writing my own INKEY$-based INPUT equivalent but I'd
rather not, it is what it is and this isn't something that bothers me.

Note - if the program is compiled using the QB64 compiler, clicking the
close button always terminates the program whether you meant to or not.

Another side effect of writing it in QBasic is there's no limit to how
much input an INPUT operation accepts, as a result if you keep on typing
garbage it will spill over into the graphical area and mess up the display.
Don't do that unless you want to provide the ants extra food. If it happens
by accident then replay the history or use the New screen function.


Rule Entry and the rule prompt menu
-----------------------------------

At the rule prompt (new screen or not) it displays...

*** ANTS ***
String of "LRFB:" chars: 

Then waits for the user to enter a string. If the user just hits enter
it displays a rule prompt menu, which varies depending on what's available
at the time. If from a new screen with no history then it displays...

*** ANTS *** L-load R-rerun C-cleanser P-prompts S-st.pattern X-exit
Any other key to return to the rule prompt

Pressing L branches to the file load prompt, R reruns the program to change
the slowdown variable or screen resolution, C permits enabling and changing
the cleanser feature, P enables prompts for entering ant positions and
directions and specifying pause on wall hit or after a certain number of
iterations, X exits the program, any other key returns to the rule prompt.
Pressing P briefly displays "Will prompt for locations and pause conditions"
and returns to the rule prompt. If the rule prompt menu is called again
the P option will be replaced with D-dis.prompts and if selected briefly
displays "Prompting disabled, random positioning and manual pause" then
returns to the rule prompt. The S option brings up a menu with options
for (re)drawing, loading, saving, entering and clearing a starting pattern.

The cleanser feature, when enabled, periodically decrements every cell state
to help keep things interesting, otherwise most ant rules will eventually
descend into chaos. When first selected it displays...

*** ANTS *** Cleanser is currently disabled
New value: 

Enter a value above 0 to enable, this determines how many iterations to
perform between cleansing operations. The optimum value depends on how many
ants are specified and how active they are, try something between 100000 to
1000000 to get started. With the right value and ant rules the patterns can
remain balanced between structure and chaos indefinitely without intervention.
The cleanser option is only available from new runs.

If enter is pressed at the rule prompt at a new screen but with
previously recorded history then the rule prompt menu changes to...

*** ANTS *** U-unNew L-load R-rerun C-Cleanser P-prompts S-st.pattern X-exit

...adding an UnNew option, which if selected replays the history to
undo an accidental new screen. After replaying it remains at the history
prompt, from there press a non-menu key to get back to the pause screen.

If just enter is pressed at the rule prompt and history has been recorded
(after selecting R-rule from the paused menu) then the rule prompt menu
changes to...

*** ANTS *** H-hist R-rerun N-new P-prompts X-exit

...replacing the load option with H-hist which when selected jumps to
a menu where the history can be saved, loaded or replayed, and adding
a N-new option and removing the C-cleanser option, which can only be
changed when starting a new run.

Rules are specified by a string of L, R, F and B characters to specify how
the ant should rotate for each cell state - left, right, forward or back which
rotates the ant 180 degrees. For example for the rule LRFB if the ant is on
a cell with state of 0 then it changes the cell to 1, rotates left and moves to
the next cell. If cell the ant is on is state 1 then it changes it to state 2,
rotates right and moves to the next cell. If the cell is state 2 then it
changes it to state 3 and moves to the next cell without rotating, and finally
reaching the end of the rule, if the cell is state 3 then it changes it back
to state 0, turns around and moves back to the cell it was previously on.
The length of the rule must be between 2 and 16 characters, more states are
possible but QBasic only supports 16 colors so for now limiting to 16 states.

More than one rule can be specified, separate each rule with a colon.
For example enter "LR:LLR:RLL" to run ant rules LR, LLR and RLL all at the
same time. The total length of the string depends on the screen size, for a
640x480 screen the maximum is still 16 characters, for larger screens the
total string length is increased according to the formula xsize / 8 - 64.
For example a 1024x768 screen permits a rule string of up to 64 characters.
When a rule string is entered the program checks to see if it's a numerical
rule and if not, and in the case of multiple rules, makes sure it isn't too
long for the user interface and that each individual rule is between 2 and 16
characters long. If the rule isn't specified correctly then the program
briefly shows an error message and returns to the rule prompt.

[note - the fbdos version has a maximum screen size of 800x600
 so the maximum rule string length is a total of 36 characters.]

The program also accepts numbered rules between 2 and 65535 where the number
is converted to binary with leading zeros removed then converted to L and R
moves. There doesn't seem to be a standard way of doing this, different
experimenters use different methods. All involve converting the number to
binary with leading zeros removed but some assign L to 1 bits, some R to 1
bits and some reverse the order. From the initial setup screen you can select
between all four combinations. As far as I can tell numerical rules cannot
fully specify a rule because the binary equivalent must start with 1, so about
half the rules will have L and R transposed, but that usually doesn't matter
because a rule such as LLRLRLL is equivalent to RRLRLRR, just mirrored, so
always starting with an L or R does not limit the behavioral coverage.
Multiple rules cannot be specified by numbers

Next, it moves over and prompts "How many: " to enter the number of ants
running the rule at the same time. If just enter is pressed it assumes 1,
or if multiple rules specified the number of rules, and moves to the next
prompt. If the entered number is less than 1 or greater than the allowed
number of ants (200 as programmed) then it briefly prints "Try again"
and returns to the how many prompt.

Finally it prompts for "Color shift: ", if just enter is pressed then
assumes 0 for no shift, otherwise checks to make sure the number is
between 1 and 14, if invalid then prints "Try again" and reprompts,
otherwise continues to the run initialization section.

When color shift is 0 states are mapped to colors according to the
usual QBasic/FreeBASIC standard...

0    Black
1    Blue
2    Green
3    Cyan
4    Red
5    Magenta
6    Brown
7    White
8    Gray
9    Light Blue
10   Light Green
11   Light Cyan
12   Light Red
13   Light Magenta
14   Yellow
15   High-intensity White

When color shift is greater than 0 then it rotates colors 1-15 (state 0 is
always black) by the color shift value. For example if color shift is set
to 3 then state 1 becomes red, state 2 becomes magenta, etc. This works
both ways, shifting the existing ant trails to the new state values.

When an ant encounters an adjusted cell state that's greater than its
number of states it reads the cell as state 0 (empty), so the color shift
setting determines if ants with a new color shift value overlay existing
trails or interacts with them. This can be visually useful when using
the cleanser feature.


Run initialization
------------------

If prompts are disabled (the default unless enabled from the rule menu)
then all the ants are assigned random positions and directions and it
proceeds to running mode. If there is only one ant and it is starting
from a new screen then the ant will start out in the center with a
random starting direction.

If prompts are enabled then it displays...

*** ANTS ***   Ant 1    X: _
(empty X/Y/dir for random, LCR or num for X, TCB or num for Y)

The second line is a reminder of the available key codes. For each ant
specified by the previous How many prompt it prompts for X: - enter the
X coordinate, or enter L C or R for left center or right, or enter an
empty string for a random X coordinate. After entering something it prints
the actual X coordinate that will be used then moves over and prompts for
Y: - enter the Y coordinate, or T C or B for top center or bottom, or
empty for random, then it prompts for Direction:

At this point after entering L at the X: prompt and C at the Y: prompt
it looks something like...

*** ANTS ***   Ant 1    X: 258    Y: 398    Direction (URDL): _
(empty X/Y/dir for random, LCR or num for X, TCB or num for Y)

For the initial direction enter U for up, R for right, D for down or L for
left, or just enter to randomly choose a direction. After entering the
direction if there is more than one ant then prompts for Ant 2 etc looping
for all of the ants previously specified by the How many: prompt. Note that
the ants don't have to have different coordinates, it's fine to stack them
on top of each other, they'll (usually) scurry off in different directions.

After the positions and initial directions have been specified, if none
of the entries were random it clears the top line and prompts...

*** ANTS *** Pause on wall hit?

Enter Y (or y or yes whatever) to enable pause on wall hit, any other
entry or just enter disables pause on wall hit. Note that this does not
disable wrap-around, it just pauses if any of the ants hit the wall.
After continuing from the pause the ant continues to the opposite side.

If pause on wall hit was not not enabled, or if any of the ants
have random coordinates, then it prompts...

*** ANTS *** Pause at iteration number (just enter for none):

If a number is entered then when it reaches that iteration number it
automatically pauses. For either a wall hit or an iteration pause, if
the run is continued then it will no longer automatically pause.


Running and paused modes
------------------------

While running the top of the display looks something like (for example)...

*** ANTS *** (press F S for speed, any to pause)
Rule: FFRRL             Ants: 1    Color shift: 0  Iterations: 21510

...with the ant(s) running around messing with the screen.
Press S to make it go slower (halves the slowdown variable),
press F to make it go faster (doubles the slowdown variable),
or press any other key to pause.

If left running long enough (more than 2,147,483,647 iterations which
takes many hours to days depending on the speed setting) the iteration
count will wrap back to 1, if this happens an "OF" is displayed after the
count. The history can still be saved but will be saved with the current
wrapped-around iteration count and cannot fully restore the screen after
reloading (which would take too long to be practical anyway).

When paused the top changes to something like...

*** ANTS *** (paused, R-rule N-new H-hist X-exit or any)
Rule: FFRRL             Ants: 1    Color shift: 0  Iterations: 351716

Press R to enter a new rule without clearing the screen, press N for a
new screen, erasing the results of the run (if pressed by mistake press
enter at the rule prompt and press U to undo by replaying the history),
press H for the history menu, press X to exit the program (there is no
are you sure), or press any other key to continue the run.


The history menu
----------------

When history is selected from either the rule prompt menu or from
the pause menu the top line of the display changes to...

*** ANTS *** (history, S-save L-load R-replay or any)

Whatever was displayed on the second line isn't changed (yet).

Selecting Save prompts for a filename to save the history to, if just
enter is pressed it goes back to the history menu. If the entered filename
does not contain a "." character then it adds ".ant" to the end of the name
for a default extension. If doing path tricks like "../name" or saving to a
directory containing "." then add the desired extension manually. Enter
"./name" (or ".\name" for Windows) if you really want to save the file
without an extension. If the file cannot be opened for writing then it
briefly prints "Can't open save file, try again" and returns to the
filename prompt, otherwise briefly prints "Saving..." and returns to
the history menu.

Selecting Load prompts for a filename to load the history file from, if
just enter is pressed it goes back to the history menu, or the rule prompt
menu if the load command was run from there, otherwise it tries to open
the file, adding the default ".ant" extension if no extension is specified.
If the file isn't found or can't be opened then briefly prints "Can't open
save file, try again" and returns to the filename prompt.

When loading a history file it checks to make sure it's a valid history
file, however attempting to load any existing file resets the history.
After loading it replays the history at full speed to recover the
states/image when the history file was saved.

While replaying at full speed after loading, the top line shows...

*** ANTS *** (replaying history full speed, any to pause)

Selecting Replay from the menu replays the history at the normal speed
set by the slowdown variable, while replaying the top line shows... 

*** ANTS *** (replaying history, F S for speed, any to pause)

In both cases the next line shows the rule, number of ants, color shift and
the number of iterations in the history entry currently being replayed.
For normal replay press F and S to speed up or slow down the display, the
slowdown variable is restored afterwards so F and S must be repeated for
each replay.

When a replay is paused the top line changes to...

*** ANTS *** (replay paused, H to halt, any to continue)

If H is pressed then it briefly displays "History reset to this point",
does that and adjusts the iterations of the last entry to correspond to
the number of iterations performed before paused and halted and it returns
to the history menu. This can be (sort of) used as an "undo" if a bad rule
wrecks the display. Once halted any history past that point is lost,
the history playback must complete to restore the previous state.
When the replay completes it returns to the history menu.

When any other key is pressed at the history menu it jumps to the paused
menu where the run can be continued or a new rule can be entered.

[note - depending on the emulator, loading history files with the
 fbdos version can be rather slow so there isn't much distinction
 between loading and playback. Speed is increased to maximum but the
 extra full speed message is disabled and F and S keys still work.]


The starting pattern menu
-------------------------

After pressing S from the rule prompt menu with no starting pattern
currently defined it displays...

*** ANTS *** Start pattern  L-load D-draw or any

The Load option loads a pattern file, default extension is ".ptn".

The Enter option adds entries to the starting pattern, after selecting
the top display changes to...

*** ANTS *** Draw pattern... L-line F-fill P-point C-color or any
X = 319  Y = 254  C = 1

...with a small cross marking the current cursor position. Use the
cursor keys to move, to move diagonally engage the number lock and use
the number keypad. Press C to select the color, press P to plot a single
point, press L to start a line, and press F to start a fill. When drawing
lines and fills a note is displayed to indicate it's in line or fill mode,
move to the desired destination point and press L or F again. Press Esc
to cancel line or fill mode. Once at least one entry is defined the
display changes to something like...

*** ANTS *** Draw pattern... L-line F-fill P-point C-color D-del or any
X = 408  Y = 292  C = 1      Entry #1: F 319 254 408 292 1

The Del option deletes the last draw command that was entered and updates
the display. This is the only editing option available (besides Clear),
at least for now. For other pattern editing needs save the pattern to a
file and use a text editor to directly edit the pattern file.

Once a starting pattern has been defined the start pattern menu changes to...

*** ANTS *** Start pattern  R-recall C-clear S-save L-load E-enter or any

Recall re-draws the starting pattern and returns to the rule prompt, use
after New to reestablish a previously defined starting pattern.

Clear clears the screen and starting pattern and returns to the initial
start pattern menu.

Save saves the starting pattern to a separate file. The starting pattern
is also embedded into saved history files so this is only needed to use
the same starting pattern with new runs or to manually edit.

The starting pattern array is dimensioned to allow enough entries to fully
specify the entire screen using P commands (1310750, 1280*1024+30) in case
anyone wants to do that. When compiled unused string array entries do not
consume additional memory.

[well they most certainly do in DOS! The fbdos version
 has a maximum of 1000 pattern draw command entries.]


File formats
------------

Here is the format of the history file...
(<--- comments for explanation, not part of file)

ANTS HIST V1           <--- file ID, do not change
 640                   <--- screen resolution X, for info only
 480                   <--- screen resolution Y, for info only
 18                    <--- the actual screen mode
ANTS PATTERN V1        <---. 
 2                         | optional starting pattern, line 4 must be a
L 319 130 319 322 1        | pattern header or number of history entries
F 360 195 421 257 2    <---'
 2                     <--- number of history entries
LLR                    <--- entry #1 rule
 2                     <--- entry #1 number of ants
 0                     <--- entry #1 color shift value
 31664                 <--- entry #1 number of iterations to run
 242                   <--- entry #1 ant #1 X position
 460                   <--- entry #1 ant #1 Y position
 3                     <--- entry #1 ant #1 initial direction
 259                   <--- entry #1 ant #2 X position
 351                   <--- entry #1 ant #2 Y position
 0                     <--- entry #1 ant #2 initial direction
LRR                    <--- entry #2 rule
 1                     <--- entry #2 number of ants
 0                     <--- entry #2 color shift value
 103225                <--- entry #2 number of iterations to run
 374                   <--- entry #2 ant #1 X position
 197                   <--- entry #2 ant #1 X position
 0                     <--- entry #2 ant #1 initial direction

Anything past here is ignored and may be used for comments if needed.
Be careful if editing the history file, any deviations from the structure
will likely cause a failed load. For rolling back a botched run, the number
of history entries can be reduced to load only that many sections, the
remaining unloaded sections can then be removed from the file.

To allow for extensions to the history file format additional characters
are added to the header line to direct the program to load additional data.
Currently the only extension is the cleanser option which adds "C" with
the cleanser iteration setting on the next line. For example...

---------- begin cleanser6.ant ----------
ANTS HIST V1C
 300000 
 640
 480
 18
 1
LR
 5 
 5 
 3550740 
 145 
 281 
 2 
 377 
 375 
 1 
 429 
 56 
 1 
 207 
 182 
 2 
 418 
 124 
 2 
---------- end cleanser6.ant ------------

This is a cool and colorful setup, Langton's original ant (LR) has several
oscillating configurations with different periods.

Here's another saved cleanser history with multiple rules...

[modified to work with the fbdos version]

---------- begin mc4fb.ant --------------
ANTS HIST V1C
 200000 
 800
 600
 20
 1
LLRLRLL:LR:LLR:LRR:RRRLRRRRLLRRRRLL
 10 
 5 
 5886356 
 561 
 534 
 0 
 60 
 362 
 0 
 231 
 270 
 2 
 158 
 513 
 3 
 268 
 246 
 3 
 842 
 551 
 0 
 399 
 205 
 1 
 975 
 336 
 2 
 600 
 489 
 2 
 991 
 556 
 2 
---------- end mc4fb.ant ----------------

Multiple simultaneous ant rules don't change the history file format.

Here is the format of the pattern file...

ANTS PATTERN V1        <--- file ID, do not change
 3                     <--- must be equal to the number of entries
F 319 254 408 292 1    <--- fill from X=319,Y=254 to X=408,Y=292 with color 1
P 355 271 2            <--- point at X=355,Y=271 with color 2
L 315 227 442 227 3    <--- line from X=315,Y=227 to X=442,227 with color 3

The initial lines must be in this format with nothing added after each
entry line, the entry line must start at column 1 but spacing between the
elements can vary. Any invalid entry on its own line is ignored and may be
used for comments but must be counted in the count on the 2nd line since
that's what tells the program how many lines to load, the extra lines are
added to the array and will be saved when embedded in a saved history file.
Any entries in the pattern file beyond the count on line 3 will not be loaded
and may be used as needed, and will not be added to saved history files.


About the code and compiling the program to a binary
----------------------------------------------------

This program is written with old-school QBasic-style code, there is little
structure, all variables are global, and all flow control from one part of
the program to another is done using GOTO. This style produces compact code
with maximum freedom of how I want it to work with no structural baggage,
and makes it easier for me to write the code because it's how I think.
Occasionally I write structured code but usually only for big programs
or stuff where the structural advantages outweigh the drawbacks, or when
using a language that doesn't allow for my natural programming tendencies.

The program works well with the FreeBASIC and QB64 (or QB64-PE) compilers.
It is possible to run it under real QBasic but it's too slow to be practical.

As provided the ants.bas source code is configured for FreeBASIC,
to compile use the command: fbc -lang qb -exx -s gui ants.bas
The -s gui part is ignored by the Linux version of fbc but is
required for Windows to avoid opening a useless command window.

[The source code in this archive has been modified for the DOS version of
 FreeBasic - scmode is limited to 18 and 19, defaulting to 19, the values
 for slowdown& sditerthresh& maxslowdown& and maxstartentries have been
 reduced, and some lines in the history playback section have been disabled.
 Other fixes and changes too since it's looking like this is becoming the
 "dev" version for trying out stuff, see below for more details.]

To modify the ants.bas source to work with QB64 search for QB64 and follow
the instructions, basically have to uncomment a _TITLE command to set the
window title, uncomment two lines and comment one line in the setscreenmode
subroutine to use QB64-specific SCREEN commands, and uncomment numerous
RESUME lines to use QBasic-style error handling. [And undo the fbdos changes.]

FreeBASIC's help implies that it supports RESUME but in practice it
doesn't since it doesn't support the RESUME label form which is the only
kind that's useful for me. Fortunately FreeBASIC doesn't require RESUME
at all after trapping an error so they can just be commented out (at least
for this program as the target label is always the next line). However
QBasic and QB64 get very upset if an error is trapped from ON ERROR GOTO
and another ON ERROR GOTO trap is set without first running a RESUME.


FreeBASIC
---------

The FreeBASIC compiler is available from: https://FreeBASIC.net
The latest stable binary version at the time of this writing is 1.10.1
from December 2023. The github page at https://github.com/FreeBASIC/fbc
is frequently updated and up to version 1.20 but might have unexpected bugs.
Note - FreeBASIC is written in itself so you need a working FreeBASIC install
to compile the source code.

Note: When clicking the big Get FreeBASIC from the web site, don't select
the "Download Latest Version" unless you really want the ARMHF version.
Instead click on the FreeBASIC-1.10.1 directory then scroll down to
"the DOWNLOADS you are MOST LIKELY looking for..." and select the
version you need.

To install the FreeBASIC binary package for Linux into /usr/local,
extract it and from a terminal within the extracted directory run:
sudo ./install.sh -i

Usually FreeBASIC installs with no issues but I had problems getting
it to work with the pre-release of the new Ubuntu 26.04, eventually got
it going but it involved installing binaries posted by someone on the
internet, not exactly recommended but was in a virtual machine. Once
26.04 is released it whatever the issue was will likely eventually
get fixed. As usual with Linux you might need to install dependencies.

To install for Windows extract it somewhere and (unless you want to have
to copy source files to compile into this directory) add the directory to
your path or make a fbc.bat file in an available path directory (enter
PATH in a terminal for a list) containing something like...

@echo off
"C:\path_to_FreeBASIC_dir\fbc" %1 %2 %3 %4 %5 %6 %7 %8 %9

I usually compile for Windows directly on my Ubuntu Linux system using a
shell script...

#!/bin/bash
if [ -t 1 ];then
 echo "Compiling $1 ..."
 echo
 wine "$HOME/installs/FreeBASIC/fbc32.exe" -lang qb -exx -s gui "$1" 2>/dev/null
 if [ "$inxt" = "1" ];then
  echo "----- press a key -----"
  read -n 1
 fi
else
 export inxt=1
 cd $(dirname "$1")
 xterm -e "$0" "$1"
fi

...and a similar script without the -s gui for making console apps.
Adjust the path in the wine command to point to the FreeBASIC directory.
Requires xterm as written, edit for other terminal emulators.


FreeBASIC for DOS
-----------------

The DOS version of FreeBASIC requires the CWSDPMI.EXE utility, this appears
to host the latest official version: https://sandmann.dotster.com/cwsdpmi/
All programs compiled by the DOS FreeBASIC also require this file to be in
the same directory as the executable. It's GPL so a link to the source
should be all that's needed to use it.

One drawback of this utility is it requires write access to drive C: to
write its swapfile, otherwise FreeBASIC for DOS will fail and possibly also
programs compiled with it. Usually this is the case but for me somehow my
DOSBox install doesn't have a C: drive, everything points to my "MYDOS"
directory set as drive D: (to match my DosEmu/FreeDOS installation) so have
to run SUBST C: D: first before using FBC. Usually when running programs with
DOSBox it assigns the program's directory as drive C: so this is usually only
an issue when compiling. DOSBox can be tricky. DOSBox-X even more so, tried
it out on the new Ubuntu 26.04 OS (was offered as a snap), it worked but
insisted that I select a writable directory every time it was run, defaulting
to a non-writable directory tree under /usr/ - I'm sure it can be tamed with
a config file but couldn't find it. Not exactly new user friendly. On my
20.04 system (can't remember if I did it or it set itself up this way) if I
right-click an EXE there is an option to run it in DOSbox and the directory
the EXE is in mounted as drive C: - that's how stuff is supposed to work.

Not sure about more recent versions of DosEmu/FreeDOS but FreeBASIC for DOS
does not work under the dosemu installed on my Ubuntu 20.04 system.

As usual for DOS programs to avoid having to add it to the path or specify
the location of the FBC.EXE file, I added a FBC.BAT file containing...

@echo off
\fbdos\fbc.exe %1 %2 %3 %4 %5 %6 %7 %8 %9

Once working it works pretty much like other versions of FreeBASIC.


QB64 Phoenix Edition
--------------------

The QB64 "Phoenix Edition" compiler is available from:
https://www.qb64phoenix.com/ or https://github.com/QB64-Phoenix-Edition/QB64pe
The latest stable release is 4.4.0 from January 2026. At least on my Ubuntu
system the Linux version doesn't compile unless I edit the Makefile to change
"-std=gnu++20" to "-std=gnu++2a", when I tried compiling gcc suggested this
fix. Once that was done it compiled and worked, compiling the ants program
with the QB64 modifications to a 1.3 megabyte binary.

The Windows version of QB64-PE is huge, the 95 megabyte archive blows up
to a 750 megabyte directory, yikes but includes mingw-based versions of
the compilers and tools (things that are usually already installed in Linux).
I tested the 64-bit version in a Windows 10 virtual machine, had to download
and install 7-zip into Windows to extract the archive (my Ubuntu 20.04 system
couldn't extract the archive). After extracting it worked fine and required
no further installation. The ants program with the QB64 modifications
compiles to a 2.4 megabyte binary. Compiling takes a fairly long time
and I was unable to get a batch file to work for compiling outside of
the qb64pe directory.

The ANTS program works well when compiled with QB64-PE and is *much*
faster than the FreeBASIC-compiled binary, which is especially noticeable
when loading history files. QB64-PE is growing on me, its main drawbacks
are the compiler installation is huge, the binaries it makes are fairly
large, and if distributed a license file should be included with the
distribution package to cover the libraries that were embedded in the
binary, which vary depending on what features are used by the program.


The DOSANTS version of ANTS
---------------------------

Details about the DOS version have been placed in-line with the rest of the
docs in brackets, so the primary docs can remain mostly intact. The biggest
difference between ants.bas and DOSANTS.BAS is in the initial variables.

This is the initial variables from the normal ants.bas source... (from 260414)

scmode = 18  'default screen mode on startup, make 12 for QBasic
minmode = 18: maxmode = 21 'modes 18-21 are (normally) FreeBASIC-specific
slowdown& = 20000 'for slowing it down, set for a comfortable default speed
maxslowdown& = 10000000 'maximum slowdown value
sditerthresh& = 15000 'if slowdown below this limit iteration updates
iterupdatemod& = 111 'update every this iterations when limiting updates
maxants = 200: maxhist = 2000 'determines memory usage, especially maxhist
defhistext$ = ".ant" 'default history file extension
defpattext$ = ".ptn" 'default starting pattern extension
numrulemode = 3 '0=forward 1=R, 1=forward 1=L, 2=backwards 1=R 3=backwards 1=L
maxstartentries = 1310750  'max number of starting pattern entries

This is the initial variables from DOSANTS.BAS... (from 260414 fbdos)

scmode = 19  'default screen mode on startup, make 12 for QBasic
minmode = 18: maxmode = 19 'modes 18-21 are (normally) FreeBASIC-specific
slowdown& = 128 'for slowing it down, set for a comfortable default speed
maxslowdown& = 2000000 'maximum slowdown value
sditerthresh& = 32 'if slowdown below this limit iteration updates
iterupdatemod& = 111 'update every this iterations when limiting updates
maxants = 200: maxhist = 2000 'determines memory usage, especially maxhist
defhistext$ = ".ant" 'default history file extension
defpattext$ = ".ptn" 'default starting pattern extension
numrulemode = 3 '0=forward 1=R, 1=forward 1=L, 2=backwards 1=R 3=backwards 1=L
maxstartentries = 1000  'max number of starting pattern entries

The default scmode is now 19 for 800x600, maxmode has been changed to 19
since that's the largest screen size currently supported by js-dos, the
slowdown& and sditerthresh& variables have been seriously reduced to
provide normal viewing speed for a web-based emulation, and maxstartentries
has been reduced to 1000 to avoid using DMPI swap file space. When compiled
natively the stock allocation of 1310750 entries doesn't even move the needle
for PC memory usage (and at least for Linux I don't think it even counts
unless the entries are actually used), but for the DOS version caused it to
consume 8 megabytes of DMPI swap. So nobody will be writing scripts to convert
arbitrary bitmaps into pattern files for this version (and probably for the
regular version too but there the extra allocation was essentially free).

The DOS version when running under an emulator is much slower than when
running natively, this is not an issue for running old DOS games, this
program would also be slow running on old DOS hardware those old programs
were designed for. However it's all relative, compared to running under
interpreted QBasic (which is how I originally wrote the code) this version
is quite speedy, and it's actually not all that slow when running under
DOSBox on a PC, just slow when running on a javascript emulation of a DOS
emulator. Even with this it's still probably faster than what the original
researchers had available to them in the late '80's. 

The slowness is mainly an issue when loading history files, which must be
replayed entirely to recover the exact state when the history file was saved.
At maximum speed the regular FreeBASIC-compiled version does roughly 400,000
iterations per ant per second, and the QB64-compiled version is much faster
than that, so even long histories can be replayed fairly quickly. Running
flat out under native DOSBox, DOSANTS can do roughly 70,000 iterations per
ant per second. Running under DOSBox-X under JS-DOS, it can only do about
20,000 iterations per ant per second. These numbers are very approximate
but regardless the regular native versions are roughly 50 times faster.

This necessitated changes to how the program is used when running in a
relatively slow environment such as JS-DOS - the replay after loading isn't
just a necessary step for restoring the pattern, it becomes the primary
playback method. To maximize loading speed the regular version disables the
iteration count and the Fast/Slow keystrokes when replaying after a load,
it goes as fast as it can but for the DOSANTS version the only distinction
between replay after loading and replay is after loading the slowdown variable
is temporarily set to 0 to maximize the speed, the iteration count and
F and S keys remain operational.


Provided binaries
-----------------

The provided DOSANTS.EXE file was compiled from DOSANTS.BAS
using the command line: fbc -lang qb -ex dosants.bas
DOSANTS.EXE requires CWSDPMI.EXE to be in the same directory.

The provided CWSDPMI.EXE file was downloaded from:
https://sandmann.dotster.com/cwsdpmi/csdpmi7b.zip
It is GPL software, source and documentation are available
from: https://sandmann.dotster.com/cwsdpmi/

Other binaries may be included as needed to support the DOS environment,
see the README.TXT file.

All binaries are provided as-is and without any warranty whatsoever.
If there are any issues please let me know and I'll look into it,
but I can't guarantee a solution.


License
-------

From the source code...

REM ------------------------------------------------------------------------
REM The ANTS program code is Copyright 2026 Terry Newton (WTN)
REM Do whatever you want to want to do with this code provided
REM that whatever you do with this code does not prevent me or
REM anyone else from doing whatever we want to do with this code.
REM THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
REM EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
REM MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
REM IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
REM CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
REM TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
REM SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
REM ------------------------------------------------------------------------

. . . . .

Terry Newton (wtn90125@yahoo.com)




