В примере из демонстрационной игры (http://rtads.org/man/TADSSMPL.HTM), следующая штука выходит:
Чтобы взять череп с пьедестала, нужно предварительно положить на него камень, тогда не сработает ловушка... но, если забрать только что положенный камень, ловушка так же не сработает:), ведь, по логике самого метода, при отсутствии на пьедестале объекта, вышеназванного бага, не должно быть... Сам метод:
doTake(actor) = { if (self.location <> pedestal or smallRock.location = pedestal) { pass doTake; } else { "Едва ты успеваешь поднять череп, как из стен вылетает целая туча отравленных стрел! Ты пытаешься увернуться от них, но их слишком много!"; die(); } }
Отредактировано Kephra (09.04.2011 19:52)
Неактивен
У меня вопрос по поводу игры-примера для информа, (http://rinform.stormway.ru/tutor/01-Heidi.html)
Object branch "надежн/ый толст/ый сук/" top_of_tree
Наверное такая логика у парсера, что если сказать "положить гнездо на суку/суки/сука" и т.д. парсер это схавает и положит гнездо, но только на сук
>положить гнездо на суки
Ты кладёшь птичье гнездо на надежный толстый сук.
даже если поменять в коде "сук/" на "сук" что, по теории должно отменить варианты окончания слова, но и это не помогает... Да, это всё пустяки, не стоит наверное обращать внимания, хоть и понимаю, что не каждому второму придет в голову извращаться так с объектом, но все же, если есть метод, хорошо бы его знать, и по случаю применить.
Неактивен
uux написал:
Kephra, еще раз призываю выслать мне код на мыло. Я честным образом скачал ту самую демо-игру из раздела игр сайта RTADS: http://rtads.org/man/GOLDSKLR.zip - оно пашет именно так, как надо, т. е. если положить камень на пьедестал, а потом убрать и взять золотой череп, ловушка срабатывает.
У меня нет вашего мыла... я васлал иходник в ЛС, но, вы меня не так поняли, я опишу последовательность действий: берем камень, ложим на пьедестал, забираем череп, ловушка не срабатывает, обратите внимание - берем камень с пьедестала и ловушка не срабатывает, хотя на пьедестале ничего не лежит, камень и череп у нас в руках.
>Пещера
взять камень
Взят.
>Пещера
положить на пьедестал
(мелкий камень)
Готово.
>Пещера
взять череп
Взят.
>Пещера
взять камень
Взят.
>Пещера
инв
У тебя имеется:
золотой череп
мелкий камень
>Пещера
Отредактировано Kephra (10.04.2011 19:39)
Неактивен
uux написал:
И, раз уж я опять вернулся к этой теме, хочу обратить внимание еще вот на что. В RTADS имеется замечательный генератор падежных форм (файл generator.t в архиве с библиотеками), который позволяет в разы сократить рутинную работу по набиванию лексических свойств для объектов в игре. К сожалению, роль генератора пока не отражена должным образом в документации, но работа с ним достаточно подробно описана в комментариях в самом файле. И, конечно, если возникнут трудности с пониманием, Вам с удовольствием помогут;).
Спасибо, интересно, я поработаю с ним, если возникнут вопросы, обязательно задам:).
Неактивен
yandexx написал:
Слеши в имени объекта используются только при выводе названия.
При вводе же рассматриваются ключевые слова указанные в перечислении name, с различными окончаниями. В обоих случаях учитывается род объекта (male, female, neuter, plural).
При вводе просматриваются грамматики для глаголов, заданные в библиотеке или вручную, и падеж учитывается. Однако там где он не столь важен, сработает существительное и в любом падеже.
Ага спасибо, для меня новичка, это пока сложно для понимания... но что-то, да и дошло (если верно), значит, прописать правильное падежное склонение для отдельного слова-существительного, можно, но только в соответствующей библиотеке? А если возможно, то как? Можете привести пример, именно для нашего "сука"...
Неактивен
uux написал:
надо доработать метод doTake камня... задание для самостоятельной работы;), помощь в которой, если она понадобится, Вам конечно же окажут;).
Я об этом подумал сразу же как увидел "баг", но, если в комнате лежит еще несколько камней, и других объектов, в сумме может набраться до 10/20 объектов в игре немного большей игры-примера, не прописывать же в самом деле для каждого, один и тот же метод? Куда логичнее прописать метод для пьедестала, и тогда можно оставлять на нём любой объект и ловушка не сработает, но и в этом случае имеется "баг", если заменить череп спичечным коробком, пёрышком, или дохлой блошкой и тогда, ловушка так же не сработает... Или в ТАДС можно задать объекту, свойство веса?
upd
Я кажется понял, можно для пьедестала прописать метод, в котором перечислить по своему усмотрению, те объекты, которыми можно заменить череп... но как это сделать? Ладно, я попытаюсь сам дойти.
Отредактировано Kephra (10.04.2011 21:21)
Неактивен
goldSkull: item ... ... location = pedestal doTake(actor) = { if (self.location <> pedestal or /* Меня уже сняли с пьедестала? */ smallRock.location = pedestal) /* А может быть, камень лежит на пьедестале? */ { pass doTake; /* Да (хотя бы одно из вышеприведенных условий */ /* верно) - берем череп как обычно */ } else /* Нет - срабатывает ловушка! */ { "Едва ты успеваешь поднять череп, как из стен вылетает целая туча отравленных стрел! Ты пытаешься увернуться от них, но их слишком много!"; die(); } }
Нафига эта проверка self.location <> pedestal ??? Как это вообще понять умом человеческим?
Всё и так работает без этого, если оставить проверку только на камень. Пробовал брать череп, выбрасывать из инвентаря на пол, поднимал его и снова ставил на пьедестал, потом снова брал. Брал с камнем на пьедестале и без него, в последнем случае погибал как надо. Во всех остальных случаях так же всё работало.
UPD
Ааааа... всё, понял. Если камень не на пьедестале, а череп на полу и если поднять его, то сработает die() без self.location <> pedestal. Одно не понятно что это за стрелочки больше-меньше? Они эквивалентны оператору «!=» в Си?
Отредактировано Kephra (30.08.2018 02:40)
Неактивен
Nikita написал:
Вообще в "Золотом черепе" этот пазл реализован не лучшим образом. Во-первых, смещение черепа лучше регистрировать через метод moveInto в его объекте (это любое изменение location, а не только взятие предмета в руки)...
Я сделал так:
moveInto(self) = { if (smallRock.location = pedestal) { pass doTake; } else { "Едва ты успеваешь поднять череп, как из стен вылетает целая туча отравленных стрел! Ты пытаешься увернуться от них, но их слишком много!"; die(); } }
И теперь без «self.location <> pedestal» если взять череп с пола при отсутствии камня на пьедестале, die() не срабатывает. Так код выглядит намного лучше: смотрю и радуюсь .
UPD
Что такое метод русским языком? Технически, это функция?
UPD
Да согласно мануалу: метод эта функция, только он является частью объекта и самостоятельно (вне объекта) не используется, в отличии от функции.
Отредактировано Kephra (30.08.2018 12:44)
Неактивен
Nikita написал:
Нет, это не совсем верно:
Да, это СОВСЕМ не верно. Даже не знаю, как я вчера смог взять череп с пьедестала (было 4 часа бессонного утра), когда уже сегодня на этом моменте игра бесконечно зациклилась — видимо на pass doTake — и сообщения «Взят (череп)» посыпались на экран, пока интерпретатор не понял, что происходит, и не выдал сообщение об ошибке.
Отредактировано Kephra (30.08.2018 17:27)
Неактивен
Nikita написал:
Во-первых, self - это ключевое слово, которым обозначается сам объект для того, чтобы обратиться к нему из самого себя. Здесь же аргументом для метода moveInto может быть любой объект, куда мы перемещаем череп, поэтому там нужно использовать некую нейтральную локальную переменную, например, obj.
Я не совсем понимаю как работает этот метод. Зачем вообще передавать что-то в него? Это же функция? Как в «doTake» так и в «moveInto» можно передать любой локальный, нейтральный, пустой объект вида «asdasd», но если этого не сделать, интерпретатор при срабатывании такого метода, выдаст ошибку. Но дело в том, что совершенно неважно что я туда впишу. Однако в мануале-то «actor» используют в качестве аргумента «doTake», зачем это делать, — не понятно, но поясняется следующее: «Определение атрибута doTake использует в качестве аргумента персонаж (actor), который пытается взять объект.» и «Система вызывает doTake каждый раз, когда игрок пытается взять объект.» Эти оба пояснения в документации следуют друг за другом. Каждое, говорит совершенно о разных вещах, но воспринимается как — об одном. Думается, будто надо использовать исключительно тот аргумент с которым будет взаимодействовать объект (в нашел случае золотой череп с актером). Иначе, ничего не будет работать. Но это не так, поэтому пояснение: «Определение атрибута doTake использует в качестве аргумента персонаж (actor), который пытается взять объект.» — даёт ложное представление, причем не объясняется зачем это делать.
Отредактировано Kephra (30.08.2018 21:41)
Неактивен
Nikita написал:
По-хорошему все внутренние проверки и прочие операции, завязанные на персонажа, выполняющего действие, надо выполнять именно в отношении объекта в переменной actor, чтобы в сложных случаях не получилось, что мы уже играем за Серого волка, а последствия действий по-прежнему происходят в отношении Красной шапочки.
То есть, если Красная Шапочка возьмёт череп с пьедестала, до этого не поместив на него камень, а в методе doTake Серый Волк, то погибнет он вместо Шапочки?
Я только что в doTake для проверки вписал пьедестал. Скомпилировал. Пошел в пещеру, взял череп и не умер — все стрелы были выпущены в пьедестал . Поменял на «me» и умер как полагается.
Неактивен
Nikita написал:
Ну и ещё раз обращаю внимание, что аргумент doTake вы можете назвать не actor, а хоть abcde. Это ничего не изменит, так как это всего лишь имя локальной переменной, в которой входные данные метода будут доступны внутри его тела. Меняя имя этой переменной вы никак не влияете на то, что туда передаёт движок, а передаёт он там всегда объект персонажа. Можете в этом убедиться, добавив в метод действия вот такую строку
Локальная переменная? Не указатель на объект?
Nikita написал:
Вместо упражнений в остроумии лучше чётче сформулируйте, что именно вам непонятно, если хотите разобраться, а не просто побалагурить на форуме.
Побалагруить!? Да я вчера весь день занимался тем, что этот череп с пьедестала туда-сюда таскал.
Вчера, я вписал pedestal в аргумент doTake, ожидая, что стрелы прилетят в него, — в случае, если не подложить камень... Так и произошло! Я взял преспокойно золотой череп, продал его, а на вырученные деньги улетел на Мальдивы ! А потом проснулся и понял: стрелы не улетали ни в какой пьедестал. Потому что аргумент я назвал так же pedestal и все проверки в теле метода, — лежит ли камень и череп на пьедестале, — производились уже с локальной переменной pedestal, а не с оригинальным объектом pedestal. Непонятно только почему в этом случае череп можно взять с пьедестала безнаказанно, если локальная переменная pedestal имеет состояние объекта pedestal на момент, когда на пьедестале лежит только череп — то есть игрок все равно должен погибнуть, но это не происходит. Всё, надо выходить из этой пещеры, а то совсем кукухой поеду...
doTake(pedestal) = { if (smallRock.location != pedestal && self.location = pedestal) { die(); } pass doTake; } ;
Отредактировано Kephra (02.09.2018 20:11)
Неактивен
Оказывается, метод отлично себе работает без аргументов, надо только после названия не ставить скобки. Я думал они обязательны, как в Си:
Правильно
doTake =
{
...
...
}
;
Не правильно
doTake ()
=
{
...
...
}
;
С пустыми скобками игра не компилировалась, наверное потому что в doTake первым аргументом должен быть какой-то персонаж из игры. Но, можно и не передавать, вышеприведенным способом.
UPD
Ага, игра-то компилируется, но уже в самой игре — если взять череп, интерпритатор выдаст ошибку. Всё же, передать в атрибут actor в advr.t надо обязательно что-то.
Отредактировано Kephra (02.09.2018 21:10)
Неактивен
Мне понятно, что первый аргумент в doTake это actor (смотрел код doTake в advr.t), но разве мы вот таким способом передаём???doTake (Красная шапочка) ={
...
...
}
Это же только объявление функции/метода?
А вот так уже передаётся:doTake (Красная шапочка, колобок, серый волк);
UPD
Или это особенность языка ТАДС? Из-за того что этот метод есть в advr.t, он работает не стандартно?
Отредактировано Kephra (02.09.2018 21:01)
Неактивен
То есть, даже если я захочу передать в doTake другой объект вместо актёра, например камень, (smallRock), просто вписав его в аргументы doTake, то это не произойдёт? Система создаст локальную переменную/объект smallRock в которой всё равно будут данные объекта персонажа, поскольку таков шаблон в advr.t. Собственно, чтобы doTake принимал отличный от actor аргумент/ты, надо править этот шаблон и его родителя. Я не собираюсь пока подобным заниматься. Но это даёт мне понимание, — как устроена логика языка. От того, я и пробую игрушку на вкус, на прочность, в общем делаю всякие на первый взгляд бестолковые вещи.
Лучше чётко опишите то, что именно вы хотите реализовать в игре, пытаясь шаманить с аргументами методов действий. Вам просто объяснят, как именно это сделать правильно, и это будет намного продуктивнее и нагляднее.
Мы пока учимся, а о замыслах — потом.
Отредактировано Kephra (03.09.2018 01:39)
Неактивен