Реализация AI горожан

Материал из Клуб любителей рогаликов
Перейти к: навигация, поиск

Данная статья была написана для RLNews Darren'а Hebden'а

Предисловие

Привет, и добро пожаловать в статью об искусственном интеллекте (AI) городских жителей.

Я Odin Jensen и я работаю над многопользовательской 3d-roguelike игрой, которая называется Curse of the Ancients. Я владелец небольшой компании, занимающейся программированием игр, которая называется Nuke Software и специализируется на предоставления инструментов для свободного программирования игр для разработчиков игр. У нас есть библиотеки/инструменты для Win32, DirectX и OpenGL. (Если вы хотите узнать больше, зайдите на ).

Как все вы вероятно знаете, всегда есть ваши типичные произвольные зеваки подобно Плачущему идиоту (Blubbering idiot). Это делается для некоторых забавных случаев и добавляет городу правдоподобия.

Только, как насчет людей которые работают в лавке? Почему они не идут домой, не ложатся спать или не идут на завтрак в гостиницу неподалёку, удерживая таким образом вас от покупки так нужных вам дополнительных факелов?

А это как раз то, о чём статья. Добавим вашему городу жизни.

Предполагаемые условия

Я предполагаю знание Си.

(Вы также можете написать мне на article_townai@nukesoftware.dk и спросить :)

Что нам нужно?

Итак, нам нужно, чтобы лавки открывались.

Сделайте их в комнатах вместо больших блоков с дверью, которая чудесным образом телепортирует вас в список снаряжения.

Ниже приведёна схема лавки. (Обратите внимание на прилавок). "S" представляет лавочника. Новая команда названная T + <DIR> позволяет разговаривать. (Вы должны, разумеется, стоять перед лавочником и быть в пределах 2-3 тайлов чтобы он вас услышал.) Это может вызывать постоянный список товаров, имеющихся в лавке или вы могли бы сделать что-нибудь более причудливое. Как пожелаете.

#############
#...#.......#
#..S#.......#
#...#........
#############

Нам также нужно создать горожан как новый объектный тип (Зависит от выбранной вами реализации). Также нужен метод, чтобы измерять текущее время дня. Теперь давайте переместим кого-нибудь из людей.

(В качестве примера я буду использовать обыкновенного владельца гостиницы.)

Движение людей с использованием метода предварительно сгенерированных схем AI

Чтобы определить движение мы сгенерируем схемы N,S,E,W,H,X N=Идти на север, S=Идти на юг, E=Идти на восток, W=Идти на запад, H=Встать, X=Конец схемы.

(Вы можете расширить эти схемы, добавив открывание/закрывание дверей, зажигание/гашение света и т.д. Главное - сама идея.)

Давайте сделаем простой пример: (Обычно вам нужно держать всех горожан в массиве или связанном списке)

 // Определить образец перемещения владельца гостиницы, 
 // для пути в гостиницу для ленча.
 unsigned char InnKeeper_GoToLunch[WALKPATT_MAXSIZE]={"NNSSEHWSSSWWWX"};

 // Переменная, чтобы следить положение владельца гостиницы в паттерне.
 char InnKeeper_CurPattPos=0;

 // Переменная, чтобы следить когда время пойти завтракать
 // Мы будем использовать строку для простоты.
 char InnKeeper_LunchTime[5]={"13:45"};

 // Bool чтобы следить, если владелец гостиницы собирается завтракать
 int InnKeeper_GoingToLunch=0;

Как вы видите, эта схема должна заставить владельца гостиницы, пойти на Север x 2, на Юг x 2, на Восток, подождать один ход, на Запад, на Юг x 3, на Запад x 3, конец схемы.

(ПОДСКАЗКА: Соберите все эту информацию на структурах/объектах для каждого жителя города. Это простой образец, и следовательно в нём не использованы наилучшие методы для оптимизации кода из-за чего возникает тенденция к усложнению для понимания.)

Вот образец игрового цикла для передвижения владельца гостиницы:

 while (!EndGame)
 {
 // Проверить, если время ленча
 if (isTime(InnKeeper_LunchTime)) InnKeeper_GoingToLunch=1;

 // Сдвинуть, если окей
 if (InnKeeper_GoingToLunch)

{

 // Переместить владельца гостиницы.
 switch(InnKeeper_GoToLunch[InnKeeper_CurPattPos])
 {
 case 'N' : InnKeeperY--; break;
 case 'S' : InnKeeperY++; break;
 case 'E' : InnKeeperX++; break;
 case 'W' : InnKeeperX--; break;
 case 'H' : break;
 case 'X' : {InnKeeper_CurPattPos=0;InnKeeper_GoingToLunch=0;};break;
 }

 // Продвинуть индекс паттерна
 InnKeeper_CurPattPos++;
 }

 // Выполнять прочие прочие функции игры.
 DoOtherStuff();
 } 

Теперь наш владелец гостиницы пришёл в гостиницу чтобы позавтракать. (Что странно, поскольку он вроде владелец этого заведения, но все-таки... :)

И в заключение моей статьи. Мне действительно нехватает этой особенности в Roguelike-играх, и я искренне надеюсь, что кто-нибудь осуществит это в своём варианте. Пожалуйста помните, что это было только быстрое разъяснение по данному вопросу. Я надеюсь вы все понимаете это и реализуете потенциал этой техники. Комментарии/предложения/баги высылайте на article_townai@nukesoftware.dk



Автор: Odin Jensen.
Источник: Implementing Interesting Townfolk AI.
Оператор ПРОМПТа: Дмитрий О. Бужинский [Bu], 19.05.2005.