четверг, 15 ноября 2012 г.

HabraWars - все новое, хорошо забытое старое...

Уже какой день не утихают бои на виртуальных просторах конкурса по программированию AI. На хабре появилась статья - разбор полетов одного из участников.

Ни для кого не секрет, что CodeTanks - это упрощенная версия Robocode. Новизной и инновациями данный конкурс не блещет, но он все же интересен и я рад что там принимал участие.

А я тем временем, серфя просторы интернета, на ткнулся на посты на Хабре, датированные 2009м годом. Оказывается был проведен турнир по аналогичным боям на Javascript в http://habrawars.appspot.com

Забавная вещь, хотя не блещет красотой и физикой, в отличие от Robocode и CodeTanks, но тоже интересна и даже затягивает. Роботы скорее напоминают конкурсных BEAM-роботов.

После закрытия песочницы CodeTanks можно будет оттачивать свое мастерство в этом варианте лайт-версии Robocode. Лично я стал фанатом такого рода игрушек и кто знает, может такие простые забавы вырастут в участие в Robocode.




Пример кода хабраварс:

// Этот код будет обрабатываться внутри класса
// Здесь можно задавать переменные, которые будут доступны во время всей симуляции
this.target_id = -1;

// Метод action - основная функция, которая вызывается при обработке каждого фрейма
// self - объект со свойствами вашего робота (id, x, y, angle, health, energy)
// enemyTanks - массив с объектами свойств противников (аналогично self)
this.action = function(self, enemyTanks, shells, world) {
//*
    // Уворачиваемся от снарядов
    for (var i = 0; i < shells.length; i++)
    {
        var shell = get_shot_destination(shells[i]);        
        // Если снаряд должен попасть рядом с нами, уворачиваемся
        if (Math.sqrt(Math.pow(self.x - shell.x, 2) + Math.pow(self.y - shell.y, 2)) < 70)
        {
            var shot_dir = get_direction(self.x, self.y, shell.x, shell.y);
            // Выбираем направление, противоположное точки попадания снаряда
            var a = get_angle_control(self.angle, shot_dir + 180);
            // Месть!
            this.target_id = shells[i].shooter;
            return [1, a, false, 0];            
        }   
    }    
//*/    
    // Если не осталось противников - просто движемся вперед
    if (enemyTanks.length == 0)
        return [0.5, 0, false, 0];    

    // Если ещё не выбрана цель или нашей цели больше нет, выбираем цель случайным образом
    // target_id - это ID цели, а не её индекс в массиве enemyTanks (индексы могут меняться)
    if (this.target_id == -1 || !get_enemy_by_id(this.target_id, enemyTanks))
        this.target_id = enemyTanks[Math.round(Math.random() * (enemyTanks.length - 1))].id;
    
    // Переменная target будет содержать объект из списка enemyTanks со свойствами цели.
    var target = get_enemy_by_id(this.target_id, enemyTanks);

    // Вычисляем под каким углом относительно нас находится цель
    var target_dir = get_direction(self.x, self.y, target.x, target.y);

    // Вычисляем угол, на который нужно повернуться (от -1 до 1)
    var a = get_angle_control(self.angle, target_dir);
    
    // Расстояние до цели
    var range = Math.sqrt(Math.pow(self.x - target.x, 2) + Math.pow(self.y - target.y, 2));

    // Если нет энергии для выстрела и мы слишко близко - убегаем от противника
    if (self.energy < 65 && range < 500)
        a = -a;
    
    // Если угол между нами и целью < 1 градуса и расстояние < 800 - стреляем
    var fire = angle_size(self.angle, target_dir) < 1 && range < 800;
    
    // Возвращаем управление [скорость от 0 до 0.5, угол поворота от -1 до 1, огонь true или false, дальность огня (положительное число)]
    return [0.5, a, fire, range];
}

​

Комментариев нет:

Отправить комментарий