The first thing you should know is that this is a very ugly hack. I'm not really keen on providing support for this package, it serves its purpose for me as a way to kill time. I know this compiles on Freebsd 4.X->5.X and on dedrat linux. You'll need GCC 3.3 for fmars. You'll also need guile, and perl. You will also need a copy of pmars to convert any warriors you wish to benchmark with. I consider my included code to be public domain, exhaust (which has been grossly deformed and included, sorry) belongs to Joonas and is under a free license, cosm which is only here because I haven't bothered to completely tear it out yet, is under the GPL. fmars is GPL code. The basic idea is a distributed evolving system for corewars. The warriors exist in "a pool" which is by default 1000 warriors, divided randomly into 20 "species". When a client starts, it checks out a copy of the pool from a server, which includes a copy of all the warriors, and a group of benchmark warriors to evaluate the fitness of each warrior in the pool. On starting a new pool, the default action for the clients is to calculate scores for COUNT (in common.h) warriors, and return the scores. Once all warriors have an initial score, the server will start handing out evolving blocks. The client will select 3 warriors from a species, attempt to breed them into a new, better child warrior. If they succeed (that is score higher than the lowest warrior of that species), the child warrior will overwrite the lowest scoring warrior of that species. When the client has produced enough new child warriors to exceed RETURN_COUNT, the client will send the new warriors back to the server, and check out a new block. As well, there is a proxy server, which will check out a block from the master (or another proxy upstream) and then serve that block to its own clients. When the proxy gets PROXY_RETURN_COUNT new warriors, it will upload the results and checkout a new block. This is useful for clusters where only the master node has a connection to the internet. ------ |Master| ------ | -------- ------>|Client| | -------- | -------- -------- -------- ------>|Proxy |---->|Proxy |------>|Client| -------- -------- -------- | | -------- --------->|Client| -------- The next thing to be aware of is populating the HILL directory with useful warriors. You'll need to convert.pl all of them into a format exhaust can read. You should also think about removing qscans, and possibly breaking each component into its own file. The stat_make script isn't terribly intelligent about how it reads the warriors, it starts at the top and runs blocks 5 instructions long until it reaches the end. Breaking warriors out into components and removing a qscan (which I have never actually seen successfully reassembled by the evolver) will keep you from walking down some useless evolutionary backwaters. I have also tried seeding the HILL directory with only one type of warriors (scanners or papers) etc. I would be interested in hearing about other successful ideas. Compiling the stat_code.c file can be quite a large task, if I use all of the K infinate hill as my HILL directory, it takes nearly a GB of ram to compile the resulting stat_code.c file. It depends greatly on what version of GCC you use, and what sort of optimizations you've configured. Once you get your stat_code.o file, perhaps you'd like to comment out the lines that rebuild it in the makefile (unless you wish to change your HILL directory). Then you won't have to wait the 30 minutes for it to compile if you choose to rebuild. If you wish to tweak any of the values of a running pool, you can use the tweak utility. The tweak utility sends a control block to the master server to change things like the number of rounds, the validation scores, mutation rates, etc. You can also invoke the -Z flag to zero the pool and force all the warriors to be rescored (which can be handy to restart a lagging pool). The most successful method I've found for evolving warriors is as follows: Run makepop and generate 5000 or 10000 random warriors. Edit the source directory in the mkrandbench.pl script to point to where you put your warriors. Run the mkrandbench.pl script to fill your data directory with 1000 warriors, then run mkrandspecies.pl to randomize the species. Run the master, and evolve until your pool acceptance rate starts to hang < 10%... using the tweak utility to raise the validate scores to hang somewhere around the average scores (although I've found the highest you'll want to set the BLOCK_VALIDATE is around 50). As well, you should slowly reduce the mutation rate as the pool progresses. When your pool reaches stagnation, dump -f server.dat -s -1 to dump all the warriors to files in the save directory. Then make another pool from random warriors and try again. Repeat with random warriors until you have 5 or 10K of evolved warriors. Switch the source directory in the mkrandbench.pl file, and begin generating pools with evolved warriors. I suggest upping the number of rounds you benchmark with at this point, as the scores tend to become closer, and score noise will become a problem. Score noise tends to exaggerate scores rather than depress them, so don't be disappointed when you run with more rounds and find all your scores have dropped slightly. Repeat this process until your pool no longer gives better results. I found that after about three levels of culling ( random pool -> evolved pool 1 -> evolved pool 2 from pool 1 -> evolved pool 3 from pool 2) the variation between warriors was becoming quite small. Eventually there will not be enough variation in the population to produce any seriously innovative combinations. I used 5 levels when I evolved Machines Will Rise. For some additional information, you could look at the article in CoreWarrior 90 (www.corewar.info/corewarrior/cw/090.htm) Although it describes the previous version of this evolver code. If you need warriors for benchmarking or the HILL directory, you can look at http://www.ociw.edu/~birk/COREWAR/ For benchmarks, you should really look at www.corewar.info/optimax I think they are by far the best. Don't forget to convert.pl Step 1, build the cosm libs ./build x86-freebsd Step 2, build the client, master and associated programs cd apps/cs-sdk Set the hostnames and various settings in common.h NETPACKET_HTTPSERVER and NETPACKET_SERVER are the default servers the clients will try to contact and the proxy server (server) will try to be. MASTER_SERVER is the hostname of the server the proxy servers will try to contact for their updates and the master server (master) will try to be. Populate the HILL directory with warriors (and convert.pl them! You will need a copy of pmars for that). This is where the stat_make program will look for warriors to generate the code chains. I have had the best luck with warriors I've removed the qscans from as well. Once you've got your HILL warriors, you're ready to make make clean ; make Step 3, create initial population You will need to place some warriors in the bench directory. Without warriors in this directory master and makepop will coredump. The current configuration is expecting ~100 benchmark warriors. They will need to be convert.pl'd as well (so exhaust and fmars can read them). The makepop script will generate random warriors from the chains built up from what was found in the HILL directory. If you are having problems getting makepop to give you anything useful, you can try putting more warriors in HILL, or lowering the MAKE_VALIDATE score in common.h and recompiling. Your best bet to get a good solid set of benchmark warriors is to use the fsh packages from OptiMAX (by Christian Schmidt), they can be found at www.corewar.info/optimax/. Simply copy to the bench directory and convert.pl. I personally used the 94nop benchmark for Machines Will Rule. ./makepop -d save This will take anywhere from a few minutes to a few weeks. It can be made faster by dropping the MAKE_VALIDATE score. cp save/* data ./master then start your clients, they'll contact the master and get work, and return it when done. To view the warriors in the masters pool, you can use the dump script, dump -f server.dat -s -1 will write a copy of all the warriors to the save directory. If you have problems, make sure your hostnames are set properly (3jane.math.ualberta.ca won't work unless you are me!!!). YMMV. Results not typical. This code promises nothing and delivers less.