2026-03-26 18:43:01 +01:00
2026-03-26 18:43:01 +01:00
2026-03-26 18:43:01 +01:00
2026-03-26 18:43:01 +01:00
2026-03-26 18:43:01 +01:00
2026-03-26 18:43:01 +01:00
2026-03-26 18:43:01 +01:00
2026-03-26 18:43:01 +01:00
2026-03-26 18:43:01 +01:00
2026-03-26 18:43:01 +01:00

SWARM challenge

The plan:

  • Reproduce the maps on the website
  • Create an assembler to generate bytecode. Add special instructions to define tweakable params and optional code blocks?
  • Create an antfarm: a high-performance program that can score ant programs inside those maps
  • Create a highly modular and customizable ant program
  • Create a program that makes small random changes to ant programs
  • BREED SUPERANTS

Contents of this repo:

  • /reference contains reference materials describing and defining the challenge
  • /maps contains scripts to generate and view maps (nodejs)
  • /asm Assembles antssembly into my custom antbytecode
  • /farm This runs the ALIEN ANT FARM

Reference

The reference folder contains

  • A sample ant program
  • The reference found on the website
  • A wget download of the relevant SPA

Maps

As mentioned in the reference, there are 12 map generator functions.

  • chambers
  • bridge
  • gauntlet
  • islands
  • open
  • brush
  • prairie
  • field
  • pockets
  • fortress
  • maze
  • spiral

When looking in the browser, the generated maps have names like 'chambers-3lc8x4' or 'bridge-1u7xlw' where the string after the dash is the seed used, encoded in base36.

  • nodejs maps.js generate -n 120 -o mymaps.maps generates 120 maps and stores them in mymaps.maps
  • nodejs maps.js view bridge-1u7xlw renders the indicated map to ascii

Asm

The assembler is not copied from the challenge, but a new implementation.

It has a couple of deviations from the spec:

  • Literals can only be 0-255, non negative. This is done to simplify the bytecode somewhat. I do not believe i will need literals outside this range (famous last words). This is only the literals in the assembly. The actual registers are full 32bit.
  • Constants, tags and aliases all end up in the same pool, and are case insensitive
  • JMP main is always prepended to every program

The bytecode is quite simple. Every instruction is 4 bytes. The first byte is the instruction number, the other 3 are single-byte arguments.

Jump instructions are a special case. They need to specify a target instruction offset, and the conditional jumps also take two normal arguments. This does not fit into 4 bytes. To accommodate this, our cpu introduces a 9th register called JR and 2 'hidden instructions' called SJR and MJR. Any jump instruction is assembled into 2 bytecode instructions: first SJR or MJR and then the original instruction. SJR (Set JR) uses all 3 argument bytes as a single unsigned little endian int to describe the offset. MJR (Move JR) copies the value from a register into JR. The jump instructions simply use JR as the destination address

FARM

Some would say this is where the magic happens.

This is a program that reads the maps file (generated by the maps script), and an apm file (ant program, generated by the assembler) and starts breeding ants!

Description
No description provided
Readme 341 KiB
Languages
JavaScript 50.5%
C 27.3%
Python 12.9%
Makefile 8%
Shell 0.9%
Other 0.4%