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.
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:
python tools/play.py --bot my_bot.py --fair
python -m openwar3 run my_bot.py --inst 5 --fair
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, useu.visible_to()do snapshot em vez de chamarg.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.
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
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: 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.