# Modo justo

> Um cliente injetado no jogo consegue ler o mapa inteiro. O modo justo faz o Bot enxergar só o que está na sua visão — como um jogador humano, e como na regra da Arena.

Fonte: https://war3ai.com/pt/docs/fair-mode/

A capacidade de observação deste projeto vem do fato de que “o cliente guarda o estado de todos os jogadores”: o snapshot traz todas as unidades do mapa inteiro, inclusive inimigos na névoa de guerra. Isso é ótimo para depurar, mas injusto numa competição.

O **modo justo** faz o SDK filtrar tudo pela sua visão:

```bash
python tools/play.py --bot my_bot.py --fair
python -m openwar3 run my_bot.py --inst 5 --fair
```

```python
from openwar3 import Game, run
g = Game(inst=5, fair=True)            # usando Game diretamente
run(MyBot, inst=5, fair=True)          # ou deixando com o executor
```

## O que é filtrado

| Conteúdo | No modo justo |
|---|---|
| Unidades | Todas as suas + as unidades inimigas e neutras que o seu lado vê neste momento |
| Itens no chão | Só os que estão na visão das suas unidades (visão de dia / de noite calculada separadamente, pela tabela de dados) |
| Tabela de produção | Só construções visíveis (você não vê o que o adversário está treinando) |
| Eventos | Os seus; os visíveis (ou vistos no último 1 segundo); o dano causado pelo seu lado |

## De onde vem a visão

- Cada unidade no snapshot traz uma **máscara de visibilidade**: bit p = o jogador p a vê neste momento (só contam os jogadores 0 ~ 11 com unidades em campo; suas próprias unidades são sempre visíveis para você). `u.visible_to(g.me())` lê isso direto, sem espera.
- Para qualquer ponto: `g.visible(x, y)` pergunta ao motor (visível / névoa de guerra / máscara preta), pela via rápida, cerca de um frame por chamada. Quando precisar checar muitas unidades num tick, use `u.visible_to()` do snapshot em vez de chamar `g.visible()` uma a uma.

## A memória dos inimigos: `last_seen`

Um jogador humano lembra que “agora há pouco viu um grupo de Wolf Riders ali”. O SDK também lembra por você: a cada atualização do snapshot, registra as unidades inimigas e os creeps que o seu lado vê naquele momento (última posição, vida, tempo); quando vê um deles morrer, apaga o registro; ao trocar de partida, limpa tudo.

```python
for u, t, age in g.last_seen(max_age=60):         # inimigos vistos nos últimos 60 segundos de jogo
    print(u.type, u.x, u.y, f"há {age:.0f}s")

heroes = [r for r in g.last_seen() if r[0].is_hero]   # onde os heróis inimigos estavam da última vez
camps  = g.last_seen(owner="creep")                   # creeps já vistos
```

No modo justo, esta é a sua única “fonte de informação sobre o adversário” — como para um jogador humano. O modo normal também registra pela visão, então o mesmo código serve para os dois.

## Comandar como um jogador específico

```bash
python tools/play.py --bot my_bot.py --player 1 --attach
```

`--player N` (ou `Game(player=N)`) faz o Bot comandar como o jogador N, e ele só pode comandar unidades do jogador N. Duas IAs se enfrentando são dois canais desses na mesma partida.

> **No modo local, o jogo limpo é um acordo, não uma barreira de segurança**
>
> Na sua própria máquina, não há como impedir um programa de ler o mapa inteiro. `--fair` é uma restrição que você impõe a si mesmo; partidas de verdade são garantidas pelo processo árbitro da [Arena](https://war3ai.com/pt/arena/): o Bot nunca toca na memória compartilhada, só recebe as observações que o árbitro filtrou pela visão, só pode enviar ações, e cada ação tem a propriedade das unidades verificada antes.

## Por que ativar desde já

- Quando você for para a Arena, a regra vai ser esta; escrevendo para o modo justo agora, você não vai precisar mudar uma linha depois;
- Só sem a informação do mapa inteiro você descobre o nível real do seu Bot (hoje, o cérebro de referência depende muito da informação do mapa inteiro, como o ponto-alvo do capitão do computador — e isso é um bom teste);
- Reconhecimento, memória e julgamento escritos no modo justo são a capacidade de IA que realmente tem valor.
