Corewar Scripts for Linux

For a long time (since the mid '90's) I've been using various QBasic and batch programs to benchmark redcode warriors (such as this and these), even after moving to GNU/Linux I continued to use my old tools under DosEmu/FreeDos. They still work. But it's a hassle to install DosEmu just to hang on to ancient technology so I've been slowly rewriting the tools to work natively under Linux. An early step was this multiple-warrior benchmark program from 2009 which uses Blassic to interpret code that resembles old-style BASIC - my preferred language when I simply want to get something done without spending a lot of time on the programming aspect (I don't care that much about "proper" programming languages which almost invariably harder to use, I simply want to make a program that does what I want it to do). Recently (December 2011 while testing the upcoming Ubuntu 12.04 OS) I rewrote the code to permit testing single warriors with performance bars showing the performance against the individual benchmark warriors, modified the multiple-warrior version so that it takes the benchmark set as a command line parameter so as to not require as many variations, and wrapped them up with various bash scripts for running in an xterm window along with a script for running the tools from the Nautilus file manager. The Blassic programs and scripts permit the corewar experimenter to "run" one or more warriors in pmarsv, benchmark a single warrior, and benchmark an entire directory of warriors, with variations for common core sizes and benchmark sets. The variations still tend to be copies with minor changes but I find this easier to use than to have a master program which I have to take extra steps to navigate, when I need a new variation I just copy one of the existing programs/wrapper scripts and make a few edits.

Here is the cwscripts.tar.gz package (last modified December 17, 2011), includes blassic programs, scripts and benchmark sets for testing warriors for coresize 80, 800 and 8000. Requires Blassic and pmars/pmarsv binaries. Blassic needs to be compiled from source to use the later 0.10 or 0.11 versions - install libncurses5-dev, extract somewhere, do ./configure then make then copy the blassic binary to the /usr/local/bin directory (you need to be root to do this - in this document I'm not going to explain how to do basic stuff like copying files as root, anyone experimenting with corewars under Linux should already know how to use their OS). The pmars binaries are compiled for 32 bit but the N2 versions should run as-is on most 64-bit Linux systems (if not ldd pmarsv and install the missing dependencies, or recompile the code from source), copy pmars92N2 and pmarsv92N2 to /usr/local/bin and rename to pmars and pmarsv. These versions of pmars/pmarsv have been slightly modified to avoid interpreting some continuation lines as comments and distorting the bench score using the Wilkies test set. The CWtools menu script requires zenity, which is usually installed in most Gnome systems but if not install it to use the menu. See the documentation in the cwscripts package for installing and using the preconfigured scripts, the remainder of this document will describe the programs in more generic terms.

The idea is to provide a set of tools that can be used from the command line, via right-click file association, and via a menu that is implemented as a nautilus script. Under all GNU/Linux systems I've tried, selecting multiple files and running an associated program launches separate instances of the program, not useful, Nautilus on the other hand passes all of the selected files on the same command line to a nautilus script so provides an easy GUI way to run multiple redcode warriors in the same core (which is the main point of the game). If Nautilus isn't available then the only obvious way to battle multiple warriors (or do anything requiring passing multiple filenames) is by dropping to a command line. The CWtools script in ~/.gnome2/nautilus-scripts provides access to all the tools via menus (different menus depending on how many parms are passed, including none to test all warriors in a directory), but if desired individual wrapper scripts can be copied to nautilus-scripts for direct access of the various tools without having to go through a menu.

A few notes about the Blassic language - Blassic ignores a line that starts with # on the first line so the programs can be made executable and #!/usr/local/bin/blassic tells the OS to use the blassic interpreter to run them. Blassic is actually a line-numbered language but if line numbers are omitted they are automatically added internally. GOTO can specify a line number or a label specified by a label keyword (as in "label done:"). Most of the constructs from GWBASIC and old 8-bit BASIC's are available and work mostly as expected. Only single-line IF/THEN/ELSE is supported, block branches have to be done with GOTO or some other construct. There isn't any error handling, the programmer has to write the code to handle all expected conditions or be OK with the program simply closing files and terminating if an error occurs. Under Linux, if reading lines from a file with dos line ends, the [cr] will be present in the string so the program needs to reject that if it matters. Blassic is also available for Windows so it's possible to write cross-compatible tools by changing the path separator, helper commands, etc - these programs theoretically should work under Windows by changing usewin=0 to usewin=1 but not tested, and of course the bash wrapper scripts would have to be recoded in batch/cmd language. Blassic is primitive, but it excels at doing primitive things and some not-as-trivial things including evolving redcode warriors (for examples JB and SEWAX).

About Linux file associations - Nautilus scripts provides a way to avoid associations but for many things that involve a single file I prefer to right-click the file and select an "open with" option. Unfortunately modern OS's (newer versions of Windows and Linux) make this much harder to do than it should be, taking away not only the ability to simply associate a particular extension, but with Gnome 3 also removing the ability to associate to arbitrary scripts and binaries (only officially installed apps can be associated). Making a new file type for *.red files is important because otherwise the corewar tools will appear in the open-with menus of all text files, KDE still has a GUI way to make new file types but for other environments to create a custom file type install a "mime editor" such as Assogiate and create a new "text/redcode" type, give it *.red for the file mask, and add text/plain as a parent type so that the normal editor and other text associations will still appear without having to reassociate them. To associate file types to arbitrary scripts or binaries, install Thunar or PCmanFM which still support opening a file with whatever you want.. after making the redcode type, navigate somewhere with .red files, right-click properties and add the needed associations with the opens-with dialog. When done reset the default back to a text editor.

Running warriors in pmarsv

The first thing needed for playing with corewar is being able to visually run the warrior in a simulated core. The pmarsv program does this but has a rather complex command line to specify the core size, warrior spacing, simulation speed and other parameters. So hide the complexity with a few scripts specific to each common core size. Normally these and all other user command line programs should be placed in the /usr/local/bin directory to avoid having to specify the path when using. If you want to avoid having to be root to edit and copy files then the files can be placed in a local directory and your PATH variable modified to include the directory, but that's another story, it's usually easier to just gksudo nautilus and navigate to /usr/local/bin. Bash scripts need to be made executable to use (usually right-click then properties), and usually need to be in unix line-end format - if copying scripts from a text file that's in "dos" format (most of my text files are so that Windows users can read them) then convert to unix format using a utility such as flip (i.e. flip -u filename).

The pmv80 script...

#!/bin/bash
pmarsv -l 5 -d 5 -s 80 -p 80 -c 800 -v 644 -fn fixed $*

The pmv800 script...

#!/bin/bash
pmarsv -l 20 -d 20 -s 800 -p 800 -c 8000 -v 444 -fn fixed $*

The pmv8000 script...

#!/bin/bash
pmarsv -l 200 -d 200 -s 8000 -p 8000 -c 80000 -v 314 -fn fixed $*

These scripts permit running one or more warriors at the command line in common core sizes without having to specify all the switches, for example to run blee.red and blah.red in coresize 800 enter "pmv800 blee.red blah.red" (without the quotes). Note - pmarsv can't handle filenames containing spaces, which generally is a bad idea anyway as it makes it harder to separate parameters.

Pmarsv doesn't respond to keypresses unless it is run from a terminal, and a terminal is needed to be able to see the battle results, so for general GUI use via association or a graphical menu the core pmv* scripts are run using additional scripts that run the core scripts in a terminal, xterm is common and already installed or available for every GNU/Linux distro I've used.

Here's a pmv80x script for running pmv80 in xterm...

#!/bin/bash
function doit {
shift
pmv80 $*
echo "--- press any key ---"
read -n 1 nothing
}
if [ "$1" == "doit" ];then
doit $*
else
xterm -e "$0 doit $*"
fi

The pmv800x and pmv8000x scripts are the same other than changing pmv80 to pmv800 and pmv8000. To use another terminal emulator change xterm to gnome-terminal, konsole, etc. With the wrapper scripts the user can now associate *.red files to pmv80x and the other variations and run single warriors by right-clicking and selecting the appropriate script. With the Nautilus file manager you can copy the wrapper to the ~/.gnome2/nautilus-scripts directory to run multiple warriors in the core at the same time, but eventually that can result in a lot of scripts for all the different variations of running and benchmarking so on down I'll present a menu script to consolidate everything.

Benchmarking a single warrior

Before submitting a warrior to a competition hill it's useful to have an idea about how the warrior will perform, benchmark sets provide a group of warriors for rating the strength of other warriors. Common benchmark sets include nanoBM07 for coresize 80 warriors, tinyFranz and tinyBM04 for coresize 800 warriors, and 94nopWilkies and 94nopWilfiz for coresize 8000 warriors. For nano warriors I also use nanob2 which is composed of the top 20 Koenigstuhl nano warriors from June 2009, and nanoht2 which I assembled in 2010 for estimating the performance of a warrior on the SAL nano hill. So that my benchmark programs can know where to find the benchmark sets I made a cw directory in /usr/local/share and copied my benchmark sets to directories under /usr/local/share/cw - but the benchmarks can be anywhere convenient so long as the benchmark programs are edited to know where to find them.

Here is a Blassic program that benchmarks a single warrior using a specific benchmark set...

#!/usr/local/bin/blassic
testdir$="/usr/local/share/cw/nanoht2"
sim$="pmars -b -k -P -s 80 -p 80 -c 800 -l 5 -d 5"
rounds=142 'match -r parm or 142 for nano -P
usewin=0 '0 for linux 1 for windows
war$=PROGRAMARG$(1)
if war$="" then print "No warrior specified":end
print "Testing ";war$;"..."
if usewin then dc$="dir /b /on ":ps$="\" else dc$="ls -1 ":ps$="/"
shell dc$+testdir$+ps$+"*.red >__test__.tmp"
open "__test__.tmp" for input as #1
score=0:n=0
while not eof(1)
line input #1,opp$
open opp$ for input as #2
if usewin then opp$=testdir$+ps$+opp$
while not eof(2)
line input #2,a$
z=instr(a$,chr$(13)):if z then a$=left$(a$,z-1)
if left$(a$,6)=";name " then name$=mid$(a$,7)
wend:close #2
shell sim$+" "+war$+" "+opp$+" >_scores_.tmp"
open "_scores_.tmp" for input as #2
line input #2,a$:close #2
z=instr(a$," "):w=val(left$(a$,z)):t=val(mid$(a$,z))
result=(w*3+t)*(100/rounds)
print left$(name$,24);
print tab(27);left$(str$(result),6);
print tab(36);w;
print tab(42);t;
print tab(48);
i=1:while (i<(result/10))
print "*";:i=i+1
wend:print
score=score+w*3+t:n=n+1
wend:close #1
score=(score/n)*(100/rounds)
print "Score = ";left$(str$(score),6)
kill "_scores_.tmp"
kill "__test__.tmp"
end

This particular program is hard-coded for coresize 80 warriors using the nanoht2 benchmark set, so I named it "cwb_nanoht2", the file needs to be made executable to permit running directly, as in program args instead of having to run blassic progname args.

The first few lines are changed to make copies for other benchmark sets and core sizes. For coresize 800...

#!/usr/local/bin/blassic
testdir$="/usr/local/share/cw/tinyBM04"
sim$="pmars -b -k -f -r 1000 -s 800 -p 800 -c 8000 -l 20 -d 20"
rounds=1000 'match -r parm or 142 for nano -P

For coresize 8000...

#!/usr/local/bin/blassic
testdir$="/usr/local/share/cw/94nopWilkies"
sim$="pmars -b -k -f -r 200 -s 8000 -p 8000 -c 80000 -l 200 -d 200"
rounds=200 'match -r parm or 142 for nano -P

...with variations for the different benchmark sets within each core size. The testdir$ line specifies the benchmark directory, the sim$ line specifies the pmars command line that is used for the tests, and the rounds line is the number of rounds specified for the -r parameter, or 142 rounds for fast nano battles using the -P parameter (which for nano, battles the warriors in all 142 possible starting configurations). For the variations I commonly use I ended up with cwb_nanoht2, cwb_nanob2, cwb_nanoBM07, cwb_tinyFranz, cwb_tinyBM04, cwb_94nopWilkies and cwb_94nopWilfiz.

With these program variations warriors can be tested from the command line and produce output like...

terry@terry-desktop:~/MyStuff/CWwork/wtnwars work/80$ cwb_nanoht2 TransferFunction.red
Testing TransferFunction.red...
02_08.red 165.49 76 7 ****************
0535.red 156.33 71 9 ***************
Another MEVO Thing 164.08 73 14 ****************
Cosmic Uncertainity 202.11 94 5 ********************
Creamed Corn 180.98 84 5 ******************
Crimson Climber 143.66 66 6 **************
Dodecadence 158.45 66 27 ***************
eerie glow 135.91 51 40 *************
e6843-5724-xt430-4-nano- 121.83 40 53 ************
Fragor Calx 141.54 64 9 **************
Frothering Foam 114.08 40 42 ***********
Furry Critter 151.40 70 5 ***************
girl from the underworld 142.25 66 4 **************
hemlock 138.02 51 43 *************
Hot Soup 157.74 73 5 ***************
JB268 176.05 79 13 *****************
Left Alone 178.16 82 7 *****************
Man&Machine 164.08 75 8 ****************
medusa's mirror 159.85 74 5 ***************
Military Grade Nano 128.87 59 6 ************
a slice of moonbeam pie 173.94 79 10 *****************
Muddy Mouse (RBv1.6r1.1. 166.19 76 8 ****************
NanoWorms 147.88 62 24 **************
Obsidian peasoup 173.23 79 9 *****************
Pacler Deux 125.35 45 43 ************
Red Moon 164.08 75 8 ****************
Little Red Rat 187.32 85 11 ******************
ripples in space-time 128.16 52 26 ************
Science Abuse 129.57 59 7 ************
Shutting Down Evolver No 138.73 63 8 *************
Sleepy Lepus 154.22 60 39 ***************
rdrc: Snapback Sprite 188.02 88 3 ******************
the spiders crept 123.23 46 37 ************
Steaming Pebbles 172.53 79 8 *****************
Stegodon Aurorae 171.12 75 18 *****************
Transfer Function 146.47 66 10 **************
White Moon 176.05 82 4 *****************
wrath of the machines 188.02 88 3 ******************
Score = 156.18
terry@terry-desktop:~/MyStuff/CWwork/wtnwars work/80$

The first field is parsed from the test warrior's ;name line, the 2nd field is the normalized score against that warrior, the 3rd and 4th fields show the number of wins and ties against the test warrior, followed by a bar with one * character for every 10 points. Corewar battles award three points for each win and one point for each tie, with the result normalized to a standard 0-300 scale by multiplying the score by 100/rounds. The last line of the report shows the average score of all of the battles, which indicates overall strength.

A bash wrapper permits running a benchmark program in an xterm window via association or a GUI menu...

#!/bin/bash
function doit {
cwb_nanoht2 "$1"
echo "--- press any key ---"
read -n 1 nothing
}
if [ "$1" == "doit" ]; then
doit "$2"
else
xterm -e $0 doit "$1"
fi

...this was named cwbx_nanoht2, with other variations to run the other benchmark programs.

Benchmarking multiple warriors

Often it is useful to benchmark several warriors in a single run to determine which ones are the strongest against a particular benchmark set, especially when evolving warriors. Here's a blassic program that benchmarks all warriors in the current directory against a specified benchmark set and leaves behind a sorted report in the same directory...

#!/usr/local/bin/blassic
sim$="pmars -b -k -P -s 80 -p 80 -c 800 -l 5 -d 5"
rounds=142 'match -r parm or 142 for nano -P
reportbase$="bench80_"
benchbase$="/usr/local/share/cw/"
usewin=0
benchset$=PROGRAMARG$(1)
if benchset$="" then print "no bench set specified":end
report$=reportbase$+benchset$+".txt"
testdir$=benchbase$+benchset$
if usewin then dc$="dir /b /on ":ps$="\" else dc$="ls -1 ":ps$="/"
shell dc$+testdir$+ps$+"*.red > testlist.tmp"
open "testlist.tmp" for input as #1
a$="File not"
if not eof(1) then line input #1,a$
close #1:bencherror=0
if left$(a$,8)="File not" or left$(a$,4)="ls: " then bencherror=1
if bencherror then kill "testlist.tmp":print "bench not found":end
shell dc$+"*.red > souplist.tmp"
open "souplist.tmp" for input as #1
a$="File not"
if not eof(1) then line input #1,a$
close #1:bencherror=0
if left$(a$,8)="File not" or left$(a$,4)="ls: " then bencherror=1
if bencherror then kill "testlist.tmp":kill "souplist.tmp"
if bencherror then print "no warriors to benchmark":end
open "benchrep.out" for output as #1:topscore=0:top$=""
open "souplist.tmp" for input as #2
print "Benchmarking using ";benchset$;" test set... (Esc to stop)"
while not eof(2) and inkey$<>chr$(27)
score=0:n=0
line input #2,war$:if usewin then war$=soupdir$+ps$+war$
open "testlist.tmp" for input as #3
while not eof(3)
line input #3,opp$:if usewin then opp$=testdir$+ps$+opp$
shell sim$+" "+war$+" "+opp$+" >scores.tmp"
open "scores.tmp" for input as #4
line input #4,a$:close #4
z=instr(a$," "):w=val(left$(a$,z)):t=val(mid$(a$,z))
score=score+w*3+t:n=n+1
wend
close #3
score=(score/n)*(100/rounds)
if score>topscore then topscore=score:top$=war$
sc$=mid$(str$(-1*(1000+score+.00001))+" ",3,6)
print sc$;" ";war$
print #1,sc$;" ";war$
wend
close #1:close #2
open report$ for output as #1
print #1,"Benchmark set: ";benchset$
print #1,"Pmars command: ";sim$
close #1
shell "sort < benchrep.out >> " + report$
kill "benchrep.out"
kill "souplist.tmp":kill "testlist.tmp":kill "scores.tmp"
print "Top score = ";str$(topscore);" by ";top$
end

[the version in the package is a bit more complex, also computes average score and lists the top-scoring warrior]

This program was named bench80 to benchmark nano warriors, the name of the benchmark directory is specified on the command line. This cuts down a little bit on duplication, a bench800 variation is used for coresize 800 warriors...

#!/usr/local/bin/blassic
sim$="pmars -b -k -f -r 1000 -s 800 -p 800 -c 8000 -l 20 -d 20"
rounds=1000 'match -r parm or 142 for nano -P
reportbase$="bench800_"

...and a bench8000 variation is used for coresize 8000 warriors...

#!/usr/local/bin/blassic
sim$="pmars -b -k -f -r 200 -s 8000 -p 8000 -c 80000 -l 200 -d 200"
rounds=200 'match -r parm or 142 for nano -P
reportbase$="bench8000_"

From the command line, program output looks like this...

terry@terry-desktop:~/MyStuff/CWwork/wtnwars_work/80$ bench80 nanoht2
Benchmarking using nanoht2 test set... (Esc to stop)
143.71 01_62.red
148.90 02_08.red
139.43 03_44.red
114.71 0514.red
144.86 0535.red
137.62 0614.red
137.80 1046.red
152.22 another.red
141.04 bazillion.red
141.25 cosmic.red
145.57 CreamedCorn.red
149.40 CrimClim.red
150.94 dimproe.red
148.66 fragor.red
147.92 freefish.red
145.97 frother.red
142.25 furry.red
150.16 hotsoup.red
144.99 JB268.red
150.03 just.red
148.05 LittleBang.red
143.14 m11_16.red
146.90 m3_20.red
139.49 m45_19.red
145.44 m57_6.red
151.13 m7_3.red
141.14 mongoose.red
143.40 multipoint.red
148.40 Nano3551.red
146.42 NanoWorms.red
144.45 NT514.red
151.48 RedRat.red
145.66 Reflow.red
146.77 SleepyLepus.red
147.99 Steaming.red
148.90 swt2-21.red
149.79 swt2-28.red
156.18 TransferFunction.red
146.70 WarmCoffee.red
Top score = 156.1897702 by TransferFunction.red
terry@terry-desktop:~/MyStuff/CWwork/wtnwars_work/80$

The resulting bench80_nanoht2.txt file contains...

Benchmark set: nanoht2
Pmars command: pmars -b -k -P -s 80 -p 80 -c 800 -l 5 -d 5
114.71 0514.red
137.62 0614.red
137.80 1046.red
139.43 03_44.red
139.49 m45_19.red
141.04 bazillion.red
141.14 mongoose.red
141.25 cosmic.red
142.25 furry.red
143.14 m11_16.red
143.40 multipoint.red
143.71 01_62.red
144.45 NT514.red
144.86 0535.red
144.99 JB268.red
145.44 m57_6.red
145.57 CreamedCorn.red
145.66 Reflow.red
145.97 frother.red
146.42 NanoWorms.red
146.70 WarmCoffee.red
146.77 SleepyLepus.red
146.90 m3_20.red
147.92 freefish.red
147.99 Steaming.red
148.05 LittleBang.red
148.40 Nano3551.red
148.66 fragor.red
148.90 02_08.red
148.90 swt2-21.red
149.40 CrimClim.red
149.79 swt2-28.red
150.03 just.red
150.16 hotsoup.red
150.94 dimproe.red
151.13 m7_3.red
151.48 RedRat.red
152.22 another.red
156.18 TransferFunction.red

Here's the bench80x wrapper script for running bench80 from a GUI menu...

#!/bin/bash
function doit {
bench80 "$1"
echo "--- press any key ---"
read -n 1 nothing
}
if [ "$1" == "doit" ]; then
doit "$2"
else
xterm -e $0 doit "$1"
fi

...similar to the other wrappers, with variations for bench800x and bench8000x. These are for running from CWtools or a similar menu script which supplies the benchmark directory name as the first parameter, if running via file association then individual scripts for each benchmark variation are needed, the scripts should extract the directory name from the passed parameter and change to it before running the bench program in a terminal. Something like this bench80x_nanoht2 variation for running bench80 with the nanoht2 benchmark set...

#!/bin/bash
function doit {
bench80 nanoht2
echo "--- press any key ---"
read -n 1 nothing
}
if [ "$1" == "doit" ];then
doit
else
cd `dirname "$1"`
xterm -e $0 doit
fi

...with variations for running bench80 nanoBM07, bench80 nanob2, bench800 tinyFranz, bench800 tinyBM04, bench8000 94nopWilkies, and bench8000 94nopWilfiz. But that's really starting to pile up the associations, plus the directory-parsing code in this script form fails if there are spaces in the directory name (not that that's much of a reason but sometimes it happens).

CWtools - a Nautilus script for running the corewar scripts

The Nautilus file manager provides a way to eliminate (or at least reduce) file associations and replace them with a menu run as a Nautilus script, this also eliminates the need to change to the directory containing the warriors as Nautilus sets the current directory to the current location before running the script, thus it still works if there happens to be spaces in the directory name (but warrior names still must not contain spaces). The CWtools script uses zenity to display menus for running coresize 80, 800 and 8000 warriors and benchmarking one or many warriors using the cwbx* and bench*x programs using the nanoBM07, nanob2, nanoht2, tinyFranz, tinyBM04, 94nopWilkies and 94nopWilfiz benchmark sets (all the needed scripts and benchmark sets are included in the cwscripts.tar.gz package). The CWtools script needs to be placed in ~/.gnome2/nautilus-scripts, and the tools must be named as discussed (pmv80x, cwbx_nanoht2, bench80x, etc) and placed in a path directory (typically /usr/local/bin), modify the script as needed to run different variations and benchmark sets.

#!/bin/bash
selection=""
if [ ! "$1" == "" ];then
if [ ! "$2" == "" ];then
if [ -e "$1" ];then
selection=$(zenity --title "CWtools" --column "" --hide-header --list \
"Run in coresize 80" \
"Run in coresize 800" \
"Run in coresize 8000" \
)
fi
else
if [ -e "$1" ];then
selection=$(zenity --width 350 --height 350 \
--title "CWtools" --column "" --hide-header --list \
"Run in coresize 80" \
"Run in coresize 800" \
"Run in coresize 8000" \
"Benchmark in coresize 80 nanoht2" \
"Benchmark in coresize 80 nanoBM07" \
"Benchmark in coresize 80 nanob2" \
"Benchmark in coresize 800 tinyBM04" \
"Benchmark in coresize 800 tinyFranz" \
"Benchmark in coresize 8000 94nopWilkies" \
"Benchmark in coresize 8000 94nopWilfiz" \
)
fi
fi
if [ "$selection" == "Run in coresize 80" ];then
pmv80x $*
fi
if [ "$selection" == "Run in coresize 800" ];then
pmv800x $*
fi
if [ "$selection" == "Run in coresize 8000" ];then
pmv8000x $*
fi
if [ "$selection" == "Benchmark in coresize 80 nanoht2" ];then
cwbx_nanoht2 "$1"
fi
if [ "$selection" == "Benchmark in coresize 80 nanoBM07" ];then
cwbx_nanoBM07 "$1"
fi
if [ "$selection" == "Benchmark in coresize 80 nanob2" ];then
cwbx_nanoBM07 "$1"
fi
if [ "$selection" == "Benchmark in coresize 800 tinyBM04" ];then
cwbx_tinyBM04 "$1"
fi
if [ "$selection" == "Benchmark in coresize 800 tinyFranz" ];then
cwbx_tinyFranz "$1"
fi
if [ "$selection" == "Benchmark in coresize 8000 94nopWilkies" ];then
cwbx_94nopWilkies "$1"
fi
if [ "$selection" == "Benchmark in coresize 8000 94nopWilfiz" ];then
cwbx_94nopWilfiz "$1"
fi
else
redfiles=$(ls *.red 2>/dev/null | wc -l)
if [ ! "$redfiles" == "0" ];then
selection=$(zenity --width 370 --height 280 \
--title "CWtools" --column "" --hide-header --list \
"Benchmark all in coresize 80 nanoht2" \
"Benchmark all in coresize 80 nanoBM07" \
"Benchmark all in coresize 80 nanob2" \
"Benchmark all in coresize 800 tinyBM04" \
"Benchmark all in coresize 800 tinyFranz" \
"Benchmark all in coresize 8000 94nopWilkies" \
"Benchmark all in coresize 8000 94nopWilfiz" \
)
if [ "$selection" == "Benchmark all in coresize 80 nanoht2" ];then
bench80x nanoht2
fi
if [ "$selection" == "Benchmark all in coresize 80 nanoBM07" ];then
bench80x nanoBM07
fi
if [ "$selection" == "Benchmark all in coresize 80 nanob2" ];then
bench80x nanob2
fi
if [ "$selection" == "Benchmark all in coresize 800 tinyBM04" ];then
bench800x tinyBM04
fi
if [ "$selection" == "Benchmark all in coresize 800 tinyFranz" ];then
bench800x tinyFranz
fi
if [ "$selection" == "Benchmark all in coresize 8000 94nopWilkies" ];then
bench8000x 94nopWilkies
fi
if [ "$selection" == "Benchmark in coresize 8000 94nopWilfiz" ];then
bench8000x 94nopWilfiz
fi
fi
fi

The menu is different depending on how many files are selected. If no files are selected (and one or more .red file exists) then a menu for benchmarking all warriors is displayed, if one file is selected then the menu displays options for running in pmarsv and benchmarking a single warrior, and if multiple files are selected then the menu shows only the pmarsv run options. The menus are presently crude...

 

...but functional, select the desired function and click OK (or double-click the selection) to run the tool. Redcode warriors must be run in the environment they were programmed for so if you select a coresize 80 tool for a coresize 800 or 8000 warrior you'll just get an error message. This solution covers the most common corewar configurations but if experimenting with other hill configurations just copy and edit the appropriate scripts and add them to the menu, modify the zenity --width and --height settings as needed to make room.

Thoughts

Corewar is an old computer game that mainly appeals to programmers who take pleasure in watching programs clobber other programs, there isn't all that much interest in it these days but a few hills remain open and every now and then a tournament is performed.. sometimes even with prizes. I hope others can make use of these scripts (or even just get ideas about using Blassic and bash scripts) but the main reason I wrote these scripts is for my own use - my old batch and QBasic scripts are rather well-worn and I wanted more modern solutions. Also I'm presently testing an alpha of the new Ubuntu 12.04 OS and needed an excuse to "develop" something to test scripting, association and usage that's typical of actual work I need to be able to do with an OS.


Created Dec.12,2011, Last mod Dec.17,2011
Terry Newton (wtn90125@yahoo.com)