# Las quince reglas

> Cada una se aprendió a base de errores en partidas reales. Repásalas al escribir un Bot y te ahorrarás la mayor parte de la depuración.

Fuente: https://war3ai.com/es/docs/rules/

> **Consejo**
>
> Dale esta página junto con [`api.json`](https://war3ai.com/es/api.json) a un LLM y el Bot que escriba dará muchos menos rodeos.

## Leer el estado

### 1. Lo que no se puede leer es `None`, no 0

`resources()`, `time_of_day()`, `production()` y `cooldown()` pueden devolver `None` (cargando, la unidad no tiene detalle, el edificio no está produciendo…). Compruébalo antes de usarlo:

```python
res = g.resources()
if res is None:
    return
```

### 2. Identifica las unidades por handle, no por dirección

Las direcciones se reutilizan para unidades nuevas: una dirección antigua puede acabar apuntando a una unidad recién creada. Para recordar una unidad entre ticks, guarda `u.handle` y recupérala con `g.unit(handle)`.

### 3. El flujo de eventos es global

`production.done` y `unit.died` incluyen también los del rival y los de los creeps. Filtra por `ev.owner` (o por el handle del edificio):

```python
if ev.kind == "production.done" and ev.owner == g.me():
    ...
```

### 4. Los trabajadores dentro de una mina de oro no están en el snapshot

Cuando un trabajador entra en la mina desaparece del snapshot (`unit.removed`, no ha muerto). Para contar cuántos hay en cada mina, **lleva tu propia cuenta** y no la recortes según el snapshot; si no, mandarás más gente a minas que ya están llenas.

## Dar comandos

### 5. Recibo "aceptado" ≠ hecho

El motor acepta al momento incluso un punto de construcción dentro de un bosque; falla cuando llega el trabajador. Las habilidades pueden interrumpirse. El efecto se ve en el snapshot y en los eventos: para construir, usa `build_near` (comprueba si aparecen los cimientos) y, para los hechizos, mira si `g.cooldown()` ha entrado en enfriamiento.

### 6. No se puede atacar lo que no se ve

Un comando con objetivo sobre un enemigo en la niebla se rechaza con el código de motivo **1001**. Para perseguir a un enemigo en la niebla, usa `attack_move` hacia la última posición donde se le vio.

### 7. Da órdenes solo a las unidades ociosas

Repetir el mismo comando a la misma unidad en cada tick la interrumpe: las tropas se quedan temblando en el sitio y el ciclo de recolección de los trabajadores vuelve a cero. Para saber si una unidad está "ociosa", usa `g.order_of(u)` (incluye lo que acabas de ordenar en este tick), no `u.order` del snapshot (el snapshot aún no se ha puesto al día).

### 8. Shift solo "inserta después de la orden actual"

El motor no tiene "añadir al final": si envías B y C seguidos con `queue='after'`, obtienes A, C, B. Para recorrer una serie de puntos en orden, usa `g.path(units, puntos)`, y para que un trabajador construya varios edificios seguidos, `g.build_queue(worker, plan)`: ambos insertan en orden inverso y lo resuelven por ti.

### 9. Los comandos de un tick, en un solo lote

Enviar decenas de comandos uno a uno supone esperar decenas de veces al hilo del juego; dentro de `with g.batch():` solo se espera una vez.

## Economía y producción

### 10. Como máximo 5 trabajadores por mina

Más no aumenta los ingresos. El objetivo de trabajadores depende del número de minas: 5 al oro por mina, más unos cuantos a la madera.

### 11. Solo 1 en la cola de entrenamiento

Llenar los 7 huecos deja el dinero bloqueado en la cola (en una prueba, el ayuntamiento tenía 4 campesinos en cola y 300 de oro bloqueado, y el inicio de partida fue mucho más lento). Pon el siguiente cuando `g.queue(b)` esté vacía.

### 12. Si falta comida, mira la tabla de producción

`g.production(b).blocked` = hay algo en cola pero no ha empezado; casi siempre, por falta de comida. Va un paso por delante de "construir cuando la comida esté casi al límite": si pierdes un montón de tropas en un combate y la cola se atasca al reponerlas, lo sabes al instante.

### 13. El héroe es único, y sin la cola del ayuntamiento vacía no se sube de tier

- Si el héroe muere, solo puedes usar `g.revive(altar)`; entrenar otro se rechaza (221). Revivir también requiere comida (un héroe ocupa 5).
- No se puede mejorar el ayuntamiento mientras quede algo en su cola (código de motivo 185, "edificio ocupado").

## Tiempo y espacio

### 14. A velocidad 2× no esperes según el reloj real

Para esperar 3 segundos de juego, comprueba que `g.clock()` haya avanzado 3; no uses `sleep(1.5)`. Con la velocidad aumentada, el reloj del motor avanza más rápido que el reloj real.

### 15. En mapas con islas o bosques, no uses la distancia en línea recta

Para elegir campamentos de creeps o expansiones, usa `g.path_distance(a, b)` (A* por tierra, rodeando bosques, acantilados y edificios); si no hay camino, devuelve `None`. El punto más cercano en línea recta puede estar al otro lado del mar.

## Una más: escribe en modo justo

Con `--fair` solo se ven las unidades, objetos, producción y eventos dentro de tu visión; es la regla de la Arena. Si escribes ya en modo justo, no tendrás que cambiar nada para la [Arena](https://war3ai.com/es/arena/). Más detalles en [Modo justo](https://war3ai.com/es/docs/fair-mode/).
