# Accusés de réception et codes de raison

> Chaque accusé de réception de commande porte un code d’état et un code de raison. C’est sur eux que les Bots et les agents s’appuient pour se corriger : le « pourquoi ça n’a pas marché » devient un nombre lisible par une machine.

Source: https://war3ai.com/fr/docs/reason-codes/

```python
r = g.train(barracks, "hfoo")
bool(r)        # False
r.status       # 1              -> rejected
r.verdict      # 3              -> nourriture insuffisante
r.reason       # 'rejected（人口不够）'  (= nourriture insuffisante)
r.exec_us      # durée d'exécution de cette commande sur le thread du jeu, en microsecondes
```

`if r:` équivaut à `r.status == 0` (le moteur a accepté).

## Code d’état `status`

| Code | Nom | Signification | Causes fréquentes |
|---|---|---|---|
| 0 | `accepted` | Accepté par le moteur | — (mais accepté ≠ réussi, voir plus bas) |
| 1 | `rejected` | Refusé par le moteur | Voir `verdict` |
| 2 | `bad_unit` | L’unité n’existe pas ou le handle ne correspond pas | Unité déjà morte ; objet unité périmé |
| 3 | `not_owner` | Ce n’est pas votre unité | Ordres donnés aux unités d’un autre joueur en tant que `player` |
| 4 | `fault` | Exception à l’exécution (interceptée par le runtime, sans conséquence pour le jeu) | Signalez-la avec les étapes pour la reproduire |
| 5 | `bad_args` | Paramètres invalides | Coordonnées, numéro de case ou code à quatre caractères erroné |
| 6 | `unsupported` | Non pris en charge | Cette version du runtime n’a pas cette capacité |
| 7 | `bad_target` | Cible invalide | La cible n’existe plus ; mauvais type de cible |
| 8 | `forbidden` | Interdit par le rôle de la voie | Ordre donné en tant qu’`observer` |
| 97 | `cancelled` | Exception levée dans le bloc de lot : aucune commande du lot n’a été envoyée | Erreur dans le code du bloc `with g.batch():` |
| 98 | `held` | Unité tenue par une couche plus prioritaire : commande non envoyée | La couche réflexe du cerveau de référence ou un ordre manuel de la console tient cette unité |
| 99 | `timeout` | Délai dépassé | Échéance dépassée pendant une pause ou un ralentissement du jeu (une commande expirée n’est jamais exécutée) |

## Code de raison `verdict`

En cas de refus, le runtime en donne la raison à l’aide des propres contrôles de faisabilité du moteur. Vous pouvez aussi poser la question avant de donner l’ordre : `g.can_do(unité, code)` renvoie les mêmes codes.

| Code | Signification | Que faire |
|---|---|---|
| 0 / 220 | Possible | — |
| 3 | Nourriture insuffisante | Construire un bâtiment de nourriture ; repérer le blocage à l’avance avec `g.production(b).blocked` |
| 8 | Or insuffisant | Attendre l’argent ; vérifier avec `g.can_afford(code)` avant de donner l’ordre |
| 9 | Bois insuffisant | Envoyer plus d’ouvriers au bois |
| 32 | File d’entraînement pleine (7 places) | Une seule unité en file : n’en ajouter une que lorsque `g.queue(b)` est vide |
| 183 | Technologie / bâtiment prérequis manquant | Construire d’abord le bâtiment prérequis, monter de tier |
| 185 | Bâtiment occupé | L’autel est en train de ressusciter un héros ; impossible d’améliorer le bâtiment principal tant que sa file n’est pas vide |
| 221 | Élément inexistant / en construction / en amélioration / déjà présent | Le héros existe déjà (s’il est mort, utilisez `revive`) ; cette boutique ne vend pas cet objet |
| 89 | Boutique pas encore approvisionnée | En début de partie, les objets arrivent selon le délai de mise en vente de la table des objets ; pour une boutique qu’on vient de construire, le compte démarre à la fin de la construction |
| 1001 | Cible invisible | La cible est dans le brouillard de guerre ou le masque noir ; faites un `attack_move` vers sa position |

## Accepté ≠ réussi

L’accusé de réception indique seulement que « le moteur a accepté la commande » ; il est relu dans la même frame. Il ne couvre pas ce qui peut se produire ensuite :

| Commande | Peut encore échouer après acceptation | Comment vérifier |
|---|---|---|
| Construire | Un point en pleine forêt est lui aussi accepté sur le moment ; l’échec ne survient qu’à l’arrivée de l’ouvrier | Utiliser `build_near` (qui vérifie que les fondations apparaissent), ou attendre `production.done` |
| Lancer un sort | Sort interrompu, mana insuffisant | Au tick suivant, vérifier que `g.cooldown(u, sort)` est bien en recharge |
| Entraîner | Placé en file, mais faute de nourriture ne démarre jamais | `g.production(b).blocked` |
| Déplacer / attaquer | Remplacé par une autre logique (ou par une couche plus prioritaire) | `g.current_target(u)`, `g.order_of(u)` |

## Interfaces de requête

Ces interfaces ne donnent aucun ordre, elles ne font qu’interroger le moteur ; le résultat est placé dans le champ `value` de l’accusé de réception (le SDK renvoie directement la valeur) :

| Interface | Renvoie |
|---|---|
| `g.can_do(u, code)` / `g.can_do_many([(u, code), ...])` | Le code de raison du tableau ci-dessus |
| `g.tech(code, player=None)` / `g.tech_many([...])` | Niveau de recherche / nombre de bâtiments terminés (chaîne d’amélioration comprise) |
| `g.visible(x, y)` | Ce point est-il visible pour votre camp |
| `g.gold_left(mine)` | Quantité d’or restant dans la mine |
| `g.enemy_ai_plan(unité_ennemie)` | Où le capitaine de l’IA de l’ordinateur compte emmener ses troupes (uniquement pour l’IA de l’ordinateur) |
