🤖 Guía de Programación de Bots

Tank Battle: Crea tu Estrategia en JavaScript

🎯 Conceptos Básicos

Sistema de Coordenadas

Mecánicas del Juego

🛠️ API Disponible

Comandos de Movimiento

move(distance)

Mover hacia adelante o atrás

  • Positivo: Avanza hacia adelante
  • Negativo: Retrocede
// Avanza 100 píxelesmove(100);

turnBody(degrees)

Girar el cuerpo del tanque

  • Positivo: Gira en sentido horario
  • Negativo: Gira en sentido antihorario
// Gira 90° a la derechaturnBody(90);

Comandos de Combate

fire(power)

Disparar

Parámetro: power (número) - Potencia del disparo (0.1 - 3.0). Mayor potencia = Más daño, más velocidad, más costo de energía.

// Disparo con potencia media-altafire(2.0);

Información del Tanque

let status = getStatus()

Retorna un objeto con el estado actual del bot.

  • x, y: Posición actual
  • energy: Energía restante
  • heading: Dirección actual (0-360°)
  • kills: Número de enemigos eliminados
  • shotsFired: Disparos realizados

Registro y Debug

log(message)

Mostrar mensaje en el log de la batalla.

log("¡Enemigo detectado!");

📡 Sistema de Eventos

Función Principal: run()

Se ejecuta continuamente mientras el tanque no esté ocupado realizando una acción (e.g., girando o moviéndose a una gran distancia).

function run() {    // Tu lógica principal aquí    // Se ejecuta cuando el tanque no está ocupado    move(100);    turnBody(45);    fire(1.5);}

Detección de Enemigos: onScannedRobot(event)

Se dispara cuando el radar detecta un enemigo. El objeto event contiene información crucial.

function onScannedRobot(event) {    // Se ejecuta cuando detectas un enemigo    log("Enemigo: " + event.name + " a " + event.distance + " píxeles");        // Propiedades del evento (puedes acceder a ellas en tu lógica)    // event.name, event.distance, event.bearing, event.energy, event.heading}

Colisiones con Paredes: onHitWall(event)

Se ejecuta cuando el tanque choca con los límites de la arena.

function onHitWall(event) {    // Se ejecuta cuando chocas con una pared    log("¡Choqué con la pared!");    turnBody(180); // Girar y alejarse    move(50);}

Impactos de Bala

onBulletHit(event)

Cuando TU bala impacta a un enemigo.

onHitByBullet(event)

Cuando TE impactan.

🎮 Estrategias de Programación

1. Bot Básico - Wall Follower

function run() {    move(100);    turnBody(90);}function onHitWall(event) {    turnBody(90);    move(50);}function onScannedRobot(event) {    fire(2);}

2. Bot Agresivo - Cazador

let enemySpotted = false;function run() {    if (!enemySpotted) {        // Buscar enemigos girando        turnBody(45);        move(50);    }}function onScannedRobot(event) {    enemySpotted = true;        // Apuntar directamente    let angleToEnemy = event.bearing;    turnBody(angleToEnemy);        // Disparar según la distancia    if (event.distance < 100) {        fire(3.0); // Máxima potencia cerca    } else {        fire(1.5); // Potencia media lejos    }        // Acercarse para el golpe de gracia    move(event.distance / 2);        enemySpotted = false;}

3. Bot Defensivo - Esquivador

let lastScanDirection = 1;function run() {    // Movimiento errático simple    move(80);    turnBody(30 * lastScanDirection);    lastScanDirection *= -1;}function onScannedRobot(event) {    // Disparar y esquivar perpendicular al enemigo    fire(1.0);        let escapeAngle = event.bearing + (Math.random() > 0.5 ? 90 : -90);    turnBody(escapeAngle);    move(100);}function onHitByBullet(event) {    // Movimiento de emergencia    turnBody(90);    move(150);}

💡 Consejos y Trucos

Gestión de Energía

let status = getStatus();if (status.energy < 20) {    // Energía baja - ser conservador    fire(1.0);} else if (status.energy > 80) {    // Energía alta - ser agresivo    fire(2.5);}

Movimiento Errático vs. Predecible

❌ Malo - Muy predecible

function run() {    move(100);    turnBody(90);}

✅ Bueno - Impredecible

function run() {    let randomMove = 50 + Math.random() * 100;    let randomTurn = -45 + Math.random() * 90;    move(randomMove);    turnBody(randomTurn);}

🐛 Debugging

Uso Detallado del log()

Utiliza plantillas de string (backticks) y Math.round() para mostrar la información de forma clara.

function onScannedRobot(event) {    log(`Enemigo ${event.name}:`);    log(`- Distancia: ${Math.round(event.distance)}`);    log(`- Bearing: ${Math.round(event.bearing)}°`);        let status = getStatus();    log(`Mi energía: ${Math.round(status.energy)}`);}

Manejo Básico de Errores con try...catch

function run() {    try {        // Lógica que podría fallar        complexStrategy();    } catch (error) {        log("Error en estrategia: " + error.message);        // Estrategia de respaldo simple        move(50);    }}

🏆 Estrategias Avanzadas

Sistema de Estados Finito

Organiza la lógica de tu bot usando estados como SEARCHING, ATTACKING, o FLEEING.

let botState = "SEARCHING"; // SEARCHING, ATTACKING, FLEEING...function run() {    switch(botState) {        case "SEARCHING":            searchStrategy();            break;        case "ATTACKING":            attackStrategy();            break;    }}

Memoria de Enemigos

Usa un Map o un objeto para recordar datos de los enemigos, incluso si no los estás escaneando actualmente.

let enemies = new Map();function updateEnemyInfo(event) {    enemies.set(event.name, {        lastSeen: Date.now(),        lastDistance: event.distance,        energy: event.energy,    });}

📚 Plantillas de Código

Bot Template Básico (Decisor)

// ========== MI BOT - TANK BATTLE ==========let myStrategy = "aggressive"; // aggressive, defensive, balancedfunction run() {    if (myStrategy === "aggressive") {        // Movimiento de búsqueda agresivo        move(100);        turnBody(45);    } else if (myStrategy === "defensive") {        // Movimiento de cobertura        move(50);        turnBody(30);    }}function onScannedRobot(event) {    log(`Detectado: ${event.name} a ${Math.round(event.distance)}px`);        // Apuntar y disparar    turnBody(event.bearing);    let power = event.distance < 100 ? 3.0 : 1.5;    fire(power);        // Decidir si acercarse o huir basado en energía    if (event.energy < getStatus().energy) {        // Soy más fuerte - atacar        move(event.distance / 2);    } else {        // Soy más débil - mantener distancia        turnBody(event.bearing + 90); // Intenta moverte lateralmente        move(100);    }}function onHitWall(event) {    log("¡Pared! Retrocediendo...");    turnBody(135);    move(80);}function onHitByBullet(event) {    log(`¡Me disparó ${event.attacker}!`);    // Movimiento evasivo rápido    turnBody(90);    move(120);}