Dicas e estratégias
Como ganhar
Um robô simples que sobrevive vence um robô sofisticado que morre cedo. Esta página reúne o que funciona, o que não funciona, e o que fazer quando aparece um erro na tela.
Atalhos: As cinco regras de ouro · Táticas · Armadilhas · Deu erro, e agora? · Checklist final
As cinco regras de ouro
Sobreviver vale mais do que eliminar
A pontuação é dada pela ordem de sobrevivência. Eliminações só desempatam. Um robô que corre, desvia e atira pouco costuma somar mais pontos ao longo das 5 partidas do que um robô agressivo que se expõe. Quando estiver em dúvida entre atacar e fugir, fuja.
Nunca fique parado
Robô parado é alvo fácil, e a arena ainda pune inatividade tirando vida, com a penalidade contando contra você no desempate. Não existe a estratégia de esperar os outros se matarem. Se o seu robô não tem o que fazer, que ele pelo menos ande em círculos ou gire o radar.
Parede é inimiga
Cada encostada custa 1 de vida, descarta o seu plano e trava o robô por alguns instantes num lugar previsível. Um robô que fica raspando a parede sangra sozinho. Mantenha uma margem de segurança (o RoboCacador usa 90 pixels) e vire antes de bater, não depois.
Trave o radar na arma
self.lockRadar("gun") no init(). É uma linha, e ela resolve
o problema mais difícil do jogo: tudo que o radar enxerga já está na mira, então basta
atirar. Sem isso, você tem que calcular ângulos para acertar qualquer coisa.
Simples e funcionando ganha de complexo e quebrado
Você tem algumas horas. Um robô que anda, enxerga e atira já compete. Faça uma melhoria de cada vez e teste depois de cada uma. Se a mudança piorou, desfaça na hora. Não acumule três mudanças sem testar, porque aí não dá para saber qual estragou.
Táticas que funcionam
Movimento imprevisível
Robôs que andam em linha reta são fáceis de acertar. Robôs que mudam de direção com frequência, não. Algumas ideias baratas:
- Alternar entre andar para a frente e de ré.
- Trocar o ângulo de curva a cada volta em vez de usar sempre 90 graus.
- Sortear a distância de cada trecho com
random.randint(40, 120), lembrando de colocarimport randomno topo.
Reagir a levar tiro
Este é o retorno mais alto por linha escrita no jogo inteiro. Se você levou um tiro, alguém está com a arma apontada para você e vai atirar de novo no mesmo lugar. Saia dali:
def onHitByBullet(self, bulletBotId, bulletBotName, bulletPower):
self.reset()
self.move(100)
self.turn(60)
Escolher a potência pela distância
Pela matemática do tiro, acertar dá lucro e errar dá prejuízo. Então: perto, onde é difícil errar, vale o tiro caro; longe, onde é fácil errar, tiro barato.
distancia = math.sqrt(dx * dx + dy * dy)
if distancia < 150:
self.fire(5)
elif distancia < 300:
self.fire(3)
elif distancia < 450:
self.fire(1)
# mais longe que isso, nem vale a pena atirar
Mudar de comportamento conforme a vida
Com vida cheia, dá para arriscar. Com vida baixa, cada ponto conta, e como a pontuação premia sobrevivência, fugir passa a ser a jogada certa.
if self.getHealth() < 30:
self.modo = "fuga" # anda mais, atira menos
else:
self.modo = "caca"
Ficar mais agressivo no fim
Quando sobra só um adversário, não há mais ninguém para gastar a vida dele. Aí vale partir para cima.
adversarios = len(self.getEnemiesLeft()) - 1
if adversarios == 1:
self.rPrint("Mano a mano")
Escolher o radar certo
| Se a sua estratégia é... | Use | Porque |
|---|---|---|
| Franco-atirador, atirando de longe | "thin" | Enxerga do outro lado da arena |
| Andar rápido e não ser surpreendido | "large" | Varre muita área ao redor |
| Brigar colado no adversário | "round" | Enxerga nos 360 graus, mas só de perto |
| Não sei ainda | "normal" | É o padrão e é equilibrado |
Armadilhas comuns
Congela o jogo inteiro. O run() já é o laço do robô: o
jogo o chama de novo sozinho toda vez que a fila de comandos esvazia. Nunca coloque um
laço infinito ali dentro.
self.move(400) deixa o robô ocupado por 80 quadros, sem tomar nenhuma
decisão nesse tempo. Prefira vários comandos curtos: o robô reage mais rápido ao que
acontece.
Sem stop(), tudo acontece ao mesmo tempo. Se você queria "anda e
depois vira" mas escreveu os dois no mesmo bloco, o robô faz uma curva aberta
e vai parar em outro lugar.
A lista inclui o seu próprio robô. Se você testar
== 1 achando que sobrou um adversário, na verdade sobrou só você, e a
partida já acabou. Sempre subtraia 1.
Aponta para baixo. E o y cresce para baixo também. Veja
a bússola da arena antes de escrever qualquer conta
com ângulo.
Deu erro, e agora?
As mensagens de erro aparecem na janela de baixo do PyCharm (a aba Run). Elas são feias, mas a última linha quase sempre diz o que houve.
| Sintoma | Causa provável | Como resolver |
|---|---|---|
| O robô não aparece na lista de seleção | Arquivo fora de Robots/, não salvo, ou com erro de código |
Confira a pasta, salve com Ctrl+S e procure na aba Run a linha Problem with bot file |
IndentationError |
Espaços errados no começo de uma linha | Todo comando fica 4 espaços à direita de class, e o conteúdo dele 4 à direita do def. Nunca misture Tab com espaço. |
SyntaxError |
Falta dois-pontos, parêntese ou aspas | Olhe a linha indicada e a de cima, porque o erro costuma estar na anterior |
NameError |
Nome escrito diferente de onde foi criado | Python diferencia maiúsculas de minúsculas: Passo e passo são coisas distintas |
AttributeError |
Comando que não existe, ou nome digitado errado | Confira na referência. Repare que os nomes têm maiúscula no meio: gunTurn, não gunturn |
TypeError: can only concatenate str |
Somando texto com número no rPrint |
Envolva o número com str(): "vida: " + str(self.getHealth()) |
| A janela do jogo fecha sozinha no meio da partida | Erro dentro de um evento, ou um evento obrigatório faltando | Leia a aba Run: o nome do evento problemático estará lá. Compare com o RoboMinimo, que tem os onze. |
| O robô anda para o lado errado | Confusão com a bússola | Ângulo 0 é para baixo. Veja a bússola. |
| O robô nunca atira | O radar não está encontrando ninguém | Ligue self.radarVisible(True) e veja o cone na tela. Se ele não está varrendo, falta girar o radar ou a arma no run(). |
| O robô fica girando no lugar sem sair | O run() gira mas nunca anda, ou o onHitWall devolve ele para a parede |
Use rPrint para ver por onde o código está passando |
| Mudei o código mas nada mudou | O jogo carregou a versão antiga | Salve, feche a janela do jogo e rode o main.py de novo |
Espalhe self.rPrint("cheguei aqui") pelo código, rode a partida e clique
no nome do seu robô no painel da direita. As mensagens mostram por onde o robô passou
e o que ele estava pensando. É assim que se acha quase todo problema de lógica.
Checklist antes do duelo
Passe por esta lista antes das 17h00:
O básico
- Arquivo dentro de
Robots/, salvo - Nome sem espaço, acento ou hífen
- Nome da classe é o nome que você quer ver na arena
- Os onze comandos obrigatórios estão lá
O comportamento
- Rodou uma partida inteira sem o jogo fechar
- Ele se mexe o tempo todo
- Ele reage ao bater na parede
- Ele reage a levar tiro
- Ele acerta pelo menos alguns tiros
Coloque o seu robô na arena junto com dois ou três do kit inicial e rode algumas partidas. Um robô que só foi testado sozinho não foi testado. Se ele perde feio para o RoboVigia, ainda dá tempo de ajustar.