1. What is Maezumo?
Maezumo is an open-source program that automatically generates
virus-like programs (known as warriors) for the game Corewar. This
document describes the settings for version 1.04 of Maezumo.
In Corewar these warriors battle each other in the core memory space of
a virtual computer called MARS (Memory Array Redcode Simulator) to
eliminate all opponents.
If you're not familar with Corewar go to one of the following sites for
more information:
http://koth.org
http://www.corewar.co.uk
http://www.corewar.info
The warriors are usually hand-coded, but there are also programs - like
Maezumo - available who "evolve" such warriors.
2. How does Maezumo work?
If you start Maezumo executable the following will happen:
1. A warrior will be created (details are in chapter 3)
2. The warrior battles then against the No.1 of the internal league
(known as hill). This is Phase 1 of the Benchmarking.
3. If the warrior performs good enough (according to the used settings)
it will battle the whole hill. This is the Phase 2 of the benchmarking.
4. The last placed warrior will fall off the hill
5. Maezumo startes again from 1.
This loop will run infinitely until you press "q" in the cmd window. In
case you're in progress to benchmark against the whole hill it could
take a moment until Maezumo stops.
To watch the progress in evolution simply open the index.htm.
It will be updated every time a warrior battles against the whole hill.
3. How does Maezumo generates warriors?
Maezum offers different modes to generate warriors:
Pure Evolution Mode
All instruction lines in the warrior are randomly generated. This is
similar to what most other "evolving" programs for Corewar do.
Paper Hint Mode
This hint mode will generate exclusively warriors which
self-replicates. If you don't know what this means please read the
following links for more details:
Exploring Replicators by Nenad Tomašev - Core Explorer #1
Papers by Christian Schmidt - at the Corewar Lexicon
The hint mode generates instruction lines by random selection of
precasted code fragments together with randomly generated code, as used
in the pure evolution mode. Overall a good randomness is achieved for a
high divergency of generated warriors.
Scanner Hint Mode
This hint mode will generate scanning warriors. If you don't know what
this means please read the following links for more details:
Anatomy of the Scanner - A
Basic Introduction by John Metcalf
The hint mode generates instruction lines by random selection of
precasted code fragments together with randomly generated code, as used
in the pure evolution mode. However, scanner can be quite complex, so
the divergency is still limited so far.
Stone Hint Mode
This hint mode will generate stone warriors. If you don't know what
this means please read the following links for more details:
My First Corewar Book by Steven Morrell - Chapter 2: Stones
Exploring Stones - The Basics by Nenad Tomašev - Core Explorer #2
The hint mode generates instruction lines by random selection of
precasted code fragments together with randomly generated code, as used
in the pure evolution mode.
Composite Hint Mode
This hint mode uses randomly all available precasted code fragments.
Mutation
This is not a hint mode, but if activated it will generate a separate
pool of warriors and mutate them. Sometimes it will be send back for
Phase 1 of the benchmarking. For details about Mutation see section 6.
The type of hint used to create a warrior is recorded in the warrior
comments, for example ;origin Paper 44 for a paper created at hill age
44. Warriors created randomly within the soup are labeled ;origin
Random followed by a number indicating the original soup position. This
method helps to ensure that new warriors have a unique origin string.
New warriors begin at generation 0, if the warrior mutates then the
;generation number is incremented but the origin comment remains the
same. Note that mutation can change a warrior so that it is no longer
the kind of warrior indicated by the origin.
4. How can I modify the settings to my demands?
Now, after you know how Maezumo works here is the description how you
can adjust the settings to your demands. Just open the Maezumo.ini
and change the values of the parameter.
Warrior Parameter
name :____
The name will appear in the warrior as ;name ___ followed by the number
author :____
The author will appear in the warrior as ;author ___
type :____
The type will appear in the warrior as ;redcode-___
Benchmarking and Hill Parameter
There are two kinds of benchmarking: scoring warriors against a hill
of warriors, and scoring warriors against a test set composed of
warriors of the same type to estimate the strength of the evolved
warriors.
coresize :
max. proc :
max. cycle :
max. len :
min. dist :
These should be set for the type of warriors being evolved. Typical
types are:
Type-name type coresize max. proc max. cycle max. len max. dist
-------------.------.---------.-----------.------------.----------.----------.
Standard | 94 | 8000 | 8000 | 80000 | 100 | 100 |
Tiny | tiny | 800 | 800 | 8000 | 20 | 20 |
Nano | nano | 80 | 80 | 800 | 5 | 5 |
Tourney | 94t | 8192 | 8000 | 100000 | 300 | 300 |
Limited Proc | lp | 8000 | 8 | 80000 | 200 | 200 |
Experimental | 94x | 55440 | 10000 | 500000 | 200 | 200 |
-------------'------'---------'-----------'------------'----------'----------'
Maezumo only generates '94 code, it cannot generate '88-rules code
such as used by the ICWS hill.
mars :(typically exmars or pmars)
Sets the path and name of the mars simulator. The string "mars" must
occur in the name, optionally a location such as
"D:\MyFiles\pmars-server.exe" can be specied, if the path contains
spaces the parameter must be quoted. Maezumo uses typical
pmars-compatible switches, the simulator must understand -s -c -p -r -k
-l -d -F etc.
hillsize :(typically 11 to 31)
How many warriors are used for the hill. The
last warrior is either a warrior that did not make the hill, or was
pushed off the hill.
threshold :(0 to evo rounds)
Number of wins against the first ranked warrior of the benchmarking
hill to enter phase 2
advance :(0 to +- evo rounds)
Number of wins which must achieved more than the first ranked warrior
of the benchmarking hill to enter phase 2
evo rounds :>10 (typical 250)
Number of rounds against the first ranked warrior of the benchmarking
hill (phase 1)
hill rounds:>10 (typical 250)
Number of rounds against the benchmarking hill (phase 2)
hill freeze:(0-(hillsize-1))
This parameter let freeze the top of the benchmarking hill. The value
assign the number of warriors affected. If 0 all warriors are
benchmarked. This parameter is especially useful if evolveing against a
certain set of warriors.
No of koth :(0-(hillsize-1))
Number of top warriors on the benchmarking hill which are randomly
fighting in Phase 1. If 1 then only the first ranked warrior of the
benchmarking hill is used. This parameter is especially useful if
evolveing against a certain set of warriors.
hill save :(0,1)
If this parameter is set to 1 then all warriors who make it onto the
hill will be saved in the species directory
EnableBench:(0,1)
If this parameter is set to 1 then all warriors who make the hill will
be benchmarked against a test set
BenchDir :(directory containing test warriors)
If EnableBench is set to 1 then BenchDir specifies the test set
directory used for the bench score, which is added to the warrior
comments. Warriors must have .red .war or .rc extension to be
recognized.
ShowExtra :(0,1)
If ShowExtra is set to 1 then origin, generation and bench score is
displayed in the HTML report. Only the first 3 letters of the origin is
displayed, generation and bench score are displayed only if
mutation/bench enabled.
Evolving Parameter
hint mode :(0,1,2,3,4,7,8)
Set the hint mode for the evolving:
0: pure evolution mode
1: paper mode
2: scanner mode
3: fragment mode
4: stone mode
7: ALL modes ON
8: paper and scanner mode
evo len :(5 - max. len)
Number of instructions (Warrior Length) of the evolved warrior
spl :(0-5000)
mov :(0-5000)
add :(0-5000)
sne :(0-5000)
seq :(0-5000)
probabilities for linear opcodes (0-5000)
djn :(0-5000)
jmn :(0-5000)
jmz :(0-5000)
jmp :(0-5000)
probabilities for looping opcodes (0-5000)
hint-pur :(0-5000)
hint-pap :(0-5000)
hint-sca :(0-5000)
hint-fra :(0-5000)
hint-sto :(0-5000)
Probabilities for different hints when using hint mode 7
Mutation Parameter
Mutation :(0,1)
Set Mutation to 1 to enable, 0 to disable
Topology :(0 to soupsize-1)
Set Topology to 0 for grid-shaped soup, >0 selects ring and
specifies maximum distance between warriors selected to battle each
other during parallel evolution.
SoupSize :(>5 or >topology whichever is bigger)
Size of the hidden soup for mutation
SoupX :(0 to soupsize/2)
Width of the soup when using grid topology, if 0 specified then selects
a square soup (as close as possible). SoupSize should be a multiple of
SoupX (or square of an integer) for a "normal" grid.
SoupDisplay:(0,1,2,3,4,5)
Set to 0 for no soup display in the report, or set to 1
for text cells, 2 for narrow blocks, 3 for wide blocks or 4 for hex
symbols. Browser support may vary. The soup display is colored so the
main color represents the instruction sequences with other redcode
elements changing the shade of the color. Soup display mode 5 selects a
custom display string, specified by the SDcustom setting.
SW Display :(0,1)
Set to 1 to display the code of randomly selected soup warriors along
with its display color (if soup display enabled)
SaveSoup :(0,1,2)
Save soup behavior.
0: load soup from species dir, don't save
1: load soup from soup dir, save to soup dir
2: load soup from species dir, save to soup dir
MutByProb :(0,1)
Set MutByProb to 1 to use probability settings above. Set to 0 to
mutate from array using hard-coded opcodes and weighting
dat :(0-5000)
Additional probability setting for dat instructions
MutSelect :(0-1)
This parameter sets how often mutation is selected rather than a hint,
from 0 to 1 (0 effectively disables mutation, 1 always mutates if a
soup warrior is available, typical value is 0.5 to 0.8)
EnableSeed :(0,1)
Set EnableSeed to 1 to copy warriors that make the hill to the soup.
Set to 0 to disable seeding so that parallel evolution is not
influenced by the hill or hint-made warriors. Useful for evolving
without using the pure hints, select the pure hint mode and set
MutSelect to 1, a few pure hints will make the hill at first but if the
parameters are good the "Random" soup warriors should take over.
MinChanges :(typical 1)
Minimum number of changes when mutating to avoid duplicate warriors
MutRate :(typical 1)
Master mutation rate, all rates are multiplied by this
SoupIter :(typical range 3 to 25)
Number of soup battles/mutations for each hill cycle. Smaller is
faster, larger produces more mutation within the soup. Set to 0 to
disable parallel soup evolution
SoupRounds :(typical range 20 to 200)
Number of rounds used for soup battles, smaller is faster, larger for
more accurate battles (not always good)
InstrRate :(0-1) (typical 0.01)
Chance of instruction change per line
AddrRate :(0-1) (typical 0.03)
Chance of address mode change per item
DataRate :(0-1) (typical 0.05)
Chance of data value change per item
SwapRate :(0-1) (typical 0.01)
Chance of swapping two lines of redcode, per line
InsertRate :(0-1) (typical 0.01)
Chance of inserting a new line, per line
DeleteRate :(0-1) (typical 0.01)
Chance of deleting the current line, per line
DupLine :(0-1) (typical 0.2)
Chance of duplicating the previous line when inserting a new line
IncDec :(0-1) (typical 0.5)
Chance of increment or decrement (instead of random) when changing data
BigNum :(0-1) (typical 0.5)
Chance of a big number (instead of small number within the warrior
size) when randomly changing data.
5. How can I re-initialize Maezumo for a new evolution?
Actually to re-initialize Maezumo you have to do the following:
- empty the "species" and "soup" folders
- set the value in the age.ini and evo.ini to 1 (also works to delete
the files to start at age 0)
- delete the content in the warrior.ini (or delete the file)
- change the parameter for your new evolutionary run in the Maezumo.ini
This can be automated using a batch file, say "re-initialize.bat" (be
careful not to run by accident!):
@del soup\*.red
@del species\*.red
@del age.ini
@del evo.ini
@del warrior.ini
6. How does Mutation work in Maezumo?
Mutation is a process where random changes are made to the code of
warriors in the hopes of making them better. For parallel evolution,
two "nearby" soup warriors are selected for battle, and the warrior
that wins is copied over the warrior that loses while making occasional
random changes. Sometimes no change at all is made, sometimes many
changes are made at once. The soup is arranged as a ring of warrior
positions, warriors selected for battle are from 1 to 4 positions
apart. If a selected position is empty, a random warrior is created.
This causes different parts of the soup to develop areas of different
strategies which can develop semi-independently of other areas,
although eventually strong warriors spread throughout the soup. The
ring "topology" with the limited range slows the spread of strong
warriors to provide a better chance for other strategies to develop
elsewhere in the soup. Another popular topology is the grid where
warriors battle one of 8 neighboring warriors. The grid topology tend
to work best with a large soup (and is more "visual" when used with an
evolver with a soup display), the ring topology provide better control
of spread when using a smaller soup but the "islands" of similar
strategies can only battle other strategies on one of two "sides" so
the warriors are not exposed to as many different strategies unless the
form spreads elsewhere. It would be relatively easy to add support for
a grid-shaped soup to Maezumo, but practically the two approaches
perform roughly the same so the simpler method was chosen.
Maezumo uses a hill and hint-generated warriors, and can make use of
mutation even if parallel evolution is disabled. Each time a warrior
makes the hill, if it is copied to a random location within the
soup
without change, and at each hill cycle, there is a chance (set by the
MutSelect parameter) that it will select a random soup warrior and
mutate that (instead of using a hint) to create the warrior used for
the Phase 1 test. If a soup warrior does not exist, or the minimum
number of changes (set by the MinChanges parameter) were not made (to
avoid duplicate warriors), then it uses the originally selected hint.
This simple method permits combining brute-force hint-based evolution
using an evaluation hill with traditional Darwin-style evolution.
Several kinds of changes can happen when a warrior is mutated,
controlled by the mutation rates and other settings described in
section 4. The individual rates are described by a number from 0 to 1,
if InstrRate is set to say .03 then each instruction in the warrior has
a 3-in-100 chance of being changed to a different instruction. Some
control over the selected instructions can be performed by setting
MutByProb to 1 then setting the instruction probabilities as desired -
these settings also affect code generation by the pure "hint". When
MutByProb is 0 then the program uses a hard-coded table of opcodes and
(sometimes) modifiers, selected to generate more MOV and SPL
instructions than others. The hard-coded address mode table selects "$"
modes more often. Expert evolvers may wish to modify the source code to
alter the default tables but if doing that the first 16 instructions
and first 8 address modes must not be changed, the hints and
probability settings depend on these remaining the same. It is possible
to add INI file support for changing the "extra" instructions and
modes, however this was not done in the present version to avoid
unnecessary complexity. One factor that must be considered if altering
the tables - if changed then previously-created warriors that use
instructions removed from the table won't be correctly loaded back into
the soup, so the instruction tables aren't something that should be
easily changed. Try to use the probability settings if a different
instruction mix is desired.
Some of the mutation settings are used only if other kinds of changes
take place. The IncDec setting is used when a data (field) value is
changed, and determines if a +/- 1 change is done instead of choosing a
new random value. If a random value is chosen, then the BigNum setting
determines if it is a big number from 0 to coresize-1, or a small
number +/- warrior size. The DupLine setting is used when a line is
inserted to determine the chance of it being a duplicate of the
previous line, this can help build up blocks of SPL and MOV
instructions but if set too high it can be distracting, making the line
look like a mistake.
7. How can I make stronger "Pure" warriors?
By choosing evolving parameters that favor the survival of strong
warriors, however that is easier said than done. Pure evolution is a
very random process, the same parameters produce different results with
each run so it can be very difficult to find the right settings.
Purely-evolved warriors for larger coresizes can be interesting but
rarely can compete with hand-coded warriors except in some environments
that are "friendly" to evolved warriors. However it is possible to
evolve nano warriors that are stronger than hand-coded warriors. The
top few slots of the SAL nano hill are usually occupied by evolved
warriors. Don't expect it to be easy - evolving strong nano warriors
often requires many tries and experimenting with the settings, and it
may take many runs to determine if a particular INI file is "good".
Sometimes it only works well only once.
The "pure" hint can help or hinder depending on what it does. Sometimes
it seeds the soup with a good form that does well both in the soup and
on benchmark tests, other times the pure hint produces a warrior that
beats the soup warriors but does not score well. The MutSelect setting
can be used to determine how much of an effect the pure hint warriors
have, lower values (typically 0.5) should seed the soup with warriors
of Pure origin, to encourage warriors of Random origin set MutSelect to
1. The SoupIter setting also has an effect, higher values make it more
likely for a Random warrior to take hold in the early stages of
evolution, and performs more parallel evolution per cycle for less
interference from the hill (and also requires better mutation settings
since the hill won't be driving the scores up as much). To totally
disable the effect of the hints on the soup set EnableSeed to 0. Set
MinChanges
to 0 to keep the pure hint from running
should the warrior not mutate, this produces more duplicate warriors
but it might add stronger warriors to the hill by not changing the soup
warriors and weakening an already strong form.
Experiment with different topologies. Usually the ring soup with
Topology set to 4 does fine, but experiment with the number which
determines how rapidly warrior forms spread through the soup. The grid
topology may offer slightly better performance because warriors are
exposed to a greater variety of other strategies and might provide
greater diversity. The main advantage of the grid topology is it
permits visually observing the soup to determine if mutation rates are
too low or too high. Identical colors are usually duplicate warriors,
similar colors are usually mutations of the same instruction sequence.
For best results "islands" of similar warriors should appear, if not
the mutation rate is probably too high. Some duplicates in the soup
usually is a good thing, but if a single color takes over completely
the mutation rate is probably too low.
If a strong form (such as SPL MOV MOV MOV DJN or MOV SPL MOV MOV DJN)
does not appear within a few hundred cycles, consider starting over, or
archive the run and come back to it later. If an inferior form takes
over the soup it makes it unlikely for a stronger form to arise because
new sequences usually start out weak. This is sometimes called finding
a "local maximum". Making the soup larger may help, but typically a
single popular form will take over anyway. The trick is to get a strong
form to mostly take over but still show diversity within itself. Note
that if using the soup display often the same sequence of base
instructions will be colored completely different because different
instruction modifiers are used, observe the code that makes the hill
and how well it scores.
Sometimes the warrior that beats the king of the hill isn't the best
warrior to try, or a very strong warrior might not be able to beat the
top warrior. Setting no. of koth to 3 might work better than the normal
value of 1 (this can sometimes help hint-driven evolution too).
Once strong warriors arise, test them against multiple benchmarks.
Warriors that do well on the nano hill should score high on the
NanoBM07 benchmark, and also score high against the top 20 nano
warriors from Koenigstuhl. A good nano warrior that can place near the
top of the hill should get a score of around 150 on both benchmark
tests.
8. How can I find strong warriors?
When EnableBench is set to 1, Maezumo adds a benchmark score to each
warrior that makes the hill and is saved to the species directory.
Warriors with high bench scores don't necessarily stay on the hill. The
following "findtop.bas" program searches through the species directory
and reports the best warrior found:
100 REM Find top-scoring Maezumo warrior in the species dir
110 REM (warriors must have ;benchscore comment)
112 REM by WTN 7/15/09
120 usewin=1 'set to 0 for Linux, 1 for Windows
130 targetdir$="species"
140 outfile$="" 'optional output file (useful if thresh < 1)
150 thresh=1 'lists warriors within this of top score
160 topscore=0:top$=""
170 if usewin then dc$="dir /b /on ":ps$="\" else dc$="ls -1 ":ps$="/"
180 shell dc$+targetdir$+ps$+"*.red > findtop.dl"
190 open "findtop.dl" for input as #1
200 if outfile$<>"" then open outfile$ for output as #3
210 while not eof(1)
220 line input #1,wn$:if usewin then wn$=targetdir$+ps$+wn$
230 open wn$ for input as #2
240 b$="0"
250 while not eof(2)
260 line input #2,a$
270 if left$(a$,12)=";benchscore " then b$=mid$(a$,13,6)
280 wend
290 close #2
300 score=val(b$):if score < topscore*thresh then goto 340
310 if score > topscore then topscore=score:top$=wn$
320 print "Warrior ";wn$;" scores ";str$(score)
330 if outfile$<>"" then print #3,"Warrior ";wn$;" scores ";str$(score)
340 wend
350 close #1:kill "findtop.dl"
360 if thresh >= 1 then goto 390
370 print "Top score warrior is ";top$;" score=";topscore
380 if outfile$<>"" then print #3,"Top score warrior is ";top$;" score=";topscore
390 if outfile$<>"" then close #3
400 system
To also list warriors that rate near the top score set thresh=0.97 or
so - sometimes the slightly lower-scoring varients will score better on
other benchmark tests. This might list a lot of warriors, run on a
terminal with scrolling ability or set outfile$="topscore.txt" to write
the results to a topscore.txt file.
It might also be a good idea to check the soup directory for strong
warriors. Soup warriors don't have benchmark scores written to them so
a benchmark program would have to be used. This can take a long time
but might find strong warriors that were not able to make the hill. The
following "benchsoup.bas" program might be useful:
100 REM Benchmark a directory of warriors against a benchmark set
102 REM by WTN 7/15/09
110 REM ---------------------------------------------------------------
120 usewin=1 'set to 1 for Windows, 0 for Linux
130 soupdir$="soup" 'set to directory containing warriors to test
140 testdir$="NanoBM07" 'set to directory containing test set
150 testmask$="*.RED" 'set to match test warriors
160 report$="souprep.txt" 'set to name of file to write bench report to
170 rounds=500 'number of rounds
180 sim$="exmars -b -k -s 80 -p 80 -c 800 -l 5 -d 5 -F 40" 'sim comline
190 REM ---------------------------------------------------------------
200 sim$=sim$+" -r "+str$(rounds)+" ":print "Press Esc to stop"
210 if usewin then dc$="dir /b /on ":ps$="\" else dc$="ls -1 ":ps$="/"
220 shell dc$+soupdir$+ps$+"*.red > souplist.tmp"
230 shell dc$+testdir$+ps$+testmask$+" > testlist.tmp"
240 open report$ for output as #1:topscore=0:top$=""
250 open "souplist.tmp" for input as #2
260 while not eof(2) and inkey$<>chr$(27)
270 score=0:n=0
280 line input #2,war$:if usewin then war$=soupdir$+ps$+war$
290 open "testlist.tmp" for input as #3
300 while not eof(3)
310 line input #3,opp$:if usewin then opp$=testdir$+ps$+opp$
320 shell sim$+war$+" "+opp$+" >scores.tmp"
330 open "scores.tmp" for input as #4
340 line input #4,a$:close #4
350 z=instr(a$," "):w=val(left$(a$,z)):t=val(mid$(a$,z))
360 score=score+w*3+t:n=n+1
370 wend
380 close #3
390 score=(score/n)*(100/rounds)
400 if score>topscore then topscore=score:top$=war$
410 sc$=mid$(str$(-1*(1000+score+.00001))+" ",3,6)
420 print sc$;" ";war$
430 print #1,sc$;" ";war$
440 wend
450 close #1:close #2
460 kill "souplist.tmp":kill "testlist.tmp":kill "scores.tmp"
470 print "Top score = ";str$(topscore);" by ";top$
480 system
Edit lines 130 to 180 to set up the benchmark, sim$ must be correctly
set for the core size etc, usually -F is coresize/2. Smaller core sizes
require a bigger rounds number for accuracy, 500 to 1000 for nano, 200
to 500 for tiny, 100 to 300 for standard. Exmars is shown but if
desired pmars can be used instead. For nano versions 0.9.2+ have a
"permutate" option which increases accuracy with fewer rounds, instead
of -F 40 specify -P and specify 142 for rounds. Like this...
170 rounds=142 'number of rounds
180 sim$="pmars -b -k -s 80 -p 80 -c 800 -l 5 -d 5 -P" 'sim comline
The bench program lists the top-scoring warrior for convenience, but
this might not be the "best" warrior, if strong warriors are found for
best results sort the output file (souprep.txt unless changed). For
both Windows and Linux the command sort souprep.txt should list the
strongest warriors at the end of the list. Note that the soup is
usually full of duplicates, warriors with the same score are likely
identical copies.
These programs are designed to run under the Blassic interpreter but they should
also run under QBasic etc. If desired they can be compiled using
FreeBasic using the option -lang qb but compiling makes it more
difficult to change the settings by editing the BASIC code.
[variations of these programs are in the tools directory]