Программирование с нуля - это совсем просто! 139) Программирование ролевой игры: Квесты-3
Школа программирования
139) Программирование ролевой игры: Квесты-3
Кстати, как-то незаметно, наша рассылка стала Золотой. С чем мы друг друга и поздравляем :)
Последний выпуск по ролевой игре был N 133.
Теперь приступим к формированию конкретного квеста убийства монстра. Нам требуется найти хотя бы одного здорового монстра, и каким-то способом отделить его от остальных. Самый простой способ - модифицировать имя монстра (поле Name), например, дополнив его оригинальным именем, что добавляет игре шарм, внося индивидуальные черточки.
Существует немало алгоритмов генерации внешне "осмысленных" имен, достаточно гладко звучащих и читающихся на русском языке, и в то же время не несущих никакой смысловой нагрузки. Рассмотрим такой алгоритм на нашем примере.
Пусть функция GenerateMonsterName выдает случайное имя. Эта функция будет определена в модуле Quest, где она и востребована. Если внимательно посмотреть на слова русского языка, то очень многие из них можно свести к схеме чередования гласных и согласных букв - чаще всего используется одна гласная (гораздо реже - две) и одна или две согласные. Тогда определим эти четыре базовые элемента слов "гласные" (одна гласная в 90% случаев и две гласные в 20%) и "согласные" (одна согласная в 75%, две согласные в 25%), и
просто будем их чередовать несколько раз (случайно, от трех до шести). Получившееся в результате и будем считать именем
Вот полный текст этой функции:
{ ----------------- } function GenerateMonsterName: string;
function GetNextS( g: Boolean ): string; var s: string;
k,i,n: Integer; begin if g then begin if random(10)=0 then k := 2 else k := 1;
s := ' ' ; for i := 1 to k do begin
n := random(length(sGlasn))+1;
s := s+sGlasn[n]; end; end else
begin if random(100)<75 then k := 1 else k := 2;
s := ' ' ; for i := 1 to k do begin
n := random(length(sSoglasn))+1;
s := s+sSoglasn[n]; end; end;
GetNextS := s; end;
begin
G := random(2)=0;
n := 3+random(4);
s := ' ' ; for i := 1 to n do begin
s := s + GetNextS(G);
G := not G; end;
GenerateMonsterName:=s; end;
Разберем его более подробно. Сама функция довольно коротка. Переменная G определяет, с какого элемента - "гласного" или "согласного", начнется имя. Ведь это важно - случайно менять тип первой буквы и всю следующую за ней последовательность. Переменная n хранит число элементов в слове (3-6), после чего в цикле n раз значение строки s наращивается с помощью функции GetNextS, которая возвращает один элемент - "гласное" или "согласное". Эта функция локальна, так как нужна лишь для текущих нужд. Ее параметр g определяет
запрос гласного или согласного элемента, а переменная k рассчитывается как длина этого элемента (один или два символа). После этого из констант, раздельно хранящих все (почти все - мягкий и твердый знак и букву "ы" мы исключили) гласные и согласные буквы, случайным образом извлекается n-й символ - k раз.
Данная функция нужна нам, чтобы придать оригинальное имя монстру, выбранному для уничтожения. В процедуре GenerateQuest он уже определен - осталось лишь модифицировать его имя (поле Name; только существующее название, фактически порода монстра, не уничтожается, а для полноты картины лишь дополняется "человеческим" именем) и сформировать значение квеста - свободного элемента массива Quests. Денежный приз и опыт сформируем в зависимости от уровня героя и числа пунктов опыта, которые надо на этом уровне набрать
(15-30% от максимума). Также необходимо запретить использовать одного и того же монстра в качестве жертвы в нескольких квестах.
{ ----------------- } procedure GenerateQuest(qi,hn: Integer; qt: TQType); var i,j: Integer; label NextMon; begin for i := 1 to MaxMonsters-MaxNPCNum do if Monsters[i].HP > 0 then begin for j := 1 to MaxQuests do if Quests[j].TargetId=i then goto NextMon;
Денег в случае успеха герой получит соответственно текущему уровню, умноженному на 80-100 золотых, а опыта - от 15 до 30% от максимально возможного на данный момент (MaxExp). В момент получения квеста герою выдается короткое сообщение, которое по большому счету не очень соответствует важности момента, и доведение его до ума (в частности, можно и мирному персонажу дать имя) оставляем читателю.
Отметим, что к данному моменту в программе могут возникнуть проблемы с объемом доступной памяти. Сегмент данных в ДОС-приложениях составляет 64 килобайта :) , и возможно за счет констант и нововведений, связанных с квестами, этот объем к данному моменту оказался полностью исчерпан. Можно сократить размер карты (уровня) - с 32*32 до 30*30 элементов. В дальнейшем, когда мы перенесем эту программу в Windows с минимальной модификацией кода, такие проблемы снимутся автоматически.
В следующем выпуске детализируем информацию о квестах.
Исходный код текущей версии для Turbo Pascal (всегда проверен и работоспособен, главный файл - main.pas):
Учебный курс рассчитан не только на разработчиков, но и на всех тех, кто хочет стать ИТ-менеджером. Для этого как минимум нужно иметь общее представление о современных технологиях разработки и их истории и владеть соответствующей терминологией.
В книге описаны десятки технологий, каждой из которых посвящены отдельные книги. Таким образом, купив одну мою книгу, вы существенно сэкономите :) В книге полностью описан язык Delphi (версия 2006, полностью совместимая с Turbo Delphi) для обеих платформ - Win32 и .NET. Охвачены также темы работы с файлами на этих платформах, создания файл-серверных, клиент-серверных, распределенных приложений, веб-программ (Indy, ASP.NET, веб-сервисы). Описаны языки SQL и OCL. Немало глав посвящены истории программирования
и различных технологий. Особое внимание уделено созданию программ с помощью технологии ECO и языка моделирования UML - программы фактически рисуются, и теперь даже для создания корпоративных приложений и их переноса в Интернет не обязательно знать программирование!
Отдельная часть отведена технологиям организации групповой работы, управления требованиями, контроля версий, локализации и тестирования.
Тут подробнее про книгу.
Другие мои книги, которые пока доступны в продаже: