Documentation

Bomberjam is an artificial intelligence programming challenge where people compete in coding the best bot.

The game world consists in a 13 x 11 tile grid with blocks that can be destroyed using bombs, bonuses randomly hidden in some of these blocks, and non-destructible walls. At the beginning of the game, each player (bot) will be assigned an index from 0 to 3, and placed at one of the four corners.

Players get points by doing specific actions:

  • Destroying blocks: 5 points.
  • Hit another player with a bomb: 20 points.
  • Being the last player standing: 50 points.

Players can also lose points by getting hit by a bomb : -10 points.

Game initialization

Your bot communicates with the game engine though standard output and standard input. You cannot use standard ouput and standard input for anything else. If you need to log something, write it to a file.

The first thing your bot must do is sending its name, prefixed with: 0:. So if you name your bot MySuperBot, you must send 0:MySuperBot.

Right after sending its name, your bot must read from standard input for its player index. It's its position in the players dictionary.

Game loop

Through standard input, and at each tick, your bot will receive the current state of the game serialized as JSON. It will have to decide whether to go left, right, up, down, to stay or drop a bomb within one second.

These actions must be sent though standard output, prefixed with the tick number, like this: 42:down.

The game state object

{
  "tick": 54,
  "width": 13,
  "height": 11,
  // flattened grid tiles, see tile type descriptions below
  "tiles": "....+++++.....#.#*#+#+#.#.+.****+++....+#.#*#+#+#.#..+++++++.+.+++#+#+#.#+#.#.+....++..+.++.#.#+#+#.#.#......++.......#.#+#+#.#.#....++++++++..",
  // learn more about sudden death below
  "suddenDeathCountdown": 186,   // number of ticks until the sudden death starts
  "isSuddenDeathEnabled": false, // whether or not the sudden death is active
  "isFinished": false,
  "players": {
    "0": {
      "id": "0",
      "name": "Askaiser",
      "x": 2,
      "y": 9,
      "startingCorner": "bl",
      "bombsLeft": 0,
      "maxBombs": 1,
      "bombRange": 2,
      "isAlive": true,  // if false, the player has been killed by the sudden death and is no longer in the game
      "respawning": 0, // if positive, the player has been blown by a bomb and is now respawning for this amount of ticks
      "score": 40, // zero of positive number of points
      "timedOut": false,
      "color": 2001125
    },
    "1": { ... },
    "2": { ... },
    "3": { ... }
  },
  "bombs": {
    "18": {
      "x": 12,
      "y": 2,
      "playerId": "1",
      "countdown": 5, // when countdown reach zero, the bomb explodes and is removed from this collection
      "range": 3
    },
    "16": { ... },
    "17": { ... }
  },
  "bonuses": {
    "19": {
      "x": 4,
      "y": 1,
      "kind": "fire" // possible values: bomb (increases maxBombs) and fire (increases bombRange)
    },
    "20" { ... }
  }
}

Tile types

Character Description Image
. Walkable empty tile Walkable empty tile
* Explosion Explosion
+ Destructible block Destructible block
# Non-destructible wall Non-destructible wall

Bonuses

Players get permanent bonuses by walking on them.

Type Description Image
bomb Increases player.maxBombs property Extra bomb
fire Increases player.bombRange property Bomb range

Sudden death

When suddenDeathCountdown reach zero, new walls are added to the grid from the outside to the inside in a circular manner. Players that are on its way will die (player.isAlive: false) and won't respawn. The only player left gets extra points.

Respawning

If suddenDeathCountdown is not active and a player gets hit by a bomb, he will be teleported to his starting corner. For a specific amount of ticks (player.respawning), this player will be invincible but won't be able to drop bomb.

Sudden death animation

Bomberjam engine CLI arguments

Usage: bomberjam [OPTION]... [BOTPATH]...
Example: bomberjam -q -r 42 -o "replay#n.json" "dotnet MyBot.dll" "java -classpath "".;*"" MyBot" "node MyBot.js" "python MyBot.py"

Options:
  -r, --repeat=VALUE         The number of games to play
  -o, --output=VALUE         Path of saved games, use placeholder #n to insert game index
  -s, --seed=VALUE           The random generator seed number
  -t, --no-timeout           Disabe all timeouts for debugging
  -q, --quiet                Suppress output logging
  -h, --help                 Show help and exit

Troubleshoot your bot

Using the C# starter

Modify your bot so it can accept an argument such as --debug. At the beginning of the program, add a pause if this argument is present. This pause will allow you to attach the debugger to the process:
public static void Main(string[] args)
{
    var isDebugging = args.Any(x => "--debug".Equals(x, StringComparison.OrdinalIgnoreCase));
    if (isDebugging)
        Thread.Sleep(TimeSpan.FromSeconds(10));

    // [...]
}
Next, modify the script that runs the bomberjam engine, usually run_game.bat or run_game.sh, and add two things:
  • The new bot argument for one of the four bots: dotnet [...]/MyBot.dll --debug
  • The --no-timeout to the bomberjam.exe engine so it will wait indefinitely for your bot to send its name and all the actions
Finally, open the IDE of your choice, add a breakpoint, start the game and attach the .NET debugger to the process that have the new bot argument --debug. Your breakpoint will be hit after the pause and you'll now have the freedom to inspect anything without timeout.