Menu

Readme

Miha Vitorovic

This page provides some information about the upcoming version 0.5. Version 0.5 is currently in the BETA stage and may still contain some bugs.

Java GA Redcode evolver v 0.5
Copyright (c) 2005-2014, Miha Vitorovič

1. Introduction

The goal of this project is to develop a Java Genetic Algorithm redcode warrior evolver. This document provides some basic information and is split into two parts. It starts with the user part, followed by a developer part.

2. Instructions

To run CoreWars you will need Java 8. You may download it from http://www.java.com . After you install Java, you may start CoreWars with:

java -jar <JAR archive name> [options] warriorFile [warriorFile ...]

Options:
-e     (--debug) Opens debug window, allows single-stepping, and memory inspection.
-r #   (--rounds) Specify the number of rounds.
-s #   (--size) Specify core size.
-c #   (--max-cycles) Sets the maximum number of cycles per round.
-p #   (--max-processes) Sets the maximum number of processes a warrior can run.
                         The default is 8000.
-l #   (--length) Sets the maximum length of a warrior source file in
                  instructions. It defaults to 100 and can be up to 500.
-d #   (--min-distance) Specify minimal distance between warriors.
-S #   (--p-space-size) Specify P-space size.
-F #   (--fixed-address) Install second warrior at fixed address #.
-b     (--brief) This options runs pMARS in brief output mode. It
                 suppresses warrior listings after assembly.
-= $   (--score-formula) Define a score formula. Default: (W*W-1)/S

-GC $  (--generate-config) Generates configuration XML file with a given name.
-RC $  (--run-config) Runs the GA algorithm using the configuration file.

3. Documentation

Mars interpreter (I hope) finally works correctly, or at least it runs the "validate.red" warrior (part of pMARS distribution) the way it should. The interpreter is based on ICWS 94 Proposed Standard implementation http://www.koth.org/info/icws94.html

It supports all ICWS'94 OpCodes, and so far the following meta instructions:

  • org <start address>
  • end [<start address>]
  • ;assert <expression>
  • ;name
    • others will be added later
  • labels and address arithmetics - parentheses may be used to change priority
  • operators & priority:

     Arithmetic:
         +   addition or unary plus
         -   subtraction or unary minus
         *   multiplication
         /   division
         %   modulo (remainder of division)
    
     Comparison:
         ==  equality
         !=  inequality
         <   less than
         >   greater than
         <=  less than or equal
         >=  greater than or equal
    
     Logical:
         &&  and
         ||  or
         !   unary negation
    
     Assignment:
         =   assignment to a variable
    
     Comparison and logical operators return 1 for true and 0 for false.
     Parentheses can be used to override this precedence order:
    
     1) ! - + (unary)
     2) * / %
     3) - + (binary)
     4) == != < > <= >=
     5) &&
     6) ||
     7) =
    

Supports EQU and FOR/ROF loops. The goal was to compile everything pMARS does, and even some things that pMARS doesn't. The compiled output may not be character by character the same as with pMARS, but is functionally equivalent, e.g. you may get '7983' instead of '-17' for CORESIZE 8000.

4. Variables

Variables contain the statistics collected during the warrior execution as well as some MARS settings. They can be used to calculate a fitness function. This section lists variables and gives some examples on how to used them:

  • size - the initial size of the warrior
  • cycles - the number of cycles the warrior ran
    • With randomly generated warriors for the first "couple" of generations one of the few things worth testing is how long can the warrior run at all
    • warrior starts on a DAT command; score -500: (cycles <= 1)*(-500)
    • warrior runs for less than 10% of its size and then dies; score -100: ((cycles*1.0/size)<0.1)*(-100)
    • warrior runs for 10%-40% of it's size; score 100: (((cycles*1.0/size)>=0.1)&&((cycles*1.0/size)<0.4))*100
    • warrior runs goes through a major part of it's instructions; score 300: (((cycles*1.0/size)>=0.4)&&((cycles*1.0/size)<1.0))*300
    • warrior actually contains a loop; score 1000: ((cycles*1.0/size)>1.0)*1000
    • A fitness function covering all of the above cases would just have to add all these equations
  • id - the ID (number) of the current warrior. Nonzero number.
  • coreSize - the size of the core
  • maxProcesses - the maximum number of processes
  • maxCycles - the maximum number of cycles the battle can run
  • maxLength - the maximum length of the warrior
  • maxEI - The rate of the max executed instruction. This is a double. If cycles==maxCycles and maxIE==0.99, this means that the warrior spent 79200 cycles executing one instruction. Which is a good indication that it stalled at one instruction. Such a warrior should get a low score.
  • victory - 2 of the warrior was victorious, 1 if it was a draw, 0 if it lost.
  • myOW - stands for "my original writers". Each memory cell holds two pieces of meta-information:

    • original writer to the cell - the ID of the warrior that originally "inhabited" this cell (0 if the cell was empty)
    • last writer to the cell - the ID of the warrior that last modified this cell (0 if nothing was modified). The myOW variable contains the original writers information for the last X executed commands of the current warrior. The last executed instruction is at index 0. Index 1 means the one before last executed commands. Note: there is no way of determining the size of the array. Non-existing indexes simply return 0 value.
    • myLW - stands for "my last writer". This variable contains the last writers information for the last X executed commands of the current warrior. The last executed instruction is at index 0. Index 1 means the one before last executed command.

      EXAMPLES: These variables help with better diagnosing the cause of the "death".
      if(myOW[0]==id && myLW[0] == 0) --> The warrior died executing its own DAT statement; bad
      if(myOW[0]==id && myLW[0] == id) --> The warrior died executing its own DAT statement, and it actually modified it before that. Maybe it wasn't a DAT statement before; REALLY BAD
      if(myOW[0]==0 && myOW[1] == id) --> the warrior jumped to uninitialized core; bad
      if(myLW[1] != id) --> the warrior died as a direct consequence of the other warrior's actions; not so bad

  • otherOW - stands for "other original writers". This variable contains the original writers information for the last X executed commands of the opponent. The last executed instruction is at index 0. Index 1 means, the one before last executed commands.

  • otherLW - stands for "other last writers". This variable contains the last writers information for the last X executed commands of the opponent. The last executed instruction is at index 0. Index 1 means, the one before last executed commands.

The variables otherOW and otherLW help with diagnosing the current warriors offensive abilities. It can tell whether the warrior won because of its offensive behavior or it simply outlived a suicidal opponent.


Related

Wiki: Developer Readme
Wiki: Home
Wiki: Tutorial