ZX-Ревю 1991 №9 1990 г.

Adventure project - расчет характеристик персонажей в адвентюрных играх.


Темы статьи: Программирование  

ADVENTURE PROJECT

Расчет характеристик персонажей.

Задание начальных атрибутов Ваших персонажей - это только начало трудного пути установления правил, по которым они будут взаимодействовать друг с другом.

В предыдущей статье (№6, с. 122) мы начали рассматривать проект, связанный с похищением экспериментального образца "Часов Вселенной" и остановились там, где Инф, Ора и Ком обнаружили затонувшую яхту, на которой налетчики вывезли уникальный прибор. Инф и Ора ныряют в море и находят, что яхта охраняется двумя чудовищами - Крамом и Боргом. Дело идет к тому, что столкновения не миновать.

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

Общий подход в программе состоит из двух этапов:

1. На основе характеристик персонажей рассчитывается желательность схватки. Либо та, либо другая сторона могут в последний момент отказаться от боя.

2. Задаются начальные условия боя:

- в программных переменных устанавливаются имена тех, кто участвует в битве и какими преимуществами они располагают (наличие оружия или магических объектов).

Эти этапы взаимосвязаны. Компьютер рассчитывает желательность схватки, а затем задает ее начальные условия. Например, Инф не станет наносить удара по Оре. Имеет смысл вообще исключить такую возможность. Вы можете, скажем, встроить в программу блок, который будет игнорировать те команды пользователя, которые не согласуются с личными характеристиками персонажей и выдавать на экран какое-то сообщение.

В нашем примере сражение, скорее всего, неминуемо, поскольку проникнуть на яхту герои все-таки должны для успешного выполнения цели игры.

Итак, программа, занимавшаяся имитацией схватки, должна решать следующие 6

задач:

1. Сколько героев вступают в схватку?

2. Сколько противников им противостоят?

3. Соотношения в силе между персонажами.

4. Имеется ли оружие и как оно учитывается.

5. Пути выхода из битвы.

6. Условия победы.

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

Соотношения боевых характеристик персонажей зависят от их атрибутов, о которых мы тоже говорили в шестом выпуске. Нам необходимы формулы для того, чтобы из исходных атрибутов (эмоции, энергия, сила, интеллект, совесть, образованность) рассчитать производные характеристики, необходимые для битвы, такие, как гнев, мужество, решительность, трусость, самолюбие. Физическая сила может не рассчитываться, а браться из атрибутов.

Гнев, например, может формироваться из эмоций, силы и интеллекта. Мужество из энергии, силы и совести.

Если первичные атрибуты установлены в диапазоне (-10... +10), Инф, Ора, и чудовища могут иметь факторы, приведенные на рис. 1.

Инф не имеет отрицательных параметров и потому очевидно готов к схватке. Оре не так повезло, у нее может быть самолюбие как у львицы, но мужества и силы у нее, как у овечки.

Тем не менее, недостатки Оры могут быть парированы, если мы рассмотрим их противников. Брог и Крам - это пара хоть и могучих, но трусливых и неповоротливых монстров, мало способных выиграть хоть какое-то сражение.

Программа, приведенная на рис. 2 - это упрошенная процедура, описывающая схватку. Входящие формулы, описывающие такие факторы, как гнев или мужество, должны быть рассчитаны в другой подпрограмме, до битвы. Так гнев, например, может рассчитываться по формуле:

LET гнев = (^Т(эмоции*интеллект+ + сила)/NOATT) + 1

Формула рассчитывает среднее значение атрибутов, заключенных в скобках. NOATT -количество атрибутов, в нашем случае это 3.

Функция INT служит для округления результата. Тот недостаток, что "Спектрум" всегда при вычислении целой части числа выполняет округление вниз, можно парировать за счет прибавления единицы к полученному результату.

Когда все атрибуты рассчитаны. Вы можете перейти к сценарию битвы. Листинг, приведенный на рис.2, соответствует атрибутам, приведенным на рис.1, которые передаются через массив C, организуемый в строках 1...90.

Группа операторов IF...THEN в строках 110-120 занимается расчетом, имеют ли Инф и Ора достаточно сил для продолжения битвы.

Брог и Крам не имеют такой возможности последнего выбора, но Вы всегда можете изменить программу и поставить столько проверок, сколько хотите.

Переменная N$ в строках 110 и 120 выполняет роль статусной переменной. Она выставляется в строке 2 и до строки 110 является пустой.

Если кто-то из героев ранен и его сила падает ниже -9, его имя помещается в переменную N$ и передается в подпрограмму 2000. Здесь чудовища могут его убить, если их атрибуты им это позволяют.

Теперь рассмотрим действия, выполняемые в строках 160...190. Строка 160 сравнивает гнев, силу и мужество Инфа и Крама. Если показатели Инфа лучше, то он выигрывает раунд и оператор LET в конце строки исполняется таким образом, что его гнев возрастает, а сила уменьшаются, далее управление передается строке 180 для оценки второй пары.

Если Крам выигрывает раунд, то управление переходит на строку 170. где изменяются его атрибуты.

Строка 190 изменяет атрибуты Брога, если Ора проигрывает в схватке.

Когда эти расчеты и изменения произведены, программа возвращается на строку 100, откуда весь процесс вновь повторяется.

Подпрограмма в строке 2000 вычисляет, может ли противник убить героя, сила которого упала ниже -9. Если это произошло, то к имени героя, хранящегося в переменной N$, добавляется символ #.

Атрибут

Инф

Ора

Кран

Брог

Ловкость

5

9

-3

-3

Гнев

3

2

7

7

Самолюбие

5

9

9

6

Интеллект

7

2

4

4

Мужество

7

-4

-2

-3

Сила

4

-3

7

5

Рис. 1

1 REM Подпрограмма "СРАЖЕНИЕ"

2 LET N$ ="" 5 RESTORE 60 10 DIM C(4,6)

20 FOR k = 1 то 4

30 FOR m = 1 ТО 6

40 READ C(k, m)

50 NEXT m: NEXT k

60 DATA 5,3,5,7,7,4:REM ИНФ

70 DATA 9,2,9,2,-4,-3:REM ОРА

80 DATA -3,7,9,4,-2,7:REM КРАМ 90 DATA -3,7,6,4,-3,5:REM БРОГ

110 IF C(1,6)<-9 THEN PRINT "Инф не может больше сражаться": LET Ы$="ИНФ": GO SUB 2000 120 IF C(2,6)<-9 THEN PRINT "У Оры нет больше сил": LET N$="Оpa": GO SUB 2000 125 LET G$=""

130 IF C(3,6)<-9 OR C(4,6)<-9 THEN GO SUB 3000 140 IF G$="STOP" THEN STOP

160 IF (С(1,1)+С(1,2)+С(1,6)) > (C(3,1)+C(3,2)+C(3,6)) THEN LET C(1,2)=C(1,2)+1: LET

C(3,6)=C(3,6)-1: GO TO 200 170 LET C(3,2)=C(3,2)+1: LET C(1,6)=C(3,6)-1

180 IF (C(2,1)+C(2,2)+C(2,6))(C(4,1)+C(4,2)+C(4,6)) THEN LET C(2,2)=C(2,2)+1: LET

C(4,6)=C(4,6)-1: GO TO 180 190 LET C(4,2)=C(4,2)+1: LET C(2,6)=C(2,6)-1 200 GO TO 100 2000 REM Гибель героя.

2010 IF C(3,1)>4 AND C(3,5)>5 AND C(3,6)>3 THEN PRINT "Крам убивает Инфа": LET N$ = N$+"#" 2020 IF C(4,1)>4 AND C(4,5)>5 AND C(4,6)>3 THEH PRINT "Брог убивает Ору ": LET N$=N$+"#" 2030 IF N$="Инф#" THEN LET C(2,1)=C(2,1)-2: LET C(2,2)=C(2,2)+1: LET C(2,5)=C(2,5)-1 2040 IF N$="0pa#" THEN LET C(1,1)=C(1,1)-2: LET C(1,2)=C(1,2)+1: LET C(1,5)=C(1,5)-1 2050 RETURN

3000 REM Гибель монстра

3010 IF C(3,6)<-9 THEN PRINT "Крам убит": LET G$="STOP" 3020 IF C(4,6)<-9 THEN PRINT "Брог убит": LET G$="STOP" 3030 RETURN

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

Последняя подпрограмма, начинавшаяся в строке 3000, проверяет, не пора ли погибать монстрам. То же уменьшение сил, которое убивает положительного героя, может убить и отрицательного.

Переменная G$, введенная в строке 125, участвует в этой процедуре. G$ принимает значение "STOP", если Брог умирает и после возвращения в главную часть программы заканчивается ее работа в строке 140. Когда монстры уйдут, Вы можете провести своих героев на яхту.

Приведенная выше распечатка текста программы может быть еще и еще более усовершенствована.

Так, в строках 110 и 120 персонаж выбывает из борьбы только если его силы падают ниже -9. Вы можете принять здесь в рассмотрение и фактор мужества, используя для этого логический оператор OR.

Еще одним дополнением может быть, например, кинжал, лежащий у двери капитанской рубки. Здесь возможны варианты. Может быть, один их героев подберет кинжал, пока другой ведет схватку, а может быть Вы решите, что его подбирать надо только когда оба противника подавлены.

Добавив несколько новых строк и строк PRINT. Вы придадите программе элемент неожиданности, совершенно очевидный дух искусственного интеллекта, а Инф и Ора получает дополнительный шанс остаться в живых.

Такие объекты, как кинжал, легко хранить в памяти программы и несложно организуется их перемещение их вместе с персонажами. В распечатке на рис. 3 показан один из методов хранения объектов в локациях до того, как персонажи их подобрали. Каждая локация имеет группу предметов и хранит их в переменной, скажем B$. Как только изменяется локация, изменяется и содержимое переменной. Если в данной локации предметов нет, то возвращается пустая строка. Размещение многих объектов в одной строковой переменной вместо массива позволяет значительно снизить расход памяти компьютера.

Формат, в котором названия объектов хранятся в b$, довольно очевиден и может обслуживаться парой строк.

Переменная начинается с астерикса (*), им же отделяются объекты друг от друга.

Первая буква в названии объекта указывает на его тип.

О - оружие

П - обычный предмет

В - враждебное существо.

Если бы в Вашей программе участвовали товарно-денежные отношения, можно было бы ввести и еще один класс ценностей, отнеся к ним драгоценные камни, золото, монеты, украшения и пр. Очевидный класс составляют магические предметы.

Следующие символы содержат информацию о названии объекта.

10 LET b$="*пяхта*окинжал*вБрог*вКран" 20 INPUT а$ 25 LET с$=а$(1 ТО 3) 30 LET k=1

50 IF b$(k)="*" THEN GO ТО 90

60 IF k=LEN (b$) THEN PRINT "Объект не найден": GO ТО 20 70 LET k=k+1 80 GO ТО 50

90 LET m=k+2: LET c=m+2

100 IF c$=b$ (m ТО c) THEN GO TO 120

110 GO ТО 70

120 IF b$(k+1) = "о" ™N PRINT а$; ":"; "Вы нашли оружие"

130 IF b$(k+1)="п" ТНЕN PRINT а$; ":"; "Вы нашли предмет"

140 IF b$(k+1)="в" ТНЕN PRINT а$: ":": "Перед Вами появился противник"

150 GO ТО 20

Переменная b$ задается в строке 10.

В строке 20 вводится название предмета и в строке 25 оно "урезается" до трех символов. Цикл в строках 50...80 ищет появление астерикса. Когда он найден, выполняется переход на строку 90. где символ за символом сканируется символьная переменная.

В строках 120. .. 140 определяется тип объекта и информация об этом доводится до играющего.

Если же этот объект не найден в b$, то сообщение об этом генерируется в строке 60.

А теперь продолжим наш проект. Когда Инф и Ора обнаружили кинжал, подняли его, победили чудовищ и прошли в дверь, их ослепил яркий свет. Они оказались в подземном городе короля Кельроса. Их захватили в плен и повели на допрос к королю.

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

(Продолжение следует).




СОДЕРЖАНИЕ:


  Оставте Ваш отзыв:

  НИК/ИМЯ
  ПОЧТА (шифруется)
  КОД



Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Humor Park - Сказки на ночь, КВН, армейские приколы...
User'am - 64 Килобайта о FIDONet.
Новости Таш-ZXNet - В январе месяце в ТашZXnet начнет свою жизнь первая эхо-конференция Ташкентской синклеровской сети.
Бук - из жизни водопроводчиков.
Intro - вступительное слово.

В этот день...   27 апреля