Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.battlecode.cam/llms.txt

Use this file to discover all available pages before exploring further.

The Controller object is passed to your Player.run() method each round. It provides all queries and actions for interacting with the game.
class Player:
    def run(self, c: Controller):
        # c is the Controller for this unit
        pos = c.get_position()

Info methods

Unit info

get_team(id: int | None = None)
Team
Return the team of the entity with the given id, or this unit if omitted.
get_position(id: int | None = None)
Position
Return the position of the entity with the given id, or this unit if omitted.
get_id()
int
Return this unit’s entity id.
get_action_cooldown()
int
Return this unit’s current action cooldown. Actions require cooldown == 0.
get_move_cooldown()
int
Return this unit’s current move cooldown. Movement requires cooldown == 0.
get_hp(id: int | None = None)
int
Return the current HP of the entity with the given id, or this unit if omitted.
get_max_hp(id: int | None = None)
int
Return the max HP of the entity with the given id, or this unit if omitted.
get_entity_type(id: int | None = None)
EntityType
Return the EntityType of the entity with the given id, or this unit if omitted.
get_direction(id: int | None = None)
Direction
Return the facing direction of a conveyor, splitter, armoured conveyor, or turret. Raises GameError if the entity has no direction.
get_vision_radius_sq(id: int | None = None)
int
Return the vision radius squared of the given unit, or this unit if omitted.

Turret info

get_ammo_amount()
int
Return the amount of ammo this turret currently holds.
get_ammo_type()
ResourceType | None
Return the resource type loaded as ammo, or None if empty.
get_gunner_target()
Position | None
Return the closest targetable occupied tile on the gunner’s forward line, or None if none exists. Empty tiles are skipped. Markers are targetable but do not block farther legal targets. Walls block the line but are not targetable. Builder bots and non-marker buildings are both targetable and blocking, so if either appears first it is returned and nothing beyond it is legal. Only valid on gunners.
get_attackable_tiles()
list[Position]
Return this turret’s raw geometric attack pattern as list[Position]. This ignores ammo, cooldown, occupancy, blockers, and any other legality checks. For gunners, this is the full forward ray up to range, including tiles behind walls. For sentinels, this is the full +/-1 band around the forward line within vision radius squared 32. For breaches, this is the forward 180-degree cone within distance squared 24. For launchers, this is every in-bounds tile with 0 < distance^2 <= 26. Raises GameError if this unit is not a turret.
get_attackable_tiles_from(position: Position, direction: Direction, turret_type: EntityType)
list[Position]
Return the same raw geometric attack pattern for a hypothetical turret at position. This can be called from any controller and does not check whether a turret exists there, whether it could legally be built there, or whether the tile is occupied. If position is out of bounds, returns []. In Python, turret_type must be one of EntityType.GUNNER, EntityType.SENTINEL, EntityType.BREACH, or EntityType.LAUNCHER; any other EntityType raises ValueError. direction is ignored for launchers.

Building info

get_bridge_target(id: int)
Position
Return the output target position of a bridge. Raises GameError if not a bridge.
get_stored_resource(id: int | None = None)
ResourceType | None
Return the resource stored in a conveyor/splitter/armoured conveyor/bridge/foundry, or None if empty. Raises GameError if the entity has no storage.
get_stored_resource_id(id: int | None = None)
int | None
Return the id of the resource stack stored in a conveyor/splitter/armoured conveyor/bridge/foundry, or None if empty. Raises GameError if the entity has no storage.

Tile queries

get_tile_env(pos: Position)
Environment
Return the environment type (empty, wall, ore) of the tile at pos.
get_tile_building_id(pos: Position)
int | None
Return the id of the building on the tile at pos, or None if empty.
get_tile_builder_bot_id(pos: Position)
int | None
Return the id of the builder bot on the tile at pos, or None if empty.
is_tile_empty(pos: Position)
bool
Return True if the tile has no building and is not a wall.
is_tile_passable(pos: Position)
bool
Return True if a builder bot belonging to this team could stand on the tile. A tile is passable when it contains a walkable building (conveyor, splitter, armoured conveyor, bridge, or road) or an allied core, and no builder bot is already present.
is_in_vision(pos: Position)
bool
Return True if pos is within this unit’s vision radius.

Nearby queries

get_nearby_tiles(dist_sq: int | None = None)
list[Position]
Return all in-bounds tile positions within dist_sq of this unit (defaults to vision radius). dist_sq must not exceed the vision radius.
get_nearby_entities(dist_sq: int | None = None)
list[int]
Return ids of all entities on tiles within dist_sq (defaults to vision radius).
get_nearby_buildings(dist_sq: int | None = None)
list[int]
Return ids of all buildings within dist_sq (defaults to vision radius).
get_nearby_units(dist_sq: int | None = None)
list[int]
Return ids of all units within dist_sq (defaults to vision radius).

Map and game state

get_map_width()
int
Return the width of the map in tiles.
get_map_height()
int
Return the height of the map in tiles.
get_current_round()
int
Return the current round number (starts at 1).
get_global_resources()
tuple[int, int]
Return (titanium, axionite) in this team’s global resource pool.
get_scale_percent()
float
Return this team’s current cost scale as a percentage (100.0 = base cost).
get_unit_count()
int
Return the number of living units currently on your team, including the core.
get_cpu_time_elapsed()
int
Return the CPU time elapsed this round in microseconds.

Cost getters

Every buildable entity has a cost getter that returns the current scaled (titanium, axionite) cost:
c.get_conveyor_cost()           # -> (int, int)
c.get_splitter_cost()
c.get_bridge_cost()
c.get_armoured_conveyor_cost()
c.get_harvester_cost()
c.get_road_cost()
c.get_barrier_cost()
c.get_gunner_cost()
c.get_sentinel_cost()
c.get_breach_cost()
c.get_launcher_cost()
c.get_foundry_cost()
c.get_builder_bot_cost()

Movement

move(direction: Direction)
None
Move this builder bot one step in direction. Raises GameError if not legal.
can_move(direction: Direction)
bool
Return True if this builder bot can move in direction this round.

Building

Every buildable entity has can_build_* and build_* methods. All require action cooldown == 0 and sufficient resources. The can_build_* variants return bool; build_* returns the new entity’s int id or raises GameError if not legal. If a can_build_* method would create a living unit, it also accounts for the global unit cap. If a tile already contains a builder bot, only walkable buildings (conveyors and roads) may be built on that tile.

Directional buildings

These take (position: Position, direction: Direction) — the direction the building faces:
c.build_conveyor(pos, direction)          c.can_build_conveyor(pos, direction)
c.build_splitter(pos, direction)          c.can_build_splitter(pos, direction)
c.build_armoured_conveyor(pos, direction) c.can_build_armoured_conveyor(pos, direction)
c.build_gunner(pos, direction)            c.can_build_gunner(pos, direction)
c.build_sentinel(pos, direction)          c.can_build_sentinel(pos, direction)
c.build_breach(pos, direction)            c.can_build_breach(pos, direction)

Bridge

Takes (position: Position, target: Position) — the bridge’s output target tile (within distance² 9):
c.build_bridge(pos, target)               c.can_build_bridge(pos, target)

Non-directional buildings

Take only (position: Position):
c.build_harvester(pos)                    c.can_build_harvester(pos)
c.build_road(pos)                         c.can_build_road(pos)
c.build_barrier(pos)                      c.can_build_barrier(pos)
c.build_foundry(pos)                      c.can_build_foundry(pos)
c.build_launcher(pos)                     c.can_build_launcher(pos)

Generic build

A single pair of methods that dispatches to the correct type-specific builder. Use these when the entity type is determined at runtime.
can_build(entity_type: EntityType, position: Position, extra: Direction | Position | None = None)
bool
Return True if entity_type can be built at position. For directional buildings and turrets (conveyor, splitter, armoured_conveyor, gunner, sentinel, breach), extra must be a Direction. For bridges, extra must be the target Position. For all other types (harvester, road, barrier, launcher, foundry), extra is unused.
build(entity_type: EntityType, position: Position, extra: Direction | Position | None = None)
int
Build entity_type at position. Returns the new entity’s id. The extra parameter follows the same rules as can_build(). Raises GameError if not legal.

Healing & destruction

heal(position: Position)
None
Heal all friendly entities on a tile within this builder bot’s action radius by 4 HP. If both a friendly builder bot and a friendly building share the tile, both are healed. Costs 1 titanium and one action cooldown. Raises GameError if not legal.
can_heal(position: Position)
bool
Return True if this builder bot can heal the tile at position this round. Position must be within the builder bot’s action radius. Requires action cooldown == 0, enough titanium, and at least one damaged friendly entity on the tile.
destroy(building_pos: Position)
None
Destroy the allied building at building_pos. Does not cost action cooldown.
can_destroy(building_pos: Position)
bool
Return True if this builder bot can destroy the allied building.
self_destruct()
None
Destroy this unit. Builder bots no longer deal damage on self-destruct. Terminates this unit’s execution immediately — no code after self_destruct() will run.
resign(message: str | None = None)
None
Forfeit the game immediately. Destroys this team’s core, ending the game as a loss. Terminates this unit’s execution immediately — no code after resign() will run.The optional message (max 500 characters) is saved to the replay and displayed in match results.

Markers

place_marker(position: Position, value: int)
None
Place a marker with the given u32 value. Does not cost action cooldown. Max one per round.
can_place_marker(position: Position)
bool
Return True if this unit can place a marker at position this round.
get_marker_value(id: int)
int
Return the u32 value stored in the friendly marker.

Combat

fire(target: Position)
None
Fire this turret at target, or perform the builder bot’s own-tile attack. Builder bots spend 2 titanium to deal 2 damage to the building on their current tile. Gunners use first-obstruction line of sight: empty tiles and markers do not block, markers are targetable, walls block but are not targetable, and builder bots plus non-marker buildings are both targetable and blocking. If a turret attacks a tile containing both a building and a builder bot, only the builder bot is hit. Use launch() for launchers.
can_fire(target: Position)
bool
Return True if this turret can fire at target this round, or if this builder bot can use its own-tile attack on target. Gunners use the same first-obstruction line of sight as fire(): empty tiles and markers do not block, markers are targetable, walls block but are not targetable, and builder bots plus non-marker buildings are both targetable and blocking.
can_fire_from(position: Position, direction: Direction, turret_type: EntityType, target: Position)
bool
Return whether a hypothetical turret at position would have a legal shot at target on the current map. This treats position as the turret’s tile and uses current map occupancy and walls, but ignores ammo, cooldown, whether a real turret is present, and whether one could legally be built there. If either position or target is out of bounds, returns False. For sentinels and breaches, this is only a geometric range/shape check. For launchers, this is only the raw throw-range check 0 < distance^2 <= 26; it does not check pickup adjacency, whether a builder bot exists, or whether the destination is bot-passable. direction is ignored for launchers.
can_rotate(direction: Direction)
bool
Return whether rotate(direction) would be legal this round. This returns False if the current unit is not a gunner, if direction is Direction.CENTRE, if direction is the gunner’s current facing direction, if the gunner cannot act this turn, or if the team cannot afford the global 10 Ti rotate cost. Unlike rotate(), this does not raise on non-gunners.
rotate(direction: Direction)
None
Rotate this gunner to face direction. Costs 10 titanium from the global resource pool and applies a 1-turn cooldown. Raises GameError if not legal. Only valid on gunners.
launch(bot_pos: Position, target: Position)
None
Pick up the builder bot at bot_pos and throw it to target.
can_launch(bot_pos: Position, target: Position)
bool
Return True if this launcher can pick up and throw the bot.

Core

convert(amount: int)
None
Convert amount refined axionite from this team’s global resource pool into titanium at a rate of 1 Ax to 4 Ti. Converted axionite is removed from the Ax collected stat and added to the Ti collected stat. Raises GameError if not legal. Only valid on cores.
spawn_builder(position: Position)
int
Spawn a builder bot on one of the 9 core tiles. Costs one action cooldown and requires room under the global unit cap. Returns the new entity’s id.
can_spawn(position: Position)
bool
Return True if the core can spawn a builder at position this round, including the unit-cap check.

Debug indicators

draw_indicator_line(pos_a: Position, pos_b: Position, r: int, g: int, b: int)
None
Draw a debug line between two positions with RGB colour. Saved to the replay.
draw_indicator_dot(pos: Position, r: int, g: int, b: int)
None
Draw a debug dot at a position with RGB colour. Saved to the replay.