ТОМ2 - платформа для парсерных игр

Объявление

Открыт сайт tom2-game.ru.


Последнюю версию платформы можно скачать здесь.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » ТОМ2 - платформа для парсерных игр » Документация » Разбираем мышей. Часть 2


Разбираем мышей. Часть 2

Сообщений 1 страница 2 из 2

1

Что-ж, раз люди говорят, что мои уроки можно читать, значит буду писать дальше. Тем более документации для ТОМа очень мало.

Продолжаем разбирать модуль Main.tml

Код:
class декорация
{ cls = предмет
  описание = "{this} - это просто декорация. {this:лич_мест*this} здесь {находится*this} лишь для красоты."
  предмет_по_месту = "" //упоминается в описании локации
}

Я думаю не стоит объяснять, для чего служит декорация.
лич_мест - свойство типа lexeme, описывающее формы личного местоимения (он, она, оно, его ...). Объявлено в классе предмет.
находится - объект типа mental, содержащий словоизменение глагола "находиться". Его мы рассмотрим позже.

Код:
class персонаж
{ cls = нечто_видимое
  //описание переопределяется автором
  this.описание = "{this} {выглядит*this} как обычно"
  //st_описание обычно не переопределяется автором
  this.st_описание = "{описание}, {item:снаружи_персонажа}."
  this.персонаж_по_месту = "{this} {находится*this} тут"
  this.по_имени = "<font color=red>{name}</font>" //программное имя выводится если "по_имени" не переопределено
  this.Род="Мр" //мужской род по умолчанию
  //предлоги
  this.предлог= "у" //находится у персонажа
  this.пред_в  = ""  //дал персонажу
  this.пред_из = "у" //взял у персонажа

  // Лм - Личные местоимение
  // Нм - это не личное местоимение
  // Ве - Возвратное местоимение
  // Не - это не возвратное местоимение
  // Вы - обращение на "Вы"
  // Ты - обращение на "Ты"
  // Мы - обращение на "Мы" - Мы, Николай II
  this.обращение_к = "Ты" //по умолчанию предполагается обращение на "ты"
  title="{this:%*$$};; НеНм; Зп=по_имени; НеНм=по_имени; НеЛм=лич_мест; Ве=возвр_мест;"
  this.лич_мест="%; НеЛмЕчОдСи; Ты2лИпМр; //личные местоимения
      1лИп=я;     1лРп=меня;   1лДп=мне;    1лВп=меня;   1лТп=мной;    1лТп=мною;    1лПп=мне;
    Мы1лИп=Мы;  Мы1лРп=Нас;  Мы1лДп=Нам;  Мы1лВп=Нас;  Мы1лТп=Нами;                Мы1лПп=Нас;
    Ты2лИп=ты;  Ты2лРп=тебя; Ты2лДп=тебе; Ты2лВп=тебя; Ты2лТп=тобой; Ты2лТп=тобою; Ты2лПп=тебе;
    Вы2лИп=вы;  Вы2лРп=вас;  Вы2лДп=вам;  Вы2лВп=вас;  Вы2лТп=вами;                Вы2лПп=вас;
    Мы2лИп=Вы;  Мы2лРп=Вас;  Мы2лДп=Вам;  Мы2лВп=Вас;  Мы2лТп=Вами;                Мы2лПп=Вас;
    3лМрИп=он;  3лМрРп=его;  3лМрДп=ему;  3лМрВп=его;  3лМрТп=им;                  3лМрПп=нём;
    3лСрИп=оно; 3лСрРп=его;  3лСрДп=ему;  3лСрВп=его;  3лСрТп=им;                  3лСрПп=нём;
    3лЖрИп=она; 3лЖрРп=её;   3лЖрДп=ей;   3лЖрВп=её;   3лЖрТп=ей;    3лЖрТп=ею;    3лЖрПп=ней;
                3лМрРп=него; 3лМрДп=нему; 3лМрВп=него; 3лМрТп=ним;
                3лСрРп=него; 3лСрДп=нему; 3лСрВп=него; 3лСрТп=ним;
                3лЖрРп=неё;  3лЖрДп=ней;  3лЖрВп=неё;  3лЖрТп=ней;   3лЖрТп=нею;
    Мы3лИп=Они; Мы3лРп=Их;   Мы3лДп=Им;   Мы3лВп=Их;   Мы3лТп=Ими;                 3лЖрПп=Них;
                Мы3лРп=Них;  Мы3лДп=Ним;  Мы3лВп=Них;  Мы3лТп=Ними;"

  this.возвр_мест = "%; ВеОдСи; Ип; //возвратные местоимения
    Рп=себя; Дп=себе; Вп=себя; Тп=собой; Пп=себе;"
  //притяжательные прилагательные
  this.притяжательное = "{this:%*$$};; НеНм; Зп=прит_прил; НеНм=прит_прил; НеЛм=прит_мест; Ве=прит_возвр_мест;"
  this.прит_мест = "%; НеЛмЕчПи; 2лИп; //притяжательное местоимение
    1лИпЖр=моя;  1лРпЖр=моей;   1лДпЖр=моей;          1лВпЖр=мою;              1лТпЖр=моей;  1лПпЖр=моей;
    1лИпМр=мой;  1лРпМр=моего;  1лДпМр=моему;  1лВпМрОд=моего; 1лВпМрНд=мой;   1лТпМр=моим;  1лПпМр=моём;
    1лИпСр=моё;  1лРпСр=моего;  1лДпСр=моему;         1лВпСр=моё;              1лТпСр=моим;  1лПпСр=моём;
    2лИпЖр=твоя; 2лРпЖр=твоей;  2лДпЖр=твоей;         2лВпЖр=твою;             2лТпЖр=твоей; 2лПпЖр=твоей;
    2лИпМр=твой; 2лРпМр=твоего; 2лДпМр=твоему; 2лВпМрОд=твоего; 2лВпМрНд=твой; 2лТпМр=твоим; 2лПпМр=твоём;
    2лИпСр=твоё; 2лРпСр=твоего; 2лДпСр=твоему;        2лВпСр=твоё;             2лТпСр=твоим; 2лПпСр=твоём;
    3лЖр=её; 3лМр=его; 3лСр=его;"
  this.прит_возвр_мест = "сво%; ВеПи; МрЕчИп; //притяжательное возвратное местоимение
    ИпЖрЕч=я; РпЖрЕч=ей;  ДпЖрЕч=ей;         ВпЖрЕч=ю;          ТпЖрЕч=ей; ПпЖрЕч=ей;
    ИпМрЕч=й; РпМрЕч=его; ДпМрЕч=ему; ВпМрНдЕч=й; ВпМрОдЕч=его; ТпМрЕч=им; ПпМрЕч=ём;
    ИпСрЕч=ё; РпСрЕч=его; ДпСрЕч=ему;        ВпСрЕч=ё;          ТпСрЕч=им; ПпСрЕч=ём;
    ИпМч=и;   РпМч=их;    ДпМч=им;    ВпМчНд=и;   ВпМчОд=их;    ТпМч=ими;  ПпМч=их;"
  this.прит_прил = ""//притяжательное прилагательное (лексема должна определяться в наследниках)

Здесь нет ничего сверхъестественного, кроме "{this:%*$$};; НеНм; Зп=по_имени; НеНм=по_имени; НеЛм=лич_мест; Ве=возвр_мест;". Я только с третьего захода понял, что означает сея незамысловатая конструкция. И то не до конца. Этот изворот отдалённо напоминает попытку вытащить самого себя из болота за волосы. С другой стороны, этот пример даже как-то элегантно смотрится и заставляет задуматься: когда же автор перестанет нас удивлять? Объяснить лучше на примере:
Допустим, нам надо из этой лексемы извлеч форму "Зп".
Берём модификатор "Зп=по_имени;" и подставляем его значение в основу вместо "%": {this:по_имени*$$}
Оператор аспекта ":", применённый к объекту, возвращает словоформу из лексемы. В данном случае возвращает значение лексемы по_имени объекта this, согласованное по ключу $$ (что значит этот странный ключ, остаётся лишь гадать). Получается: "<font color=red>{name}</font>".
Т.е. лексема "{this:%*$$};; НеНм; Зп=по_имени; НеНм=по_имени; НеЛм=лич_мест; Ве=возвр_мест;" возвращает разные свойства объекта при согласовании её с различными ключами. Вот такие пироги :)

Новые ключи:
е - м[е]стоимение: [В]озвратное, [Н]е возвратное
м - признак употребления в качестве [м]естоимения: [Л]ичное, [Н]е местоимение
л - [л]ицо: [1]-ое, [2]-ое, [3]-е
п - [п]адеж: [З]вательный (Кать, Вань, Петь)

Код:
  //
  // предопределенный метод для вычисления изменчивой части ключа
  //
  CalcKey(Key)
  { //разберемся с лицом
    if(Key~п=="Зп") //звательный падеж
      Key="2лНмНе"+Key //всегда подразумеваем 2е лицо и не может быть местоимением
    if(!Key~л) //нет указания лица
    { if(this==talker) Key=Key+"1лЛм" //первое лицо (тот кто говорит)
      else if(this==addressee) Key=Key+"2лЛм" //второе лицо (тот кому говорят)
      else Key=Key+"3л" //третье лицо (тот о ком говорят)
    }
    //разберемся с местоимениями
    if(this==actor) //объект и актер одно лицо
    { switch(Key~п)
      //для этих падежей указываем возвратное местоимение
      case("Рп") Key=Key+"Ве"
      case("Дп") Key=Key+"Ве"
      case("Вп") Key=Key+"Ве"
      case("Тп") Key=Key+"Ве"
      case("Пп") Key=Key+"Ве"
      //иначе это не возвратное местоимение
      case() Key=Key+"Не"
    }
    else Key=Key+"Не" //это не возвратное местоимение
    //разберемся с родом
    if(str=="прит_мест") //это форма притяжательного местоимения
    { if(Key~л=="3л")
        Key=Род+Key; //в 3м лице пр_мест согласование всегда по собственному роду!
    }
    else if(str!="прит_") Key=Key+Род;
    //добавим ключ обращения
    Key = Key + talker.обращение_к[this]
    //возвратим вычисленный ключ
    return Key
  }

Существует 7 специальных контекстных значений: this, act, actor, talker, addressee, told и addressed.
Здесь мы видим:
this - уже знакомый нам объект, код которого в данный момент выполняется.
actor - персонаж, в данный момент активно выполняющий действие
talker - персонаж, от которого в данный момент исходит речь.
addressee - персонаж, которому адресована речь.

CalcKey(Key) - специальный метод для расчета контекстно-зависимых морфологических ключей. Рассмотрим смысл тела метода:
Первая часть метода "разберемся с лицом" служит для замены имён персонажей на местоимения. Например, если ТОМ сгенерировал фразу "Мышонок дал кроту очки", и указано, что говорящий - мышонок, а тот к кому обращена речь - крот, то платформа изменит имена и выведет на экран фразу "Я дал тебе очки".
Вторая часть "разберемся с местоимениями" заменяет "мышонок стукнул мышонка по лбу" на "мышонок стукнул себя по лбу".
Часть "разберемся с родом" подставляет род, в зависимости от употребляемого местоимения. Например "моя тарелка"/"мой нож" - род зависит от существительного, а в "его тарелка"/"его нож" - род зависит от самого местоимения.
Затем метод добавляет ключ обращения (Ты/Вы) и возвращает получившийся ключ.
Таким образом, CalcKey помогает обрабатывать генерируемые фразы и приводить их в более естественный вид.

Код:
  //
  // метод ChkClsName() вызывается парсером при решении неоднозначности 
  // по классовым именам объектов
  //
  ChkClsName(Round,iRound,iForm,oRound,oForm)
  { // Round - номер текущего хода 
    // iRound - ход, в котором объект упоминался игроком (input)
    // iForm - форма, в которой объект упоминался игроком (input)
    // oRound - ход, в котором объект упоминался игрой (output)
    // oForm - форма, в которой объект упоминался игрой (output)
    //
    // проверим личные местоимения
    //
    if(str=="лич_мест")
      if(this==pers)
      { //проверим соответствие рода
        if(key~"р" and key~"р"!=Род)
          return "местоимение не подходит к ранее упомянутым персонажам."
      }
      else
      { //личные местоимения
        var chk_key = "ч" //проверка по числу
        switch(key~л)
        case("1л") //1 лицо относится к говорящему
          if(this!=told)
            return "1 лицо местоимения не подходит персонажу {name}."
        case("2л") //2 лицо относится к адресату
          if(this!=addressed)
            return "2 лицо местоимения не подходит персонажу {name}."
        case("3л") //3 лицо
        { if(this==told||this==addressed)
            return "1 лицо местоимения не подходит персонажу {name}."
          chk_key = "рч" //проверка по роду и числу
        }
        var род_число = key~chk_key
        iForm = iForm~chk_key
        oForm = oForm~chk_key
        var Ok = false
        //персонаж обязательно должен быть упомянут ранее
        switch(iRound!=0, oRound!=0)
        case(false,false)//не упоминался 
          return "местоимение не подходит к ранее упомянутым персонажам."
        case(true,false) //упоминался игроком   
          Ok = род_число==iForm
        case(false,true) //упоминался игрой   
          Ok = род_число==oForm
        case(true,true) //упоминался игрой и игроком   
          Ok = род_число==iForm or род_число==oForm
        //должны совпадать по роду и числу с последним упоминанием предмета
        if(!Ok)
          return "местоимение не совпадает с ранее упомянутыми персонажами."
      }
    //
    // проверим возвратные местоимения
    //
    if(str=="возвр_мест" and this!=actor)
      return "местоимение не подходит к персонажу."
    //
    // оставшиеся классовые имена подходят с различной степенью вероятности
    //
    if(iRound+10>oRound) //упоминание игроком +10 ходов к приоритету
      return iRound+12;
    else // +1 ход к приоритету над предметами
      return oRound+2;
  }

Аналогично одноимённому методу из класса предмет с дополнительной проверкой лица.
Потом допишу здесь описание возможности задавать в switch(iRound!=0, oRound!=0) по несколько аргументов. Сразу не доглядел.

Код:
  //телепортируем персонажей
  ChkMoveObj(From,To)
  { if(!act) return //произвольное перемещение
    var L = To.ведёт_в()
    if(L)
    { if(L.typ=="string") %{L}
      else L + this //отправим по назначению
      return нет //отменяем первоначальное перемещение
    }
  }

Предопределённый метод ChkMoveObj(From,To) вызывается при проверке перемещения персонажа.
From - от куда перемещаем
To - куда перемещаем
if(!act) return - если персонаж переместился не по нашей команде, то не обрабатываем.
ведёт_в() - пользовательский метод, возвращающий место, куда ведёт объект.
Например, если To - это дверь, то метод To.ведёт_в() возвратит локацию, куда ведёт эта дверь или строку с описанием ошибки, если дверь никуда не ведёт или закрыта.
if(L.typ=="string") %{L} - если тип - строка, то выводим эту строку на экран (например, "дверь закрыта")
else L + this - если не строка, а объект, то перемещаем персонажа в этот объект.

Код:
  //отображаем перемещения персонажей 
  BefMoveObj(From,To)
  { if(!act) return //произвольное перемещение
    if(тут_темно(To) && !this.светит())
      %<i><font color=aqua>{this} {act*this} в темноту.</font></i>
    else
    { if(To.пред_в=="к")
        var ПадежМеста = "Дп"
      else
        var ПадежМеста = "Вп"
      %<i><font color=aqua>{this} {act*this} {To.пред_в} {To*ПадежМеста}.</font></i>
    }
  }

Аналогично предыдущему, только вызывается перед перемещением персонажа.
Методы работы со светом описаны в модуле Light.tml, который мы не рассматриваем, т.к. он не используется в игре "Мышки".
Метод BefMoveObj в данном случае выводит на экран строку, описывающую перемещение персонажа.

Код:
  AftMoveObj(From,To)
  { if(!act||this==pers) return //произвольное перемещение или протагонист
    %<i><font color=aqua>{this} {act*this} {To.предлог} {To*Вп}.</font></i>
  }

Вызывается после удачного перемещения персонажа.
<i>...</i> - отображает текст курсивом.

Код:
  //
  // далее методы настройки поведения персонажей
  //
  свобода_воли(Объект,Место,Прочее)
  { //влияет на все действия
    if(this!=pers) return да //по умолчанию NPC всегда на все согласен
    %_
    %послушаться {told*ВпНеНм} и {act.инфинитив}?
    if(input("да/нет >")=="да")
      return да //выполняем действие
    else
    { this > "не {act*this*Бв}."
      return нет //ГГ не согласен
    }
  }

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

Код:
  //ответные реакции на действие "взял"
  может_не_дать(Объект)
  { //если метод вернёт строку, ГГ не будет пытаться брать Объект у this
  }
  не_дал(Объект)
  { //если метод вернёт да, ГГ не сможет взять Объект у this 
  }
  //ответные реакции на действие "дал"
  может_не_взять(Объект)
  { //если метод вернёт строку, ГГ не будет пытаться давать Объект this
  }
  не_взял(Объект)
  { //если метод вернёт да, ГГ не сможет дать Объект this 
  }
}

4 пользовательских метода для проверки ответных реакциях на действие "взял". Переопределяются в унаследованных объектах автором игры. Рассмотрим позже.

На этом и заканчиваются классы, описанные в модуле Main. А мы продолжаем разбор дальше...

Код:
unique ГГ //стандартный главный герой
{ cls = персонаж
  //специального рассказчика нет - его роль выполняет global
  global.narrator = global 
  //рассказ от 2 лица. Narrator обращается непосредственно к ГГ
  narrator.addressee = this 
  //текущий персонаж - это ГГ
  pers = this
}

В модуле Main описан единственный объект категории уникальное: ГГ. Он задаёт главного героя по умолчанию. Обычно в играх главный герой переопределяется.
Категория unique (уникальное) описывает единственный объект. Для элементов (item) уникального объекта подразумевается, что они или находятся внутри этого объекта, или являются его частью или собственностью.
narrator - специальная переменная "рассказчик". Олицетворяет того, от кого идёт повествование.
narrator.addressee - ссылка на того, к кому обращается рассказчик при повествовании.
pers - персонаж, которым управляет игрок. Можно менять во время игры.

Задавать действующее лицо (pers) нужно после всех расстановок narrator и addressee, т.к. операция смены главного героя автоматически вызывает описание локации и находящихся в ней объектов, что может привести к выводу начального описания локации в неправильной форме.

Код:
//текущий рассказчик - это narrator
talker = narrator
//текущий адресат - это ГГ
addressee = ГГ

Задание начальных рассказчика и адресата.
Приведу несколько наиболее употребляемых комбинаций задания narrator и addresse, приводящих к различным формам повествования:

narrator = ГГ
pers = ГГ

> возьми малину
я взял малину
> осмотри себя
я выгляжу как обычно

narrator = global
narrator.addressee = ГГ
pers = ГГ

> возьми малину
ты взял малину
> осмотри себя
ты выглядишь как обычно

global.narrator=global
ГГ.title = "крот"
pers = ГГ

> возьми малину
крот взял малину
> осмотри себя
крот выглядит как обычно

Код:
// ====================================================================
// синонимы 
// ====================================================================
"."="и"="а"="затем"="потом" //разделители команд

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

Код:
// ====================================================================
// глаголы и прилагательные используемые в модуле 
// ====================================================================

mental выглядит
{ this.инфинитив = "выглядеть" 
  title = "выгля%;; МрЕч3лНв;
    МрЕчПв=дел;   ЖрЕчПв=дела;   СрЕчПв=дело; МчПв=дели; //прошедшее время
    ТыЕч1лНв=жу;  ТыЕч2лНв=дишь; ТыЕч3лНв=дит; //настоящее время на ты
    ВыЕч1лНв=жу;  ВыЕч2лНв=дите; ВыЕч3лНв=дит; //настоящее время на вы
    МыЕч1лНв=дим; МыЕч2лНв=дите; МыЕч3лНв=дят; //настоящее время на мы
    Мч1лНв=дим;   Мч2лНв=дите;   Мч3лНв=дят;"
}
mental видит
{ this.инфинитив = "видеть" 
  title = "ви%;; МрЕч3лНв;
    МрЕчПв=дел;   ЖрЕчПв=дела;   СрЕчПв=дело; МчПв=дели; //прошедшее время
    ТыЕч1лНв=жу;  ТыЕч2лНв=дишь; ТыЕч3лНв=дит; //настоящее время на ты
    ВыЕч1лНв=жу;  ВыЕч2лНв=дите; ВыЕч3лНв=дит; //настоящее время на вы
    МыЕч1лНв=дим; МыЕч2лНв=дите; МыЕч3лНв=дят; //настоящее время на мы
    Мч1лНв=дим;   Мч2лНв=дите;   Мч3лНв=дят;"
}
mental держит
{ this.инфинитив = "держать"
  title = "держ%;;Ты3л; Ты1л=у; Ты2л=ишь; Ты3л=ит; Вы1л=у; Вы2л=ите; Вы3л=ит;" 

}
mental находится
{ this.инфинитив = "находиться" 
  title = "нахо%;; МрЕчТы3лНв;
    ТыМрЕчПв=дился; ТыЖрЕчПв=дилась; ТыСрЕчПв=дилось; ВыЕчПв=дились; МыЕчПв=дились; МчПв=дились; //прошедшее время
    ТыЕч1лНв=жусь;  ТыЕч2лНв=дишься; ТыЕч3лНв=дится; //настоящее время на ты
    ВыЕч1лНв=жусь;  ВыЕч2лНв=дитесь; ВыЕч3лНв=дится; //настоящее время на вы
    МыЕч1лНв=димся; МыЕч2лНв=дитесь; МыЕч3лНв=дятся; //настоящее время на мы
    Мч1лНв=димся;   Мч2лНв=дитесь;   Мч3лНв=дятся;"
}
mental обычный
{ title = "обычн%; Пи; МрЕчИп;
    МрЕчИп=ый; МрЕчРп=ого; МрЕчДп=ому; МрЕчВпОд=ого; МрЕчВпНд=ый; МрЕчТп=ым; МрЕчПп=ом;
    ЖрЕчИп=ая; ЖрЕчРп=ой;  ЖрЕчДп=ой;         ЖрЕчВп=ую;          ЖрЕчТп=ой; ЖрЕчПп=ой;
    СрЕчИп=ое; СрЕчРп=ого; СрЕчДп=ому;        СрЕчВп=ое;          СрЕчТп=ым; СрЕчПп=ом;
    МчИп=ые;   МчРп=ых;    МчДп=ым;    МчВпОд=ых;    МчВпНд=ые;   МчТп=ыми;  МчПп=ых;"
}

Категория мыслимое (mental) имитирует поведение нематериальных сущностей - мыслей, символов, объединений, концепций и т.п.
Более подробно с назначением этой категории мы познакомимся при непосредственном изучении игры "Мышки". В стандартной библиотеке же она используется только для хранения словоизменения некоторых часто употребляемых глаголов и прилагательных, чтобы не описывать их каждый раз в объектах.
this.инфинитив - свойство, заданное автором библиотеки для удобства. Используется, например, так: "ты не можешь {видит.инфинитив} эту кошку"
в - [в]ремя: [П]рошедшее, [Н]астоящее
ы - форма обращения: [Т]ы, [В]ы, [М]ы

Код:
// ====================================================================
// предлоги используемые в модуле 
// ====================================================================
preposition в
{ во что
  во мне
  во льду
  во льдах
  во рту
  во ртах
  во времени
  во временах
}
preposition из
{ изо льда
  изо льдов
  изо рта
  изо ртов
  изо всех
  изо всей
}
preposition к
{ ко мне
  ко дню
  ко дням
  ко двору
  ко дворам
  ко времени
  ко рву
  ко рвам
  ко сну
  ко снам
  ко второму
  ко второй
  ко вторым
  ко рту
  ко ртам
  ко вс*
}
preposition о
{ обо мне
  об а*
  об и*
  об е*
  об у*
}
preposition под
{ подо мной
  подо льдом
  подо льдами
  подо ртом
  подо ртами
}
preposition с
{ со мной
  со льдом
  со льдами
  со ртом
  со ртами
  со временем
  со вс*
  со сб*
  со св*
  со сг*
  со сд*
  со ск*
  со сл*
  со см*
  со сн*
  со сп*
  со ср*
  со ст*
}

preposition (предлог) - это некая сущность, описывающая употребление различных форм предлогов. Не обладает свойствами и методами. Содержит лишь список шаблонов изменения предлога, записанных в столбик. Используется платформой только для замены предлогов в некоторых случаях, например:
"думаю о огне" -> "думаю об огне"
"из льда" -> "изо льда"

Остальное в следующем уроке.

2

Alexandr написал(а):

согласованное по ключу $$ (что значит этот странный ключ, остаётся лишь гадать)

На самом деле вместо знаков $ и $$ подставляются различные ключи.
Вместо знака $ подставляется "внешний" ключ. Т.е. тот ключ Key_B, который был указан в выражении согласования Object_A*Key_B
Вместо знака $$ подставляется "внутренний" ключ. Т.е. результирующий ключ, который получился из ключа Key_B после обработки в методе Object_A.CalcKey()


Вы здесь » ТОМ2 - платформа для парсерных игр » Документация » Разбираем мышей. Часть 2