Модератор форума: GUNNER161, Panikaha |
Форум РЕДАКТОР - ArmA 3 Скрипты Виртуальный противник (Создание управляющей программы для боевых действий) |
Виртуальный противник |
› Воскресенье
› 16.11.2014
› 19:59
› Сообщение #
andrucio, функция возвращает позицию именно в тот момент, когда её вызывают. А логику, когда именно нужно получить эти данные и что с ними делать зависит не от этой функции, а от скрипта вызывающего её.
Добавлено (16.11.2014, 19:59)
Cтруктуры данных важнее кода!
Список команд | Список оружия | Список техники | Список юнитов | Список объектов Armstalker Online |
› Воскресенье
› 16.11.2014
› 22:20
› Сообщение #
ZoRRo или andrusio, пожалуйста, объясните мне "на пальцах" работу команд private, setVariable, getVariable.
Чем, например, отличается private "_var" от _var , если они находятся в коде? Или _var setVariable ["_var", 0] от _var = 0? Для чего это: Хочу создать код подсчета пуль, к которому через call будут обращаться лидеры групп. Пока пользуюсь глобальной переменной, но это только для одного лидера. Как обойтись без глобальной переменной и возможно ли это сделать с помощью вышеуказанных команд? |
› Понедельник
› 17.11.2014
› 00:29
› Сообщение #
Индеец,
setVariable - записывает переменную в сам объект. Это не обязательно должен быть "юнит". Можно записать в: Control, Group, Namespace, Task, Location, Trigger. Пример: _object setVariable ["var", _var]; //запись _var = _object getVariable"var"; //чтение Я же писал тебе про это постом выше? private - решает проблему с пространством имён внутри скрипта. Поскольку в sqf функциях могут быть вложенные контексты, то возможна ситуация когда имя переменной созданной во вложенном контексте уже используется во внешнем. Приведу пример, сразу увидишь: Код _my_var = "это переменная доступна в текущем и во всех вложенных контекстах"; call { _my_var = "однако ее можно случайно испортить создав другую с тем же именем"; }; player sideChat _my_var; //_my_var = "однако ее можно случайно испортить создав другую с тем же именем"; Для разрешения такой ситуации необходимо явно объявлять переменные приватными: Код _my_var = "это переменная доступна в текущем и во всех вложенных контекстах"; call { private ["_my_var "]; _my_var = "однако ее можно случайно испортить создав другую с тем же именем"; }; player sideChat _my_var; //_my_var = "это переменная доступна в текущем и во всех вложенных контекстах"; Теперь переменная существующая во внешнем контексте уже не перезаписывается, а вместо этого создается новая локальная переменная с таким же именем. При выходе из блока вызываемого командой call эта новая переменная будет уничтожена, в то время как старая переменная по прежнему доступна. Строго рекомендуется все локальные переменные sqf функций объявлять приватными, лишь за исключением тех случаев, когда вы осознанно желаете получить иной эффект. Принебрежение этим правилом может привести к непредсказуемым последствиям и к полному выносу мозга, выявляя причину того с чего это переменная вдруг внезапно изменила своё значение и тип). Примечание: вложенность контекстов появляется не только при использовании команды call, каждая из нижеперечисленных команд создает свой контекст: foreach, count, while, do, then, exec. Однако, поскольку контекст, создаваемый командой exec, не имеет родительского контекста, объявление всех локальных переменных запущенного с помощью exec скрипта приватными обычно не будет иметь смысла. Итак, поскольку это важный момент, рассмотрим его с точки зрения интерпретатора. Встречая во вложенном контексте любую локальную переменную, интерпретатор просматривает родительские (внешние по отношению к текущему) контексты на наличие переменной с таким именем; если такая переменная уже существует — то будет использована она, в противном случае будет создана новая, принадлежащая текущему контексту, локальная переменная.
Cтруктуры данных важнее кода!
Список команд | Список оружия | Список техники | Список юнитов | Список объектов Armstalker Online |
› Понедельник
› 17.11.2014
› 00:42
› Сообщение #
ZoRRo, теперь стало более понятно. Столкнулся со случаем, когда необъявленная переменная не хотела принимать предписанное ей значение внутри switch (хинт писал any)
|
› Понедельник
› 17.11.2014
› 09:35
› Сообщение #
ZoRRo, спаибо за private.
А по поводу setVariable - я так и не понял, что значит "записать переменную в объект". Это как? Объекту придается дополнительная информация в виде значения новой переменной? И, как ярлычок, сопровождает его до смерти объекта? Поясни, пожалуйста. А то так и останусь темным в этих вопросах. |
› Понедельник
› 17.11.2014
› 18:09
› Сообщение #
Индеец, да читай здесь
Это просто переменные хранящиеся в пространстве памяти объекта, а не в пространстве имён миссии (иначе глобальные переменные). Даже без функции удобной синхронизации, они более удобные для того, чтобы держать специфические данные относящиеся к объекту. unit1 setVariable ["name","John"]; unit2 setVariable ["name","Mike"]; _name = unit1 getVariable "name"; (для получения имени юнита, что было бы более сложнее с глобальной переменной массива). Это очень удобная вещь, потому что это дает возможность передавать / обновлять / проверять значения в нескольких сценариях, не используя глобальную переменную, или того, чтобы создать массив глобальных переменных для проверки каждого конкретного объекта. Для удаления переменной: unit1 setVariable ["name", nil]; Переменная объекта является локальной для каждого клиента, и изменения по умолчанию не транслируются.
Cтруктуры данных важнее кода!
Список команд | Список оружия | Список техники | Список юнитов | Список объектов Armstalker Online |
› Пятница
› 21.11.2014
› 12:41
› Сообщение #
Наваял скрипт набора тактической информации для одной группы. Думаю применять, когда есть визуальный контакт с врагом.
Определяются:
Используются блоки команд для определения каждого критерия, вызываемые посредством call. Натыкал private и set/getVariable, где только можно. Теперь нужно все это определять для трех групп и обрабатывать информацию. // ОПРЕДЕЛЕНИЕ КООРДИНАТ И ОРИЕНТАЦИИ ВРАЖЕСКОЙ ПОЗИЦИИ _posAndDirEnemy = { // добавляем в код новые переменные private ["_unit","_enemy","_leaderEnemy","_posLeaderEnemy","_dirFormationEnemy"]; // боец _unit = _this select 0; // ближайший враг, которого видит лидер группы _enemy = _unit findNearestEnemy _unit; // лидер вражеской группы _leaderEnemy = leader group _enemy; // позиция лидера вражеской группы _posLeaderEnemy = getPos _leaderEnemy; // направление вражеской группы ( в град., по час. стрелке, от севера) _dirFormationEnemy = formationDirection _leaderEnemy; /* присваиваем переменной в пространстве имен бойца значение координат вражеского лидера */ _unit setVariable ["_posEnemy", _posLeaderEnemy]; /* присваиваем переменной в пространстве имен бойца значение направления в построении вражеского лидера */ _unit setVariable ["_dirEnemy", _dirFormationEnemy]; }; // ОПРЕДЕЛЕНИЕ КОЛИЧЕСТВА ВИДИМЫХ ВРАГОВ _numberEnemy = { // добавляем в код новые переменные private ["_unit","_enemies","_man","_numberEnemy"]; // боец _unit = _this select 0; // список врагов _enemies = []; // список объектов класса "человек" в радиусе 69 м от лидера группы _man = nearestObjects [_unit, ["Man"], 69]; { // если сторона юнита не дружественна стороне лидера группы if (((side _x) getFriend (side _unit) < 0.6) // и лидер группы знает о юните более чем на 1.5 баллов and (_unit KnowsAbout _x > 1.5)) // то зачислить юнита в список врагов then {_enemies set [count _enemies,_x]}; // для всех людей в радиусе 69 м от лидера группы } forEach _man; // присваиваем переменной в пространстве имен бойца значение количества видимых врагов _unit setVariable ["_counterEnemy", count _enemies]; }; // ОПРЕДЕЛЕНИЕ ПЛОТНОСТИ ВРАЖЕСКОГО ОГНЯ _densityFire = { // добавляем в код новые переменные private ["_unit"]; // боец _unit = _this select 0; // устанавливаем обработчик событий на наличие пуль вокруг бойца _in = _unit addEventHandler ["FiredNear", { // добавляем в код новые переменные private ["_unit","_link","_typeSlug","_typeOfBullets"]; // боец _unit = _this select 0; // список бойцов группы _link = units group _unit; // тип обнаруженной пули _typeSlug = _this select 6; /* присваиваем новой переменной значение выделенной из пространства имен бойца списка типов вражеских пуль*/ _typeOfBullets = _unit getVariable "_bullets"; // если тип обнаруженной пули есть в списке типов вражеских пуль, if (_typeSlug in _typeOfBullets) // то пополняем счетчик бойца на единицу then {_unit setVariable ["_counterFire", ((_unit getVariable "_counterFire") + 1)]}; }]; sleep 3; // задержка (период цикла набора тактической информации в скрипте) // удаляем обработчик событий _unit removeEventHandler ["FiredNear", _in]; }; // боец _unit = _this select 0; // сторона отделения _side = side _unit; // название отделения _group = group _unit; // состав отделения _units = units _group; _target = _this select 1; // ОПРЕДЕЛЯЕМ ДЛЯ ГРУПП НАПРАВЛЕНИЕ АТАКИ // определяем центры "зон ответственности" для групп _centerGroup = _target modelToWorld [0,0,getPos _target select 2]; // ОПРЕДЕЛЯЕМ ТИП ВРАЖЕСКИХ БОЕПРИПАСОВ // составляем списки всех людей, попавших в "зоны ответственности" _list = _centerGroup nearEntities [["Man"], 25]; // список типов пуль, используемых врагом _bullets = []; { // класс обоймы, используемой врагом _magazineClass = currentMagazine _x; // по классу обоймы определяем тип боеприпаса _bullet = getText (configFile >> "cfgMagazines" >> _magazineClass >> "ammo"); // если тип боеприпаса не состоит в списке типов пуль if !(_bullet in _bullets) // то добавить его в список типов пуль врага then {_bullets set [count _bullets, _bullet]}; //для всех людей, попавших в "зоны ответственности" } forEach _list; // пока жив хотя бы один из бойцов отделения, выполнять: while {{alive _x} count _units > 0} do { // лидер группы _leader = leader group _unit; // НАБОР ТАКТИЧЕСКОЙ ИНФОРМАЦИИ // ДОБАВЛЯЕМ В ПРОСТРАНСТВО ИМЕН ЛИДЕРА ГРУППЫ ДОПОЛНИТЕЛЬНЫЕ ПЕРЕМЕННЫЕ // координатам вражеской позиции присваиваем значение начальных координат _leader setVariable ["_posEnemy", [0,0,0]]; // направление вражеского построения - на север _leader setVariable ["_dirEnemy", 0]; // количество известных врагов - 0 (обнуляем счетчик) _leader setVariable ["_counterEnemy", 0]; // список типов вражеских пуль _leader setVariable ["_bullets", _bullets]; // плотность огня (количество пуль за цикл) - 0 (обнуляем счетчик) _leader setVariable ["_counterFire", 0]; // ОПРЕДЕЛЕНИЕ КООРДИНАТ И ОРИЕНТАЦИИ ВРАЖЕСКОЙ ПОЗИЦИИ [_leader] call _posAndDirEnemy; _posEnemy = _leader getVariable "_posEnemy"; _dirEnemy = _leader getVariable "_dirEnemy"; // ОПРЕДЕЛЕНИЕ КОЛИЧЕСТВА ВИДИМЫХ ВРАГОВ [_leader] call _numberEnemy; _counterEnemy = _leader getVariable "_counterEnemy"; // ОПРЕДЕЛЕНИЕ ПЛОТНОСТИ ВРАЖЕСКОГО ОГНЯ [_leader] call _densityFire; _counterFire = _leader getVariable "_counterFire"; hint str _counterFire; // тест if (_counterFire > 10) then {{_x setUnitPos "DOWN"} forEach _units} else {{_x setUnitPos "MIDDLE"} forEach _units}; // если лидер не жив, if !(alive _leader) // то удалить у лидера вложенные переменные - нужно ли это? then { _leader setVariable ["_posEnemy", nil]; _leader setVariable ["_dirEnemy", nil]; _leader setVariable ["_counterEnemy", nil]; _leader setVariable ["_bullets", nil]; _leader setVariable ["_counterFire", nil]; }; }; Порылся в тактике: Цитата Охват осуществляется в тесном тактическом и огневом взаимодействии, обход - втактическом взаимодействии с войсками, которые наступают с фронта. Кроме того, насколько я понял, обход совершается скрытно. Т.е. или гнать ботов за границу видимости вражьих ботов (а это метров 800), или использовать складки местности (что, как мы выяснили, геморрой еще тот). Да и условия необходимости его применения я так и не нашел. Ну, возможно, кроме этого: Цитата для нападения на позиции артиллерии и командные пункты, нарушения связи, управления и работы тыла. Но это уже при крупномасштабных боевых действиях. А для уничтожения одного отделения (а тем более взвода) разделять силы для обхода - необходимо ли? Может, при наличии тяжелого вооружения? Тогда, при наличии у противника станкового пулемета, охватывать его нужно с другого фланга. И ли хватит обхода? |
› Суббота
› 22.11.2014
› 22:07
› Сообщение #
Цитата // то удалить у лидера вложенные переменные - нужно ли это? А как запускать хочешь ? Надо было с этого начать. Что то я не могу пока придумать. Кроме как постоянный циккл на группе, там и цель узнавать и прочее. А в примере цель идёт как входящий параметр, если был бы обработчик было бы отлично, но такого нет.
Cтруктуры данных важнее кода!
Список команд | Список оружия | Список техники | Список юнитов | Список объектов Armstalker Online |
› Воскресенье
› 29.05.2016
› 22:08
› Сообщение #
ZoRRo, это промежуточный скрипт. Думаю запускать его, когда группа уже знает о наличии противника в зоне атаки. Т.е. при подходе группы на определенное расстояние к центру "зоны ответственности".
Пока рассуждения такие: отделению указывается позиция атаки (не важно в структуре взвода или самостоятельно), при подходе на какое-то (сейчас определяю на какое) отделение разбивается на группы и перестраивается в предбоевой порядок, опять же на каком-то расстоянии от позиции атаки, разворачиваем группы в боевой порядок и запускаем этот скрипт. По полученным данным определяем: будет ли фронтальная атака (есть интересный т.н. "маневр огнем"), или применим обход, или придется отходить. Также определяем позу, скорость, ну наверное и применение "подавляющего огня" для атакующих групп. Конечно же нужно определять согласованность выполняемых действий м-ду группами. Применять охват, думаю, не имеет смысла. Планирую вокруг позиции атаки создать шаблон прикрепленных координат для выполнения маневров. И выбранный маневр будет выполняться по уже обозначенным координатам. Кстати, на эту мысль меня натолкнула работа andrucio над размещением предметов. Добавлено (02.12.2014, 23:10) --------------------------------------------- Гадство. У меня такое ощущение, что БИСы специально морочат голову этими командами. Ну зачем создавать для перемещения пять(!) вариантов команд: addWaypoint, moveTo, commandMove, и совсем почти идентичные doMove и move? Но это - лирика. Отпуск закончился, времени не стало, но... Остановился на таком варианте:
Пока приготовил скрипт лобовой атаки, по которому отделение разбивается на первый - второй и, пока первые прикрывают, вторые передвигаются и наоборот. Пока не тестил. // БЛОК КОМАНД ДЛЯ ПЕРЕМЕЩЕНИЯ ОТДЕЛЕНИЯ ПРИ ЛОБОВОЙ АТАКЕ // Активация _fa = [юнит] execVM "frontalAttack.sqf" // добавляем в код новые переменные private ["_unit","_group","_units","_enemy","_leaderEnemy","_posAttack","_j","_posAttack"]; // боец _unit = _this select 0; // позиция атаки _posAttack = _this select 1; // название отделения _group = group _unit; // командир отделения _leader = leader _group; // состав отделения _units = units _group; // последний индекс элемента в массиве _units _j = (count _units) - 1; // ближайший враг, которого видит боец _enemy = _unit findNearestEnemy _unit; // лидер вражеской группы _leaderEnemy = leader group _enemy; // задаем построение отделения _group setFormation "VEE"; // время на перепостроение sleep 5; // пока жив лидер вражеской группы, выполнять: while {alive _leaderEnemy} do { // отделение движется к позиции лидера вражеской группы _group move getPos _leaderEnemy; // задаем для отделения скорость передвижения _group setSpeedMode "FULL"; // для "_i" от 0 до (число бойцов в группе -1) шагом 2, выполнять: for "_i" from 0 to _j step 2 do { (_units select _i) disableAI "MOVE"; // отключение движения (_units select _i) setUnitPos "MIDDLE"; // поза - на колено (_units select _i) suppressFor 5; // подавляющий огонь }; // для "_i" от 1 до (число бойцов в группе - 1) шагом 2, выполнять: for "_i" from 1 to _j step 2 do { (_units select _i) enableAI "MOVE"; // включить движение (_units select _i) setUnitPos "UP"; // поза - стоя }; sleep 5; // для "_i" от 0 до (число бойцов в группе-1) шагом 2, выполнять: for "_i" from 0 to _j step 2 do { (_units select _i) enableAI "MOVE"; // включить движение (_units select _i) setUnitPos "UP"; // поза - стоя }; // для "_i" от 1 до (число бойцов в группе - 1) шагом 2, выполнять: for "_i" from 1 to _j step 2 do { (_units select _i) disableAI "MOVE"; // отключение движения (_units select _i) setUnitPos "MIDDLE"; // поза - на колено (_units select _i) suppressFor 5; // подавляющий огонь }; sleep 5; }; // убираем ограничения { _x enableAI "MOVE"; // включить движение _x setUnitPos "AUTO"; // поза - по желанию } forEach _units; // для всех бойцов отделения // отделение движется к позиции атаки _group move _posAttack; Добавлено (13.02.2015, 01:23) --------------------------------------------- Прошло много времени, закончился отпуск, сильно ограничен во времени. В общем доделал сркриптяру. Поставил бессмертную группу супостатов, создал свое отделение кащеев - и в путь! Мое отделение мчится по полю, почему-то обнаруживает врага только в 500-400 м на ровной поверхности, послушно разделяется на три группы. Группы не спеша(!) добираются до своих позиций, залегают, бросают дымовые гранаты в сторону вражьей позиции (смотрится прикольно) и определяемая маневровая группа, также не спеша, чухает по маршруту обхода. Все все видят, не переживают, идет вялая перестрелка. И вот маневровая группа добирается до рубежа атаки и тут происходит непонятное: огневые группы, имея команду двигаться на позицию супостата, забивают на команду и толпой мчатся на соединение с маневровой группой. Видимо БИСы добавили ботам немного внутреннего мира и боты заимели свое видение ситуации. Ладно, - подумал я (конечно другое подумал), убрал бессмертие - результат плачевный: маневровую группу покрошили в момент выполнения маневра - сказалось отсутствие взаимодействия с местностью. Без скрипта соотношение выживших примерно то же. Возник вопрос: на кой нужен тогда этот скрипт? А потом по зомбоящику увидел передачу про беспилотники. Так вот там говорилось об управлении стаей. Рассматривалось два способа управления: общим управляющим алгоритмом и приданием индивидуального ИИ, когда каждый бот сам определяет как выполнять общую задачу. И тут нужно и определение важной цели, и взаимодействие с соседними союзными ботами, и, в моем случае, взаимодействие с местностью. Такие вот идеи... Добавлено (29.05.2016, 22:08) --------------------------------------------- Возможно кому-то эта тема еще интересна. В общем, есть идея: вначале забахать скрипт для одиночки, затем уже для группы. Для одиночки основные команды для выживания: защита от гранаты, поиск и пополнение боезапаса и аптечек, поиск и движение к безопасной позиции при наличии противника. Для группы - взаимодействие и тактические построения. Защита от гранаты и мародерство практически решены, а вот о перемещении во время боя хотелось бы узнать мнения. Из того что есть - в цикле определяются известные враги, из них выбираются те, кто целится в бойца, из них - ближайший. Затем вокруг бойца строится спираль из 100 координат и каждая проверяется на просматриваемость со стороны врага, и, если существует позиция, на которой не видно бойца в положении лежа, но видно ствол оружия бойца в положении стоя, то назначается перемещение к этой позиции. Кроме того определяется характер текущей позиции бойца, и, если оружие врага направлено на бойца, то боец принимает защитную позу, если нет - атакующую. Подробнее в прикреплении. https://yadi.sk/d/0Q2Tk024s6imi В чем мой вопрос? Ну во-первых: жизнеспособность самой идеи, во-вторых: новые приемы для поиска укрытий или классификации целей, ну а в-третьих: как, гадство, заставить бота хилять точно в указанные координаты, или как этого урода упросить не останавливаться в раздумьях на полдороги к укрытию, или чтобы он постоянно целился в опасного врага, а не блуждал в поисках завтрашнего дня? P.S. Где- то вычитал сравнение игры в мультиплеере с сексом с живым человеком, а одиночную игру - с резиновой женщиной. Давайте сделаем ее краше что-ли?! Сообщение отредактировал Индеец - Воскресенье, 29.05.2016, 22:39
|
› Воскресенье
› 29.05.2016
› 23:29
› Сообщение #
|
› Понедельник
› 30.05.2016
› 10:22
› Сообщение #
alex70-03, выкладывать миссию нет смысла - ставишь бота, ставишь в отдалении противника, задаешь боту перемещение к врагу, активируешь скрипт, все.
Тут, как раз, в этом то и дело, что бот должен сам реагировать на изменяющуюся обстановку. А в том как - тут вопрос. Почитал статейки о моделировании ИИ - наиболее понятный и реализуемый вариант - это "конечные автоматы" (это когда на каждую ситуацию прописываются отдельные команды). Но и тут много работы. Дальше пойдут категоричные заявления, но сразу предупреждаю, что это - мое личное мнение. Как мы играем в одиночную игру? Мы подсознательно (или явно) определяем алгоритм работы ИИ. Все удовольствие заключается в том, чтобы обыграть машину. Ясен пень, чем сложнее -тем интереснее. А как повышается сложность - боты более меткие, их перемещения иногда не предсказуемы и все это в обрамлении псевдореализма: на разворот требуется время, бот реагирует на объекты в направлении головы и т.д. Задача состоит в том, чтобы боты представляли собой не метких одиночек-камикадзе, а действовали согласовано, реагировали на действия противника изменением построения и т.д. Что предлагаю я? В начале темы я предлагал создать общую управляющую программу, которая будет руководить перемещением ботов как фигурами на шахматной доске. Но не пошло. Причин этому несколько: боты не обращают внимание на ланшафт, действуют не согласовано и (самое главное) их поведение, маршрут передвижения сложно предугадать. Я думаю, что это - встроенный БИСами ИИ. Но, согласитесь, сложно управлять бойцом, который бегает куда захочет или во время боя рассматривает достопримечательности. Не хочу полностью отказываться от идеи управляющей программы, вернее она нужна будет для постановки задач, а как их выполнять- боты должны решать самостоятельно. В том числе реагируя на ланшафт и расположение союзников и врагов. Как в пирамиде Маслоу - сначала частное, затем общественное. А какие задачи ставятся перед бойцом? Ответ - точка перемещения. А что важно для достижения этой точки? Ответ - наличие врагов и их опасность. И вот тут мы подходим к самому сложному - как действовать бойцу во время боя: как строить маршрут передвижения, какую позу принять, когда открывать огонь, как найти укрытие (вот тут список желательно дополнить) и т.д. На данном этапе разработана методика определения наиболее опасного врага (ближайший из получивших приказ целиться в бойца), поиск координат на местности возле бойца относительно безопасных и в направлении заданной точки перемещения, выбор позы в зависимости от того нацелено ли оружие выбранного врага на бойца. Из проблем: Безопасность позиции определяется с помощью команды checkVisibility, а она, в свою очередь, тонко реагирует на покрытие (траву и т.д.). В итоге найденная позиция оказывается видна врагу. Если позицию проверять на наличие пересечения с местностью и объектом - это сильно утяжеляет скрипт. Кроме того выбранная координата возможно не видна, но когда боец ложится, из-за наклона рельефа его жбан торчит чуть выше и виден. Маршрут передвижения - отдельная тема. В принципе можно вокруг бойца определить позиции, относительно безопасные, но как их связать в маршрут - я не знаю. Смысл в том, что конец маршрута - заданная точка перемещения, а определение безопасных позиций производится на расстоянии близком от бойца, и, возможно, выбор ближайшей безопасной позиции в дальнейшем заведет бойца в тупик. Вариант перемещения от объекта к объекту - я до сих пор не могу выделить отдельно деревья, камни, кусты и другие статические объекты без класса. Команда nearestObjets возвращает кроме них мух, комаров, пылинки и другую хрень, мягко говоря нам не нужную совсем. Взаимодействие - не решено совсем. Во какую простынь накатал! Жду предложений... |
› Понедельник
› 30.05.2016
› 12:57
› Сообщение #
Индеец, точку перемещения ставить нужно в любом случае, для того что бы если её нет, бот искал укрытие рядом с тем местом, где он находится.
У меня в миссиях основная проблема, при атаке на блок пост, боты либо разбегаются, либо их командой останавливать приходится, тогда интерес теряется, всё равно что по болванкам стрелять. А хотелось бы, что бы разума в такой ситуации было больше. Помню в "Путь Дракона", боты неплохо отстреливались выбирая укрытия рядом с собой. |
› Вторник
› 06.09.2016
› 19:19
› Сообщение #
Вот один вопрос задам: что мы хотим от поведения ботов?
Объяснить вопрос достаточно сложно без предыстории. А она такова: мною был создан скрипт, по которому отделение ботов осуществляло маневр обхода вражеской позиции. Много было всякого передумано, в результате чего при испытании выяснилась полная несостоятельность самой концепции. Т.е. без анализа местности (определение высот, рельефа, объектов) и соответственного планирования и выполнения маршрута, эффективность перемещений рана нулю. На данный момент способ анализа местности большой площади так и не решен. Почитав пару статей, отступив на шаг назад , решил создать алгоритм поведения для одного бота. И вот тут вопрос: как он должен себя вести. Ну увидел он врага, дальше что? То, что сейчас в голове - увидел врага, определил опасность, в направлении опасного врага нашел укрытие, добрался до укрытия, из-за укрытия поразил цель. Все это в цикле. На сейчас есть:
Может не туда я иду? Может нужно другая постановка приоритетных задач, иерархия выполнения, или еще что? |
› Пятница
› 09.09.2016
› 01:01
› Сообщение #
Наверное, того же, что делаем сами.
Но это уже слишком сложно. Кто-то пойдет по дну оврага для скрытности, а кто-то по гребню, желая контролировать обстановку. Причем в зависимости от задачи можно и так, и этак. Может, просто добавить смену положения при наличии обстрела, перекаты влево-вправо и тп? Иначе ты просто стремишься подменить родной движок. |
› Вторник
› 28.02.2017
› 14:07
› Сообщение #
Уже долгое время, периодически бросая, тешусь разработкой ИИ для ботов Армы. Начиная очередной раз, приходится
заново вспоминать направление работы и старые наработки. Вот надумал написать статью о ИИ для себя и для других, которым будет интересна эта тема.Изначально полет моей мысли заключался в следующем: в зависимости от количества и положения известных противников, выбирать один из созданных алгоритмов поведения для одного отделения. Моя фантазия рвалась дальше: Вот находится взвод на базе. И вот от одного из патрулей поступает информация о наличии противника. Запускаются дроны для определения количества и направления передвижения врагов. Исходя из известной скорости передвижения и расчетного времени организации обороны (засады), определяется место перехвата. Взвод делится на отделения и каждому из них определяется маршрут передвижения и конечное место расположения. Боты садятся в транспорт и направляются к месту перехвата.Прибыв на место,исходя из рельефа местности и направления появления противника, разворачиваются позиции обороны (засады). Бой Когда огневойконтакт состоялся, стороны уже знают о взаимном примерном количестве бойцов. Задача - поставить противника в такое положение, при котором, даже зная о расположении соперника, противник не сможет организовать оборону (атаку). В случае если противник имеет преимущество в живой силе или огневой мощи, организуется отход (бегство). Мысль была легка и логична, но разбилась о реалии – недостаток информации и кривые руки. Как оказалось,боты в Арме почти не умеют пользоваться укрытиями, а выбирать их не умеют совсем. И тут большая проблема: если для живого человека добежать до вон того укрытия и спрятаться за ним будет очевидным действием, то для того чтобы бот сделал то же самое, нужно за него перелопатить кучу информации за 0.5 сек. Более того, не всегда понятно в каком порядке мы выбираем действие, и какова его приоритетность в выборе. Кроме того неизвестна модель поведения бота заданная самими BISами. Я отмел в сторону эти упаднические настроения и поступил следующим образом. Т.к. скрипт управления группами не оправдал себя, я начал лепить скрипт для одного бойца. История моих метаний из стороны в сторону вряд ли кому-то нужна, важное тут другое. Для бойца основная цель – достичь заданной точки перемещения. Уничтожение всех известных врагов – дело вторичное. Причина – если боец перемещается в тыл врагу, то ему не нужно ввязываться в бой не имея желаемого преимущества в положении. Для достижения точки перемещения нужно рассчитать маршрут передвижения. Желательно перемещаться перебежками в направлении точки перемещения (не обязательно по прямой). Для этого нужно определить объекты-укрытия, которые нужно подбирать по высоте. Тут опять таки интересно: двигаться нужно к позиции за укрытием относительно наиболее опасного врага, которого в свою очередь нужно еще определить (по направлению оружия или по заданной ему цели). Кроме того опасный враг может измениться в момент достижения укрытия, т.е. производить выбор позиции за укрытием нужно в цикле. Добравшись до укрытия, нужно выбрать: двигаться дальше или действовать из-за укрытия. Ладно, если двигаться дальше (опять определять следующее укрытие в направлении точки перемещения). А если на бойца направлено оружие или тактическая обстановка изменилась, что тоже нужно держать на контроле (опять цикл!)? Тут необходим алгоритм поведения за укрытием. Для этого нужно знать координаты углов объекта или рассчитывать просматриваемость опасным врагом позиций возле бойца. Я пошел следующим путем: садил бойца на колено и анимацией передвигал его к ближайшему краю объекта, и, если точка рядом с бойцом оказывалась открытой и опасный враг не целился в него, то боец наклонялся и стрелял по цели. Если же опасный враг целился в бойца и боец был открыт но точка рядом с бойцом оказывалась укрытой, то боец отклонялся за укрытие.Все бы хорошо, но определение угла поворота объекта-укрытия относительно опасного врага или цели, определение координат точек за углами укрытия, выбор из них ближайших, выбор способа передвижения нагружает процессор (А если бот не один? А если их 10? А если 100?). Еще теплых слов просит воспроизведения анимации движения в сторону. Иногда бот просто елозит на месте. Зависит ли это от рельефа или от других неизвестных мне параметров? А вы говорите«добежать до вон того укрытия»! Ну пока как-то так. Сообщение отредактировал Индеец - Вторник, 28.02.2017, 14:13
|
| |||
Чат сайта |