Forum.iFiction.Ru

iFiction.Ru · ifHub · FAQ · IFWiki · QSP · URQ · INSTEAD · AXMA

форум об interactive fiction, текстовых приключенческих играх и всём таком...

Вы не зашли.

0    0    #1
05.12.2007 12:55

Flint
Участник
Зарегистрирован: 06.09.2007
Сообщений: 148

---

Универсальный spellchecker для RTADS

Людям свойственно ошибаться. При наборе, к примеру, мы частенько делаем опечатки. В этом случае текстовые процессоры подчеркивают неизвестные слова, а поисковая система 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>&laquo;<<correct>>&raquo;</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 – лучшая платформа!

Неактивен

0    0    #2
06.12.2007 18:32

fireton
некто с бородой (+330, -92)
Откуда: Москва
Зарегистрирован: 22.08.2005
Сообщений: 1087
Вебсайт

Тон

Re: Универсальный spellchecker для RTADS

Боюсь, ошибка выдается не игровой программой, а самим проигрывателем...

Неактивен

0    0    #3
22.01.2008 02:14

fireton
некто с бородой (+330, -92)
Откуда: Москва
Зарегистрирован: 22.08.2005
Сообщений: 1087
Вебсайт

Тон

Re: Универсальный spellchecker для RTADS

2. В файле advr.t найдите функцию preparse и в самом конце, но перед return comStr; добавьте

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

Было б клево вот что. Написать статейку на этот счет в вики и приаттачить туда файлик для инклюда (опираясь на текущую 24 версию библиотек).

Неактивен

0    0    #4
23.01.2008 18:52

fireton
некто с бородой (+330, -92)
Откуда: Москва
Зарегистрирован: 22.08.2005
Сообщений: 1087
Вебсайт

Тон

Re: Универсальный spellchecker для RTADS

Flint, клево!

Неактивен

Powered by PunBB
© copyright 2001–2020 iFiction.Ru