Регистрация: Jan 2009
Сообщений: 1,651
|
Учим АИ колдовать
Будет тема во флейме, нет у нас отдельного раздела по алгоритмам, или по программированию компьютерных игр.
Представьте себе такую игру. Стоят друг напротив друга персонаж игрока и его оппонент, накапливают полоски маны, кидаются заклинаниями. Что-то типа японских рпг, final fantasy, что-то такое. Puzzle quest или galactix тоже в какой-то степени подходит под описание.
Вопрос в программировании АИ на использование этих самых заклинаний.
В первом подходе я решил сделать так. Каждое заклинание в наличии - это экземпляр класса заклинания. У него есть функция calculateEffectiveness, которая получает ссылку на всю сцену боя и возвращает некое число - насколько эффективно использовать заклинание в данных условиях. Некий приоритет, вес. По таймеру проходимся по всем заклинанием, сохраняем их вес в массив, сортируем на убываение, оставляем только заклинание с максимальным весом, если их несколько с одинаковым весом, то выбираем одно из них случайным образом.
На первый взгляд выглядит круто. Можно на ходу менять наборы умений монстров, что очень полезно, потому что баланс занимает много времени. Не надо писать логику для каждого монстра в отдельности. Но я предвижу так же проблемы в будующем.
1) АИ будет спамить дешевые заклинания, не давая себе накапить маны на дорогие. Ведь если на заклинание не хватает маны, то оно возвращает оценку эффективности 0.
Можно решить эту проблему тем, что приоритет эффективности не будет зависеть от того сколько маны в данный момент, а если ее не хватает, то АИ просто будет переходить в режим накопления маны для этого заклинания, но при этом если в какой-то момент окажется, что эфффективность другого заклинания перевесила текущее(скажем надо срочно подлечиться) и на него хватает маны, то будет использовано только оно.
2) Некоторые заклинания - часть комбы. Т.е. сначала нужно наложить усиление урона, а потом только стрельнуть.
Ну, в принципе, решаемо. Скажем, если усиление урона еще не наложено, то на его использование будет больший приоритет, чем на сам "выстрел" и наоборот. Но, если, скажем, выстрел убьет оппонента и без усиления, то его приоритет можно увеличить, чтобы он перевесил усиление урона.
3) Дорогое заклинание требует много зеленой маны и чуть-чуть красной. Зеленая на нуле, зато красной полная полоска. Есть мелкое заклинание, которое требует только немного красной маны, но АИ в режиме накопления маны на дорогое заклинание.
Опять же решаемо. Если полоска маны заполнена, пусть мелкое заклинание приобретет дополнительный вес. АИ сбросится и использует его.
4) Заклинания, которые наносят урон, в зависимости от того, насколько заполнена полоска маны. У них обычно некое минимальное требование, типа минимум 15 маны, но при 40 маны они наносят значительно больше урона.
Вот это чуть более тяжелый случай. Можно перевести АИ в какой-то особенный режим наколения, который накапливает маны не на использования, а пока не достигнет какого-то порога.
В целом похоже, что такая система справиться с любой ситуацией, но я боюсь, что все это лишний геморой, и простой набор if'ов для каждого конкретного монстра справился бы лучше.
А еще беспокоит то, что множество действий будет произведено несколько раз. Каждый вызов calculateEffectiveness каждого заклинания независимо друг от друга будет проверять одно и тоже: сколько жизней у оппонентов, хватает ли маны, какие эффекты наложены и все такое. С другой стороны заклинаний-то ну шесть штук на АИ максимум, и проверка будет, ну максимум раз в пол секунды, чаще нет смысла.
Ну вот какие-то сумбурные разглагольствования, я прошу прощения, мне, наверное, просто нужно было привести мысли в порядок =))))
__________________
мой пустой блог
|