Internal state¶
The state/ layer is the drone's memory: what it knows about itself (level,
inventory, food, position, orientation) and about its surroundings (the toroidal
mental map). It is fed by the update callbacks and consulted by
the strategy.
| Module | File | Role |
|---|---|---|
drone |
ai/src/state/drone.py |
DroneState: snapshot of the drone's state |
inventory |
ai/src/state/inventory.py |
Inventory helpers |
vision |
ai/src/state/vision.py |
Vision-cone geometry |
world_map |
ai/src/state/world_map.py |
Toroidal mental map |
DroneState — the drone's state¶
DroneState (ai/src/state/drone.py:28) is a @dataclass with a custom
__init__ (ai/src/state/drone.py:59). On construction it:
- sets
level = 1,inventory = {},food = 0; - places the position at the centre of the map:
pos = (W // 2, H // 2); - faces the drone
N; - builds its own
WorldMap(W, H); - immediately sends
InventorythenLook(ai/src/state/drone.py:76-86), each with its callback (update_inventory/update_vision).
self.pos = (world_map[0] // 2, world_map[1] // 2) # centre of the map
self.direction = "N"
self.world_map = WorldMap(world_map[0], world_map[1])
...
client.send_command(inventory(), lambda line: update_inventory(self, client, line))
client.send_command(look(), lambda line: update_vision(self, client, line))
Life methods¶
| Method | Definition | Meaning |
|---|---|---|
time_units_left() |
food * LIFE_PER_FOOD |
remaining life in TU (LIFE_PER_FOOD = 126, ai/src/config.py:18) |
is_starving(threshold) |
time_units_left() < threshold |
imminent starvation below a TU threshold |
is_dead() |
food <= 0 |
death by starvation |
The position is estimated
The server never returns the drone's absolute position. pos starts from
the assumed centre and is updated locally by the FSM on every move
(optimistic local state, see Strategy (FSM)).
inventory — inventory helpers¶
inventory.py (ai/src/state/inventory.py) provides high-level access over an
InventoryResult:
normalize_inventory(inv): a full dictionaryfood+ the 6 stones (absent ones coerced to 0);food_count(inv): the amount offood;stones_count(inv):{stone: quantity for stone in STONES}— always returns all 6 stones, an absent stone counting as 0.
vision — vision-cone geometry¶
At level n, the drone sees a cone of (n+1)² tiles. vision.py
(ai/src/state/vision.py) gives the formulas:
tiles_count_for_level(level)=(level + 1) ** 2(number of tiles seen);row_width_for_distance(distance)=2 * distance + 1(width of one row).
tile_index_to_relative_coord is a dead stub
tile_index_to_relative_coord (ai/src/state/vision.py:20) raises
NotImplementedError. The index → coordinate conversion geometry is in fact
re-implemented inline in WorldMap.update_from_look; this stub is never
called. See Known limitations.
WorldMap — toroidal mental map¶
WorldMap (ai/src/state/world_map.py) remembers the resources it has seen,
always working in wrapped coordinates (the world is a torus).
wrap(x, y)=(x % width, y % height): toroidal wrap.remember_tile,add_resource,remove_resource,get_resources_at: per-tile memory.nearest_food(from_pos)/nearest_resource(resource, from_pos): nearest known tile by toroidal distance (toric_distance,ai/src/strategy/pathfinding.py).
update_from_look — projecting vision onto the map¶
update_from_look(drone_pos, drone_direction, look_tiles)
(ai/src/state/world_map.py:97) is the heart of the memory: for each look
tile, it derives the relative offset then rotates it according to the
drone's orientation to obtain world coordinates, which it wraps and remembers:
for i, tile_objects in enumerate(look_tiles):
level = int(math.sqrt(i))
dx_rel = (i - level**2) - level
dy_rel = level
if drone_direction == "N": real_dx, real_dy = dx_rel, -dy_rel
elif drone_direction == "E": real_dx, real_dy = dy_rel, dx_rel
elif drone_direction == "S": real_dx, real_dy = -dx_rel, dy_rel
elif drone_direction == "W": real_dx, real_dy = -dy_rel, -dx_rel
tile_pos = (drone_pos[0] + real_dx, drone_pos[1] + real_dy)
self.remember_tile(tile_pos[0], tile_pos[1], tile_objects)
The look index i encodes the row (level = ⌊√i⌋) and the column; the
N/E/S/W rotation maps the drone's “front/left-right” frame into world frame.
display_map(pos) produces an ASCII debug grid.
The link with strategy¶
The update_from_look above is called by the FSM states, which re-inject
into the LookResult the position and orientation at the moment the Look
was issued (not at the moment the response arrives). This idea of optimistic
local state — updating pos/direction before the server confirms — is
detailed in Strategy (FSM).
Going further¶
- Protocol layer —
update_inventory/update_visionthat feed these fields. - Strategy (FSM) — optimistic local state and toroidal navigation.
- Known limitations — the
tile_index_to_relative_coordstub.