Здравствуйте, господа!
Подскажите мне, пожалуйста, реализуема ли на TADS следующая команда:
"попросить Тимофея отвлечь продавца".
Глагол "попросить" сейчас определяется такmodify askVerb
verb = 'попросить'
;
Заранее спасибо.
Неактивен
Извиняюсь, что не привожу кода, но самым простым путем будет заменять "попросить *существительное*" на "*существительное*,". Это приведет предложение к принятому в ТАДСе синтаксису. Вставить этот хак, скорее всего, придется в функцию предпарсинга.
Неактивен
Сделай глагол "отвлекать" и обыграй реакцию на команду "Тимофей, отвлеки продавца" (реакцию на действие главным персонажем тоже сделай). TADS понимает команды актёрам (Inform тоже), это знают игроки, знакомые с жанром. Для новых игроков не забудь вставить в "помощь" упоминание и пример, как отдавать команды актёрам.
Если не разберешься, спрашивай. Напишу подробнее.
Неактивен
В TADS-мануале совершенно точно есть именно такой пример - преобразование фразы "попросить актера сделать что-либо" в "актер, сделай что-либо", но прямо сейчас найти не смогу. Ищи где-то в главах, посвященных синтаксическому анализатору.
upd. См. в английском варианте мануала, глава 6 "The Parsing Sequence", , в разделе, посвященном функции preparseCmd. Вот текст примера (на английском):
Here’s a sample implementation of preparseCmd. This implementation converts commands
in the format “tell actor to command” to the standard TADS notation for these commands, “actor, command.”
#pragma C+
preparseCmd: function(cmd)
{
local i, tot, to_loc, actor, the_rest;
tot = length(cmd);
/* check to see if it starts with "tell" */
if (tot > 3 && cmd[1] == 'tell')
{
/* see if there's a word "to" */
for (i = 1, tot = length(cmd) ; i <= tot ; ++i)
{
if (cmd[i] == 'to')
to_loc = i;
}
/* if there's a "to", convert the command */
if (to_loc != nil && to_loc > 2)
{
/* find the parts before and after the 'to' */
for (i = 2, actor = [] ; i < to_loc ; ++i)
actor += cmd[i];
for (the_rest = [], i = to_loc + 1 ; i <= tot ; ++i)
the_rest += cmd[i];
/* convert it to "actor, command" */
return actor + ',' + the_rest;
}
}
/* otherwise, process the command as normal */
return true;
}
Из русского мануала я его убрал, заменив на описание работы preparseCmd в RTADS.
Отредактировано uux (22.11.2007 09:40)
Неактивен
Большое спасибо за ответы.
Попробую реализовать преобразование фразы, как предложили GrAnd и uux.
Вариант с использованием стандартного синтаксиса "Тимофей, отвлеки продавца" сделаю только если не получится первый способ, потому что в моей игре нигде команды такого типа не используются, не хотелось бы быть непоследовательным.
Как реализую - напишу что получилось.
Неактивен
Итак, как все разрешилось.
Была написана функция preparseTell, которая преобразует строки из вида "попросить Тимофея отвлечь продавца" к виду "Тимофея, отвлечь продавца" (выглядит криво, но парсер всё понимает, спасибо GrAnd'у :-)preparseTell: function(str)
{
local lst, len, actor, rest, i, types, o;
lst := parserTokenize(str);
types := parserGetTokTypes(lst);
len := length(lst);
if (len >= 3)
{
o := parserDictLookup([] + lst[1], [PRSTYP_VERB]);
if (length(o) = 0 || o[1] != askVerb)
return str;
if ( (types[3] & PRSTYP_PREP) != 0 )
return str;
actor := lst[2];
rest := '';
for (i := 3; i <= len; i++)
rest += lst[i] + ' ';
return actor + ',' + rest;
}
return str;
}
Функция проверяет, является ли третье слово предлогом, чтобы отличать фразы
"попросить Тимофея отвлечь продавца" и
"попросить Тимофея о помощи".
Потенциальная засада возникает, если обращаться к актеру двумя словами, напр. "Иван Иванович" или имя+прилагательное, но у меня в игре нет ни того ни другого, поэтому данное решение можно считать условно безопасным.
Эта функция затем "вклинивается" в самый конец стандартной функции preparse в файле advr.t:
comStr := preparseTell(comStr);
Вроде бы работает.
Неактивен
Браво! (Растроганно смахиваю слезу со щеки)
Теперь я знаю, что могу спокойно уйти на покой, так как есть люди, способные дорабатывать систему.
Неактивен