📚Game documentation
This section will cover the information for the Game Environment.
Last updated
This section will cover the information for the Game Environment.
Last updated
Winning conditions The winner of a game is the last bot standing, or the bot that scores the most points at the end of 180 seconds (i.e. 1800 game 'ticks').
Health Points (HP) Each agent starts the game with 3 HP. You lose 1 HP each time you are within range of an exploding bomb. If you run out of HP, it's game over.
Game controls On each game 'tick' (every 100ms), you can either move up, left, down, right, place a bomb, or do nothing.
Scoring points Score points by destroying blocks, collecting treasure chests or hitting other players with bombs. Blocks can only be destroyed from the impact of exploding bombs.
Wooden blocks Takes one hit to destroy and gives +2 points to the Agent.
Ore blocks Takes three hits to destroy and gives +10 points to the Agent that makes the final hit.
Metal blocks Metal blocks are indestructible.
Treasure Chests Treasure chests spawn randomly around the map. Walk over a tile containing a treasure chest to collect +1 point.
Bombs Each Agent starts the game with 3 Ammo. Placing a bomb costs 1 Ammo. Bombs explode 3.5 seconds after they've been placed, and hits any player or blocks to the top, left, right or left-side of it with a 2-tile blast radius. Bombs can detonate early, if they are hit by another exploding bomb. Players are only impacted by the bomb if they are within range on the game tick that the bombs explode on. Hitting another player with a bomb will net you 25 Points.
Bomb ammo Ammo spawns randomly around the map. Walk over tiles containing ammo to pick them up. Ammo tokens that are not picked up will perish after 175 ticks (17.5s) and randomly respawn in a new location.
Below is a simplified diagram of what happens at each 'tick' of the game (every 0.1s):
Once all game dependencies properly installed outlined in the Setup guide. The game can be launched using command line:
Or alternatively:
There are a number of command line options supported by the game driver. To get a full list of options run:
Alternatively, if the above doesn't work, you can try:
The game runner recognises a number of command line options.
--headless
- run the game without graphics. Tournament matches will be run in this mode.
--interactive
- game is created with an extra player for the interactive user. This player can be controlled using the keyboard.
--watch
- automatically reload the user's agent if the source code files changes. This allows for interactive development as code can be edited while the game is running.
--record <FILE>
- record game action into a specified file for later review.
Enter
- to pause / un-pause the game
R
- to restart the game with new random map
↑
/ ↓
/ ←
/ →
- arrows to move the player
<SPACE>
- to place the bomb
There are 3 main modes to run the game:
Interactive mode - when a human player can participate in a match. This is a 'normal' game mode when a human user can play the game with the keyboard the game to explore it. This mode requires at least one bot.
Match - two (or more) AI agents play a game without a human participant.
'Headless' match - the game is played by bots with no human participant and without graphics output. This is the mode used to run a tournament.
By default, game runs in a tournament mode, without user input, with graphics output. For example, to run a random match between two AI agent "agent1.py" and "agent2.py", run:
From here on we're referring to your bot as an agent (in keeping with AI research terminology).
Your job is to define a class Agent
.
You'll need to complete the next_move
method contained within your class which is called on each turn of the game and:
Is given information about the game environment (stored in game_state
and player_state
)
Must return an action (see '🕹️ Actions' section)
Below is what our most simple agent, the Random Agent, looks like. You are welcome to use it as a template for your agent.
The map of the game is represented as below:
Each object in the game is represented by a string 'Tag':
0
: Player 1 (Wizard)
1
: Player 2 (Knight)
ib
: Metal Block (i.e. Indestructible Block)
sb
: Wooden Block (i.e. Soft Block)
ob
: Ore Block
b
: Bomb
a
: Ammo
t
: Treasure Chest
For more information on how to request information about the game environment, check out the '🎮 Game State' section.
⚠️ Note: if a player and bomb are on the same tile of the map, it will be represented as b
only. To access the location of the player, use player_state.location
.
Actions are represented by a string value:
''
: Do nothing
l
: Move left
r
: Move right
u
: Move up
d
: Move down
p
: Place a bomb
On each game tick (i.e. every 100ms), the game will request your agent's action as one of the above values. If you do not provide an action for that tick, you agent will do nothing. You can take as long as you wish to produce an action, but the longer you take to make a move, the more the game will update around you.
All information on the current state of the game is given to your agent each turn in two objects: game_state
and player_state
game_state
(class object), has the following properties:
is_over
(Boolean): whether the game has ended
tick_number
(int): the number of turns that have passed. Each 'tick' corresponds to 100ms
size
(tuple): the size of the game map, represented as (x,y) - (x = columns, y = rows)
bombs
(list of tuples): list of the locations of all bombs currently on the map
ammo
(list of tuples): list of the locations of all ammo currently on the map
treasure
(list of tuples): list of the locations of all treasure currently on the map
all_blocks
(list of tuples): list of the locations of all blocks (wooden, ore, metal) currently on the map
soft_blocks
(list of tuples): list of the locations of all wooden blocks currently on the map
ore_blocks
(list of tuples): list of the locations of all ore blocks currently on the map
indestructible_blocks
(list of tuples): list of the locations of all indestructible metal blocks currently on the map
game_state
also provides the following methods:
entity_at(location)
: takes an input location as an (x,y) tuple and returns the tag of the entity/object at that location:
As an int (if the entity is a Player, i.e. 0
or 1
)
None
if empty
A string otherwise (e.g. sb
, ob
, a
, etc).
is_in_bounds(location)
: takes an input location as an (x,y) tuple and returns True or False (Boolean) depending on whether that location is within the boundaries of the game map
is_occupied(location)
: takes an input location as an (x,y) tuple and returns True or False (Boolean) depending on whether that location is occupied (i.e. contains ammo, block, players etc.)
opponents(excluding_player_pid)
: takes an Agent ID as an integer and returns the current location of the opponent players as a list of tuples
player_state
(class object), with the following properties:
id
(int): your agent's player number (i.e. Player 1 = 0
, Player 2 = 1
, and so on)
ammo
(int): the amount of ammo your player currently has
hp
(int): the amount of HP your player currently has
location
(tuple): your agent's location on the map, represented as (x,y)
reward
(int): the total score of your agent
power
(int): the blast-radius of the bombs placed by the player (default: 2)
The game will tick every 100ms and progress game_state
regardless of whether your Agent has returned its action or not within that time (i.e. it will not wait for your Agent). If your Agent takes more than 100ms to return its move, its action will be picked up on the next tick. This can therefore lead to an asynchronous situation between what your Agent thinks the current game_state
will be, versus what is actually happening.
To illustrate, here is what happens if your Agent returns its move within 100ms:
This is the behaviour you might expect.
Here is what can happen if your Agent takes more than 100ms to process its moves:
Here, you can see the asynchrony between your Agent and the Game. The action u
was issued after tick 2
, and will therefore be picked up by the Game in tick 3
. The game_state
your Agent observes in tick 2
will therefore show you what the Game looks like without u
having been executed yet. This is a limitation of how the game environment is set up to enable the game to progress without being stalled by any Agent in play.
On the first run the game will generate a default config file config.json
and store in the OS-specific configuration directory.
The default config.json
looks like this:
In your local development environment you have access to all config options, such as number of iterations the game runs (max_iterations
) or game update time step (tick_step
). However, these options are fixed in the tournament and can not be modified so please ensure your Agent works correctly with the default values.