Людям свойственно ошибаться. При наборе, к примеру, мы частенько делаем опечатки. В этом случае текстовые процессоры подчеркивают неизвестные слова, а поисковая система Google предлагает вариант исправления для неправильного слова.
Интерфейс всех парсерных игр основан на вводе текста, причем количество введенного игроком текста за всю игру может быть весьма существенным. Естественно, не обходится без ошибок. «К сожалению, слово "деференциал" мне неизвестно.» Довольно странным выглядит то, что эта проблема никак не решается в этой абсолютно текстовой среде, где, вроде бы, сам бог велел (а ведь сейчас проверку орфографии встраивают даже в браузеры), тем более, что никаких словарей для проверки таскать за собой не надо – словарь, вот ведь он, заботливо объявленный автором в самой игре!
Поэтому я решил написать нечто вроде spellchecker для RTADS.
Он исправляет опечатки следующих типов:
1) пропустили букву
>о холдильник
2) набрали лишнюю букву
>о холодлильник
3) перепутали буквы местами (частенько случается при наборе)
>о холдоильник
4) ошиблись в букве
>о халодильник
После того, как вы нажмете Энтер, на экране, вместо раздражающего«К сожалению, слово "халодильник" мне неизвестно.»
вы увидитеВозможно, вы имели в виду «холодильник».
Высокий белый холодильник. На боковую стенку налеплен магнит в виде головы панды (довольно дурацкий, верно?).
Мой spellchecker исправляет только одну ошибку на слово (т.е. «халодильник» он исправит, а «халадильник» уже нет). Это связано с объемом вычислений. Для слова из 7 букв выполняется 478 проверок на одну ошибку, соответственно, для проверки на 2 ошибки необходимо производить 478^2 = 228484 проверок, что конкретно затормаживает игру. К тому же, по статистике Google, из всех ошибок при вводе ошибки в одну букву составляют более 90% случаев, так что большинство опечаток мой spellchecker исправит.
Спелчекер универсален – он использует активный словарь текущей игры, обеспечивая тем самым 100% релевантность исправлений и минимум ложных срабатываний :-).
Чтобы подключить spellchecker к вашей игре на RTADS, сделайте следующее (процесс описан для файлов 24 релиза библиотек, но, скорее всего, заработает и на более ранних):
1. Откройте файл advr.t, найдите там функцию preparse и в самый ее конец, но перед “return comStr;” воткнитеglobal.prevCommand := comStr;
2. Откройте файл erroru.t и в самый конец файла добавьтеparseErrorParam: function(errornum, string, ...)
{
local correct, pos, newstr;
if (errornum != 2)
return parseError(errornum, string);
correct := spellcheck(getarg(3));
if (correct)
{
pos := reSearch(getarg(3), global.prevCommand);
newstr := substr(global.prevCommand, 1, pos[1] - 1) + correct + substr(global.prevCommand, pos[1] + pos[2], length(global.prevCommand));
"Возможно, вы имели в виду <b>«<<correct>>»</b>.<br><br>";
parserReplaceCommand(newstr);
}
return parseError(errornum, string);
}
spellcheck: function(word)
{
local ruslet := 'абвгдежзиклмнопрстуфхцчшщьыъэюя';
local englet := 'abcdefghijklmnopqrstuvwxyz';
local curlet := ruslet;
local i, j;
local variants = [];
local found;
//узнаем, английский ли это текст или нет
for (i := 1; i <= length(word); i++)
{
for (j := 1; j <= length(englet); j++)
{
if (substr(word, i, 1) = substr(englet, j, 1))
{
curlet := englet;
goto next;
}
}
}
next: ;
//пропущенные буквы
for (i := 1; i <= length(curlet); i++)
{
for (j := 0; j <= length(word); j++)
{
variants += substr(word, 1, j) + substr(curlet, i, 1) + substr(word, j + 1, length(word));
}
}
//лишние буквы
for (i := 0; i < length(word); i++)
{
variants += substr(word, 1, i) + substr(word, i + 2, length(word));
}
//неправильные буквы
for (i := 1; i <= length(curlet); i++)
{
for (j := 0; j < length(word); j++)
{
variants += substr(word, 1, j) + substr(curlet, i, 1) + substr(word, j + 2, length(word));
}
}
//перепутанные местами буквы
for (i := 0; i < length(word) - 1; i++)
{
variants += substr(word, 1, i) + substr(word, i + 2, 1) + substr(word, i + 1, 1) + substr(word, i + 3, length(word));
}
for (i := 1; i <= length(variants); i++)
{
found := parserDictLookup([] + variants[i], [PRSTYP_NOUN]);
if ( length(found) > 0)
return variants[i];
}
for (i := 1; i <= length(variants); i++)
{
found := parserDictLookup([] + variants[i], [PRSTYP_VERB]);
if ( length(found) > 0)
return variants[i];
}
for (i := 1; i <= length(variants); i++)
{
found := parserDictLookup([] + variants[i], [PRSTYP_ADJ]);
if ( length(found) > 0)
return variants[i];
}
return nil;
}
Все! Компилируйте игру и можете пробовать.
Из недостатков спелчекера стоит отметить то, что он не занимается подбором форм слов, поэтому возможно неграмотное с точки зрения русского языка исправление написания, например «осмотреть сантехникв» (хотели написать «осмотреть сантехника») будет исправлено на «осмотреть сантехник». К сожалению, это никак не исправить.
Просьба протестировать работу на имеющихся у вас проектах RTADS. Пожелания и предложения приветствуются.
И напоследок, может кто-нибудь знает, как убрать вывод сообщения [TADS-1014: 'abort' statement executed] при каждом вызове функции parserReplaceCommand?
RTADS – лучшая платформа!
Неактивен
Прикольно. Как вариант решения проблемы с выбором формы слова - проверить его на схожесть с sdesc, rdesc, vdesc....
Если совпадает - использовать подходящую форму. Правда, в них может быть существительное с прилагательным.
Неактивен
Потестировал. Ощибка появляется внутри parseErrorParam при вызове parserReplaceCommand(newstr);
Почему - не знаю.
Также обнаружил мощный спойлерный потенциал spellcheckerа. Великолепно выявляет любые присутствующие в игре вещи, включая те, о которых игрок и не догадывался (и не должен был).
Неактивен
Ещё оптимизация.
//узнаем, английский ли это текст или нет for (i := 1; i <= length(word); i++) { for (j := 1; j <= length(englet); j++) { if (substr(word, i, 1) = substr(englet, j, 1)) { curlet := englet; goto next; } } } next: ;
легко заменяется на
//узнаем, английский ли это текст или нет if (reSearch('[a-zA-Z]',word)) curlet := englet;
Проверяются все буквы до первого вхождения.
Неактивен
Нужно сделать ограничение не на четыре, а три буквы. Три буквы заново набрать не проблема, и не будет путаницы с предлогами и сокращениями глаголов.
Неактивен
Это был дефект основной библиотеки, в новой версии исправлено.
Неактивен