Física do jogo
As regras do mundo
Quanto custa cada ação, quanto dano cada coisa causa e como o jogo entende direções. Quem conhece estes números escreve um robô melhor, e isso é aritmética simples.
A bússola da arena
Este é o ponto que mais confunde, então vale começar por ele. No PyRobocode, o ângulo 0 aponta para baixo, e não para cima nem para a direita, como a maioria das pessoas espera. E os ângulos crescem no sentido horário.
turn(90) partindo do zero deixa o robô olhando
para a esquerda da tela.
O canto superior esquerdo da arena é o ponto (0, 0).
O x cresce para a direita, como você espera. Mas o y
cresce para baixo: quanto maior o y, mais perto da
parede de baixo o robô está. É a mesma lógica que faz o ângulo 0 apontar para baixo.
Guarde as quatro direções como constantes no topo do arquivo e nunca mais pense nisso:
BAIXO = 0
ESQUERDA = 90
CIMA = 180
DIREITA = 270
Como o tempo passa: quadros e a fila
A partida acontece em quadros, como um desenho animado. A cada quadro, o jogo executa um pedacinho do que cada robô mandou fazer.
Quando você escreve self.move(20), o robô não pula 20 pixels. O jogo divide
esse comando em pedaços de 5 e executa um por quadro:
| Quadro | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|
move(20) |
+5 px | +5 px | +5 px | +5 px | fila vazia → run() |
Vale igual para giros: turn(20) vira 5 graus por quadro, em 4 quadros.
Por isso um move(400) deixa o robô ocupado por 80 quadros, uma
eternidade em que ele não decide mais nada e vira alvo fácil.
| Grandeza | Valor |
|---|---|
| Passo de movimento | 5 pixels por quadro |
| Passo de giro | 5 graus por quadro |
| Velocidade do tiro | 10 pixels por quadro, o dobro da velocidade do robô |
Como tudo é fatiado de 5 em 5, ângulos e distâncias que são múltiplos de 5 saem exatos. Valores quebrados negativos podem girar até 5 graus a mais do que você pediu. Não quebra nada, mas atrapalha a mira fina.
Vida
| Regra | Valor |
|---|---|
| Vida inicial | 100 |
| Teto de vida | 100, e curar acima disso não acumula |
| Vida zerada | o robô sai da arena; quem deu o último dano ganha uma eliminação |
A vida de cada robô aparece embaixo do tanque na arena e na barra colorida do painel da
direita. No seu código, use self.getHealth().
De onde vem o dano
| Situação | Efeito |
|---|---|
| Bater numa parede | −1 de vida, o robô é empurrado para trás e a fila de comandos é descartada |
| Trombar em outro robô | −1 de vida nos dois, os dois são empurrados e as duas filas são descartadas |
| Levar um tiro | −3 × potência de vida |
| Disparar | −1 × potência de vida, na hora do disparo |
| Acertar um tiro | +2 × potência de vida para quem atirou |
| Ficar parado tempo demais | perda de vida automática e uma penalidade registrada no desempate |
A matemática do tiro
Esta é a conta mais útil do jogo inteiro. Um disparo de potência P:
- custa P de vida sua, sempre, na hora de atirar;
- se acertar, tira 3P do adversário e devolve 2P para você;
- se errar, o custo P foi perdido e nada acontece.
Ou seja, em relação à sua própria vida:
| Resultado | Sua vida | Vida do adversário | Saldo da troca |
|---|---|---|---|
| Acertou | −P +2P = +P | −3P | Excelente: você ganha vida e tira o dobro dela do outro |
| Errou | −P | nada | Prejuízo puro |
Números concretos
| Potência | Custo do disparo | Dano se acertar | Vida que você recupera | Tiros para eliminar alguém com 100 de vida |
|---|---|---|---|---|
1 | −1 | 3 | +2 | 34 |
2 | −2 | 6 | +4 | 17 |
3 | −3 | 9 | +6 | 12 |
5 | −5 | 15 | +10 | 7 |
10 | −10 | 30 | +20 | 4 |
Tiro forte que acerta é o melhor negócio do jogo. Um fire(10)
que acerta tira 30 do outro e te devolve 20, então você sai da troca com mais vida
do que entrou.
Tiro forte que erra é o pior. Três fire(10) errados
custam 30 de vida sua, quase um terço do total, sem encostar em ninguém.
Por isso a regra que os robôs bons seguem: potência alta quando o alvo está perto e parado, potência baixa quando está longe ou se mexendo. A potência aceita valores de 0.5 a 10.
Como o radar enxerga
O radar projeta um cone à frente dele. Quando o tanque de um adversário entra nesse
cone, o jogo chama o onTargetSpotted() do seu robô, entregando a posição do
inimigo. Fora do cone, o adversário é invisível, mesmo que esteja colado em você.
O cone gira junto com o radar. Se o radar estiver travado na arma
(lockRadar("gun")), ele gira quando a arma gira; se estiver travado no
corpo, gira quando o corpo gira; se estiver livre, só gira com
radarTurn().
Os quatro formatos disponíveis, e a troca entre alcance e abertura, estão na página de referência.
self.radarVisible(True) no init() desenha o cone na tela.
Ver o cone varrendo a arena explica na hora por que o robô não está encontrando
ninguém.