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

Объявление

Платформа ТОМ предназначена для создания текстовых игр на русском языке и имеет развитый парсер, позволяющий взаимодействовать с играми с помощью команд на близком к естественному языке. В данный момент активно разрабатывается версия ТОМ 2.
Последнюю версию платформы можно скачать здесь.

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

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


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


Прототип

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

1

Выложил прототип интерпретатора. Пока крайне сырой, но работает.
Достижений не много, но поиграться можно.

В демо-примере работает только 2 глагола - "заложи" и "осмотри".
Порядок слов в команде произвольный, глагол может быть где угодно.

Пока нет словоизменения по ключам и контроля падежей - это прекрасно работало в 1м ТОМе, проблем с переносом быть не должно.
Вообще там почти ничего нет - минимальный функционал для проверки работоспособности парсера.

P.S. Код демо-примера несколько страшен, так как пришлось обходиться только теми средствами которые уже работают.

2

Дааа. В примере не нашёл ни одной знакомой строчки. ТОМ 2 будет реально другим языком. Насколько я понял, слова в начале будут содержаться в словаре?

Код:
// предикаты ==========================================
факт(объект заложен)
{
#check
  return объект.заложен = 1

#execute
  объект.заложен = 1
}

Напомнило пролог.

Код:
директива(заложить за объект)
{
#parsing
  //предлог "за" должен стоять перед объектом
  ошибка если за.pos+1 != объект.pos 
#execute
  %что заложить?
  return ""
}

Похоже гибкость парсера будет на высоте!

> за воротник рюмку заложи
  Рука неуверенно потянулась к рюмке и вернулась назад... Нет! воспитание не позволяет пить без салфетки...

:O сработало! :jumping:

Прекрасная работа! Жду с нетерпением.

3

Дам небольшие комментарии по основным отличиям нового тома от старого и по отличиям от классических языков программирования.
Описывать буду только то, что уже реализовано и можно посмотреть в прототипе.

1. Объекты объединены с переменными. Создаются как переменные и уничтожаются как переменные при выходе из контекста функции.
    Следовательно, глобальные объекты должны создаваться в глобальном контексте вне вызова какой либо функции.

2. Объекты не имеют методов, всё делается функциями. Т.е. говорить о классическом ООП тут нельзя и в дальнейшем я буду избегать применения этого термина.

3. Функции не имеют имён. Какая именно функция будет вызвана определяется исключительно набором переданных аргументов.

4. Расположение аргументов при вызове функции не имеет значения. Это соответствует правилам русского языка, в котором слова в предложении могут занимать произвольное* место в отличие от английского.

5. Функция не является инкапсуляцией. При исполнении функции доступен контекст всех не завершившихся функций вызванных перед ней.

Выше перечисленного достаточно, чтобы утверждать что ТОМ 2 не будет похож не только на предыдущий ТОМ но и ни на один из существующих языков программирования.

*почти произвольное

4

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

сработало!

мне больше нравится что сработают и команды:

>в ломбард заложите часы 

>заложи ногу за ногу

5

Всё больше читая код понимаю, на сколько всё продумано.

Код:
  если объект_2 != воротник{
    %__ты не хочешь засовывать {объект_1} за {объект_2}^^^ водочки бы
    return ""
  }

  если объект_1 это салфетка {
    если салфетка заложена {
      %__ты поправил уже заложенную за воротник салфетку и жадно сглотнул. 
      return ""
    }
    %__ты взял салфетку, неторопя`сь расправил ее и аккуратно заложил за воротник, провел по ней рукой, еще раз  убедившись, что она на месте.
    салфетка.заложена = 1   
    return ""
  }

Фраза "если салфетка заложена" убивает. Склонение по роду прямо в коде? Это так факт(объект заложен) срабатывает?
"если объект_2 != воротник". Надеюсь потом появится "если объект_2 это не воротник"?
"салфетка.заложена = 1". Разве факт(объект заложен) не должен позволять закладывать объекты на естественном языке? Или это ещё не доделано?

6

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

Насколько я понял, слова в начале будут содержаться в словаре?

Совершенно верно.

Склонение по роду прямо в коде? Это так факт(объект заложен) срабатывает?

Нет, это слово заложен так срабатывает. После того как переменная привязалась к слову для её обозначения в коде можно использовать любую из словоформ.

Надеюсь потом появится "если объект_2 это не воротник"?

Обязательно

"салфетка.заложена = 1". Разве факт(объект заложен) не должен позволять закладывать объекты на естественном языке? Или это ещё не доделано?

Это я в примере забыл исправить. "салфетка.заложена = 1" можно заменить на "салфетка заложена" - будет работать.

7

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

После того как переменная привязалась к слову для её обозначения в коде можно использовать любую из словоформ.

Это позволяет срабатывать даже таким кривым фразам:

> заложи рюмкой за салфетке
Ты не хочешь засовывать рюмка за салфетка... Водочки бы

Думаешь, это не приведёт к последствиям в будущем? Вдруг между двух похожих интерпретаций сработает именно не нужная? Хотя может я преувеличиваю...

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

Насколько я понял, слова в начале будут содержаться в словаре?

Совершенно верно.

Ох замучаешься ты с синонимами.

Слово "объект" и "строка" какие-то внутренние слова ТОМа?

Ну и добавлю в эту большую бочку мёда мааааленькую ложку дёгтя:
Ты каждый раз выкладываешь ТОМ с включенным плагином speech.plg.dll. Я каждый раз сразу-же переименовываю его, что-бы отключить. Ибо этот голос по умолчанию разрывает мозг. У меня есть другие хорошие голосовые движки и я бы послушал текст с их использованием, но тот, который выбирает плагин - просто кошмар. И пока нет настроек выбора движка, думаю этот плагин будет только пугать пользователей. Особенно включенный по умолчанию.

8

перенёс в отдельную тему

9

И раз уж почти весь код будет писаться на естественном русском языке, не слишком ли жестоко заставлять квестописателя писать программные скобки фигурными скобками {}? :hobo:

10

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

Это позволяет срабатывать даже таким кривым фразам:
> заложи рюмкой за салфетке
Ты не хочешь засовывать рюмка за салфетка... Водочки бы
Думаешь, это не приведёт к последствиям в будущем? Вдруг между двух похожих интерпретаций сработает именно не нужная? Хотя может я преувеличиваю...

Будет проверка по падежам, склонениям, лицам и т.д. Пока не сделана.

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

Ох замучаешься ты с синонимами.

Есть мысль как это реализовать.

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

Слово "объект" и "строка" какие-то внутренние слова ТОМа?

Это типы значений. Попробуй в командной строке набрать:
>5.тип
>var X.type
>"текст".тип

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

Ибо этот голос по умолчанию разрывает мозг.

:D ломать не строить :D
Голос по умолчанию настраивается в винде: Contron Panel -> Speech -> Voice selection
А если посоветуешь приличный голосовой движок - моя благодарность не будет иметь границ в пределах разумного  :flirt:

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

не слишком ли жестоко заставлять квестописателя писать программные скобки фигурными скобками {}?

Фигурные скобки - это наше фсё! Это святое! это единственное что осталось от СИ  :'(

11

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

Голос по умолчанию настраивается в винде: Contron Panel -> Speech -> Voice selection

Не знал, что в виндовс настраивается отдельно. Всегда настраивал непосредственно в говорилках.

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

А если посоветуешь приличный голосовой движок - моя благодарность не будет иметь границ в пределах разумного

Я использую Loquendo Olga, но он платный (в инете полно крякнутых версий). Довольно давно скачивал. Сейчас может уже есть что-то получше, но меня и этот устраивает. Кстати, вот здесь(здесь должна быть ссылка, но она пропала: http://mytts.mybb.ru/f10-forum) можно почитать про русские голосовые движки, а так-же скачать дополнительные словари для них и др.

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

Фигурные скобки - это наше фсё!

Ну тогда придётся настраивать горячие клавиши на эти символы, что-бы набирать в русской раскладке.

Отредактировано Alexandr (2011-05-22 11:11:19)

12

Обновил прототип интерпретатора.
Немного подчистил код демоигры и ошибки в интерпретаторе.

Наиболее заметное изменение - возможность задавать закрытые вопросы:
> салфетка заложена?
> рюмка заложена?

13

ТОМ 2 был полностью переписан с нуля или он использует какие-то модули от старого (исключая плагины)?
Сколько примерно тыщ строк уже занимает код?
Извиняюсь за необоснованное любопытство, просто интересно стало.
Движок ТОМа всё ближе приближается к моей мечте, которую я описывал в теме Командная строка на ЕЯ в неигровых приложениях.

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

> салфетка заложена?
> рюмка заложена?

Ну какой парсер ещё может вот-так вот сам отвечать на логические вопросы?
Вот только меня смущает то, что он без всякого зазрения совести принимает то, что ему говорят:

> рюмка заложена
Выполнено, факт принят
> рюмка заложена
Да, заложена за воротник
> воротник заложен?
Пусто, свойство отсутствует
> воротник заложен
Выполнено, факт принят
> воротник заложен?
Да, заложена за воротник

Ну хотя-бы то, что парсер начал воспринимать знаки препинания на конце, радует.

14

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

Вот только меня смущает то, что он без всякого зазрения совести принимает то, что ему говорят:

Сейчас еще нет игрового режима, парсер работает в режиме демиурга. А слово демиурга воплощается безоговорочно.

> воротник заложен?
Пусто, свойство отсутствует
> воротник заложен
Выполнено, факт принят
> воротник заложен?
Да, заложена за воротник

Можно немного усложнить код факта(объект заложен) чтобы воротник не закладывался сам за себя, но в такой короткой демо-игре это на мой взгляд излишне.

15

// предикаты ==========================================
факт(объект заложен)
{ #check
  объект.заложен
  #execute
  объект.заложен = да, "заложена за воротник."
}

В данный момент один факт обрабатывает все объекты. Но что сделать, что-бы разделить разные факты с одним названием (синонимичные факты)? Допустим мы хотим, что-бы рюмка закладывалась по своему, а салфетка по своему. Ведь "заложить рюмку" значит "выпить водку из рюмки". Можно ли разделить ёмкости в одну кучку а салфетки в другую? Что-бы фразу "заложи рюмку" обрабатывал один факт (означающий выпивание чего-то), а на фразу "заложи салфетку" парсер запускал другой факт? Это надо делать какую-то проверку в факте, что объект принадлежит классу салфеток или стаканов.

16

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

ТОМ 2 был полностью переписан с нуля или он использует какие-то модули от старого (исключая плагины)?
Сколько примерно тыщ строк уже занимает код?

На текущий момент общий вес всех исходников - 235kB.
Очень многое взято из тома v.0.9.4.x - интерфейсный модуль вообще не редактировался, низкоуровневые модули для контейнеров, строк и пр. взяты полностью, но эволюционировали в процессе работы.
С нуля написана только подсистема значений и объектов, а также сам парсер и интерпретатор. Но и тут я подсматривал в старые исходники одним глазом...

17

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

Это надо делать какую-то проверку в факте, что объект принадлежит классу салфеток или стаканов.

Сейчас всё еще нет классов и наследования.

А должно быть примерно так:

Код:
переменная рюмка.класс = ёмкость
переменная салфетка.класс = салфетка_столовая

факт(ёмкость заложен)
{
  //...
}

факт(салфетка_столовая заложен)
{
  //...
}

Т.е. для каждого класса можно будет назначить свою функцию, если это необходимо.

18

Обновил прототип интерпретатора.

Добавил прилагательные и проверку по роду/падежу.
Список прилагательных: пустая, полная, запотевшая, белая.

Теперь работают команды и вопросы примерно такого вида:
> рюмка водки пустая?
> воротник белый?
> заложи полную запотевшую рюмку водки за воротник

По непонятной мне пока причине не работают команды (а должны):
> заложи за воротник рюмку водки
> заложи за воротник белую салфетку

P.S. код примера подстроен под еще не исправленные баги. Не везле выглядит логично.

19

Щас потестим. :D
- Уходит в бесконечный цикл на вопрос "белая рюмка белая?".
- На вопросы типа "водка белая?" отвечает просто "Да". Хотя по логике должен отвечать "Да, беленькая"
- "Заложи за воротник белую водку" и правда не работает. Странно.

В целом не плохо. ТОМ 2 будет действительно уникальным среди парсерных платформ. В общем, ждём классов.
Кстати, на счёт словаря. Слова будут описываться в игре или ты хочешь сделать встроенный словарь, в котором будут описаны частые слова? Может прикрутить к ТОМу какой-нибудь специфический плагин, который будет заниматься словами? Может я смогу как-нибудь тот плагин, который генерировал лексемы, переделать под это дело?

20

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

Кстати, на счёт словаря. Слова будут описываться в игре или ты хочешь сделать встроенный словарь

Я хочу оба варианта :)

Описание слов в коде игры уже есть и так там и останется. При наличие словаря будет использоваться для редких или "авторских" слов.

Словарь в идеальном виде я вижу так:
Должна быть SQL база, в которой словарь подготавливается.
Должна быть утилита, формирующая из базы компактный файл, с которым работает платформа.
Это программа минимум.

Далее возможны различные инструменты для работы с базой: редактирование, экспорт/импорт, слияния словарей от разных игр/авторов и т.д.

Всё это должно быть гибко, максимально открыто и дружелюбно для сторонних разработчиков.

21

Обновил прототип интерпретатора.
Добавил пример словаря, реализованного как плагин.
В демо-словарь перенёс 4 слова из демо-игры.

22

Обновил прототип интерпретатора.

Исправил ошибки в парсере, теперь работают все команды, включая:
> заложи за воротник полную запотевшую рюмку белой водки

Как побочный продукт появился файл parsing.log, обновляющийся после каждой введенной команды.

23

Ваааау. Красота. Практически любое сочетание известных слов понимает правильно. :jumping:
Хорошо сделанная игра на ТОМ 2 должна сносить мозг неподготовленному игроку. Потому-что программа, которая понимает практически любую фразу (в пределах игрового мира) и адекватно реагирует на неё - это... мягко говоря очень необычно (не могу подобрать нужных слов). Помню, как я первый раз запустил парсерный квест (это был спелеологист 2 на ТОМе). Как долго я завязывал и развязывал лиану, верёвку и динамит в разных последовательностях и каждый раз восхищался, как игра "съедает" то что я говорю. :D Что же будет с появлением ТОМа 2?

24

Обновил прототип интерпретатора.

Исправил некоторые ошибки.

Из нового:
- обязательная точка в конце утверждения:
> салфетка заложена.
Без точки работает как вопрос.
Не уверен что так оставлю. Обязательная точка - потенциальный источник ошибок. Вероятно должно одинаково работать как с точкой так и без неё.

- расширенное отрицание
ЕЯ позволяет ставить НЕ не только в логических выражениях, но вообще перед любым значащим словом.
Попробуйте команды:
>рюмка не полная?
>салфетка не белая?
>заложить за воротник не рюмку водки.
>заложить за воротник рюмку не водки.
Как использовать эту возможность мне пока еще не до конца ясно... есть над чем подумать.

25

Обновил прототип интерпретатора.

- добавил полиморфический вызов функций - смотрите в коде примера.
- расширена и углублена обработка отрицания "не".

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

В данный момент один факт обрабатывает все объекты. Но что сделать, что-бы разделить разные факты с одним названием (синонимичные факты)? Допустим мы хотим, что-бы рюмка закладывалась по своему, а салфетка по своему.

Да, теперь уже так можно.

26

Обновил прототип интерпретатора.

Новые возможности:
1. составные слова
Рассмотрим пример Красная шапочка.
Это вовсе не объект класса "шапочка", имеющий свойство красный=да, а просто девочка, откликающаяся на эти 2 слова.
(в отличии от серого волка, который действительно является объектом класса "волк" и имеет свойство серый=да)
Такие объекты теперь можно создавать кодом вида:

Код:
переменная красная_шапочка

В примере см.объект "огненная_вода".

2. синонимы
Стали работать так как это изначально планировалось. Для задания синонима достаточно присвоить какой-либо переменной значение другой объектной переменной.
См. в примере синоним

Код:
огненная_вода = водка

3. многозначность слов
Имя переменной может состоять из 2х частей, разделенных знаком '@':

Код:
переменная замок@сооружение
переменная замок@механизм

1 часть имени связывает переменную с соответствующим словом, 2 часть обозначает смысловые различия переменных.
Для демонстрации добавил в пример вторую рюмку водки. Одной уже мало...

P.S. Уточняющие вопросы еще не делал, в случае возникновения неоднозначной команды выдаётся ошибка с минимальным (пока) описанием.

27

Немного поясню, что будет представлять из себя структура словаря игры (независимо от того, набивается он руками, или использует плагин).

Возможности, объявленные топиком выше, необходимы и достаточны для формирования такой структуры.
Значимым является и то, что наследование во 2м ТОМе буде множественным, а не линейным как в 1м ТОМе.

Итак, основу составляют объекты типа "слово", которые несут в основном морфологическую нагрузку.

К слову может быть привязан 1 или несколько классов, каждый из которых соответствует одному из значений этого слова.
На этом же уровне происходит привязка синонимов.
Насколько подробно нужно будет расписывать эти классы сейчас затрудняюсь сказать. В идеальном варианте они должны составить большую часть стандартной библиотеки.

Далее, каждому объекту игры, к которому можно обратиться словом, назначаются один или несколько классов тех слов, которыми он может быть назван.
Таким образом объект получит не только название, но и часть свойств, характерных для объектов с таким названием.

Примерно так...

28

Обновил прототип интерпретатора.

Добавлены классы.
Реализация классов пока довольно куцая. Эта тема обширна и будет развиваться далее.
Реализовано:
- подбор парсером объектов по имени класса;
- использование классов в качестве аргументов функций;
- добавлено ключевое слово "любой": >заложи за воротник любую рюмку.
Не реализовано:
- наследование объектами свойств класса;
- разруливание коллизий множественного наследования (кросс-классы);
- много еще чего...

Код демоигры переписан с использованием классов.

29

Обновил прототип интерпретатора.

Добавлены локации и команда goto для перемещения между ними.

В примере специальных функций для перемещений не делал.
Для тестирования добавил еще одну микро-локацию - улица.
Можно потестить команды:
>goto улица
>goto рюмочная

30

С удивлением для себя обнаружил что парсер свободно принимает команды вида:
> если салфетка не заложена, заложи салфетку за воротник, иначе заложи за воротник любую рюмку.


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