aBOTcalypse
Design a bot to compete in a King-of-the-Hill challenge! Here's a replay of a default bot game.
The board is 2D, like a side-scrolling video game (but without any scrolling).
A valid bot must accept a multiline string representation of the region of the board it can see, and output a move for the bot.
Mechanics
This is a survival game. The apocalypse has come, and only bots (and an endless supply of rocks stored in hammerspace) remain. Each bot is given a random starting location, at elevation 0. In a given move, a bot can rest, move, throw a rock, or drop a rock. Bots can share space with stationary rocks, but a bot that collides with another bot or a meteor is killed, as is a bot hit by a thrown rock.
- Gravity: bots and rocks must rest on top of the floor of the board or on top of another rock; resting on something else (air, a meteor, a bot, etc.) leaves one "unsupported". Unsupported bots or rocks will fall until they are supported; a fall of greater than one space will kill a bot, and a bot underneath a falling rock or bot is also killed. This means that trying to move or drop up will only work if the bot is currently sharing a space with a rock (otherwise the bot/rock will fall back down 1 space). A space can become "unsupported" if the rock beneath it falls or is destroyed by a meteor or projectile.
- Meteors: Each turn a meteor enters the board from the top. A meteor has a velocity of magnitude 2, with a random angle chosen uniformly in the range [-180,0], and a random starting x position. Meteors fall in a straight line along the given trajectory until they hit something, at which point they disappear. Note that rounding in a meteor's movement is towards 0 (as per python's
int()
). - Projectiles: A bot can choose to throw a rock any distance up to its elevation. A thrown rock moves in a straight line until it hits something (all in one turn, unlike a meteor; thrown rocks don't appear on the board), at a slope of
- elevation / max distance
. Note that thrown rocks begin their trajectory at x +- 1 square. For example, if a bot is at an elevation of 5, and throws left a distance of 1, the rock will begin at(x-1,5)
and end at(x-2,0)
. Collision is only checked in steps ofdx=1
, anddy
is rounded towards 0 (as per python'sint()
).
Input
Each bot can see a square 20 pixels in each direction (Chebyshev distance = 20), up to the boundaries of the board. There are 8 different characters in each input string:
'#'
(board boundary)'.'
(air)'@
' (meteor)'&'
(rock)'e'
/'s'
(an enemy bot, or itself)'E'
/'S'
(an enemy bot, or itself, sharing a space with a rock)
Here's an example input (line breaks will be \n
):
..............................#
..............................#
..............................#
..............................#
..............................#
..............................#
..............................#
..............................#
..............................#
..............................#
..............................#
..............................#
..............................#
..............@...............#
.....................E........#
.....................&........#
.....................&........#
.....................&........#
.....................&........#
...........@.........&........#
....................s&........#
###############################
Output
There are four actions that a bot can take each turn.
rest
(literally sit and do nothing)move <direction>
moves the bot one space in any of the four directions,up
,down
,left
, orright
. Movement causes the bot to fall if the new space is not supported by the floor or a rock (fall > 1 = bot.kill()
).drop <direction>
places ("drops") a rock in the indicated direction. Dropping a rock up (i.e., placing a rock in the square[bot_x, bot_y+1]
) or to the side causes it to fall until supported (possibly falling onto the bot duringdrop up
).drop down
places a rock in the same position as the bot, if there is not a rock there already.throw <direction> <distance>
throws a rock as per the "projectiles" mechanics above, with the indicated max distance. Max distance is irrelevant for throwing upward or downward - the projectile collides with the square below (fordown
), or attempts to collide with the square above (forup
) and then with the bot's square if it doesn't hit anything (killing the bot).
A bot in the contest must output a scalar string with its action upon receiving the input string.
Interface
A bot must consist of a single program which can be called via a python 2 subprocess
. Any commands should be indicated, and will be saved in a file called command.txt
; before a game begins, the controller will execute each command in command.txt
, in order, and then the final command will be used to pass input to the bot from then on.
A bot may have a single storage file called storage.txt
in its folder; the "Default Thrower" bot shows an example implementation, using json to save its state during various turns. In addition, feel free to include debugging output in a write-only errlog.txt
, which I'll pass along in case your bot fails during a run. I'll make sure to run several tests with each bot, to try and find any errors beforehand.
Scoring
A bot's total score is equal to the number of turns it survives, accumulated over X games of maximum length Y. At the moment, X,Y = 10, 500
; if bots are lasting a long time, I'll increase Y, and if they are lasting a short time, I'll increase X.
Controller code is found in controller.py; many thanks to @Nathan Merrill for his DDOS koth from which I adapted the Communicator code.
&&&\n&S&\n###
? They would be invulnerable to falling meteors. \$\endgroup\$