État interne¶
La couche state/ est la mémoire du drone : ce qu'il sait de lui-même
(niveau, inventaire, food, position, orientation) et de son environnement (la
carte mentale torique). Elle est alimentée par les
callbacks de mise à jour et consultée par la
stratégie.
| Module | Fichier | Rôle |
|---|---|---|
drone |
ai/src/state/drone.py |
DroneState : photographie de l'état du drone |
inventory |
ai/src/state/inventory.py |
Helpers d'inventaire |
vision |
ai/src/state/vision.py |
Géométrie du champ de vision |
world_map |
ai/src/state/world_map.py |
Carte mentale torique |
DroneState — l'état du drone¶
DroneState (ai/src/state/drone.py:28) est un @dataclass doté d'un
__init__ personnalisé (ai/src/state/drone.py:59). À la construction, il :
- pose
level = 1,inventory = {},food = 0; - place la position au centre de la carte :
pos = (W // 2, H // 2); - oriente le drone au
N; - construit sa propre
WorldMap(W, H); - envoie immédiatement
InventorypuisLook(ai/src/state/drone.py:76-86), chacun avec son callback (update_inventory/update_vision).
self.pos = (world_map[0] // 2, world_map[1] // 2) # centre de la carte
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))
Méthodes de vie¶
| Méthode | Définition | Sens |
|---|---|---|
time_units_left() |
food * LIFE_PER_FOOD |
TU de vie restants (LIFE_PER_FOOD = 126, ai/src/config.py:18) |
is_starving(threshold) |
time_units_left() < threshold |
famine imminente sous un seuil en TU |
is_dead() |
food <= 0 |
mort par famine |
La position est estimée
Le serveur ne renvoie jamais la position absolue du drone. pos part du
centre supposé et est mise à jour localement par la FSM à chaque
déplacement (état local optimiste, cf. Stratégie (FSM)).
inventory — helpers d'inventaire¶
inventory.py (ai/src/state/inventory.py) fournit des accès de haut niveau sur
un InventoryResult :
normalize_inventory(inv): dictionnaire completfood+ les 6 pierres (absentes ramenées à 0) ;food_count(inv): quantité defood;stones_count(inv):{pierre: quantité for pierre in STONES}— renvoie toujours les 6 pierres, une pierre absente valant 0.
vision — géométrie du champ de vision¶
Au niveau n, le drone voit un cône de (n+1)² tuiles. vision.py
(ai/src/state/vision.py) en donne les formules :
tiles_count_for_level(level)=(level + 1) ** 2(nombre de tuiles vues) ;row_width_for_distance(distance)=2 * distance + 1(largeur d'une rangée).
tile_index_to_relative_coord est un stub mort
tile_index_to_relative_coord (ai/src/state/vision.py:20) lève
NotImplementedError. La géométrie de conversion index → coordonnée est en
fait réimplémentée en ligne dans WorldMap.update_from_look ; ce stub
n'est jamais appelé. Voir Limitations connues.
WorldMap — carte mentale torique¶
WorldMap (ai/src/state/world_map.py) mémorise les ressources aperçues, en
travaillant systématiquement en coordonnées wrappées (le monde est un tore).
wrap(x, y)=(x % width, y % height): repli torique.remember_tile,add_resource,remove_resource,get_resources_at: mémoire par tuile.nearest_food(from_pos)/nearest_resource(resource, from_pos): tuile connue la plus proche selon la distance torique (toric_distance,ai/src/strategy/pathfinding.py).
update_from_look — projeter la vision sur la carte¶
update_from_look(drone_pos, drone_direction, look_tiles)
(ai/src/state/world_map.py:97) est le cœur de la mémoire : pour chaque tuile du
look, il déduit son décalage relatif puis le fait pivoter selon
l'orientation du drone pour obtenir des coordonnées monde, qu'il wrap et
mémorise :
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)
L'index i du look encode la rangée (level = ⌊√i⌋) et la colonne ; la
rotation N/E/S/W transpose le repère « devant/gauche-droite » du drone en repère
monde. display_map(pos) produit une grille ASCII de débogage.
Le lien avec la stratégie¶
L'update_from_look ci-dessus est appelé par les états de la FSM, qui
réinjectent dans le LookResult la position et l'orientation du moment où
le Look a été émis (et non du moment où la réponse arrive). Cette idée
d'état local optimiste — mettre à jour pos/direction avant la
confirmation serveur — est détaillée dans Stratégie (FSM).
Pour aller plus loin¶
- Couche protocole —
update_inventory/update_visionqui alimentent ces champs. - Stratégie (FSM) — état local optimiste et navigation torique.
- Limitations connues — stub
tile_index_to_relative_coord.