В настоящее время я пишу свой собственный текстовый движок приключений из-за того, что у Inform/Adrift/Quest есть фатальный недостаток, который меня раздражает — кошмарный, запутанный синтаксис Inform (и это исходит от UX-дизайнера, который любит, чтобы все было так же просто, как возможно для новичков), уродливый читатель Adrift, а в Adrift/Quests отсутствует поддержка реальных классов/объектов.
Возможно, это не лучший способ сделать это, но пока он работает нормально. Я изучил Regex, но вместо этого решил сделать это таким образом.
Первое, что нужно сделать, это разделить строку ввода/команды игрока на список. К счастью, в этих играх первым элементом этого списка почти всегда является глагол.
Вам понадобятся классы данных глагола/объекта/и т. д., к которым можно получить доступ по ключу, содержащему все значения, которые могут совпадать с ним, такие как «смотреть, исследовать, пример».
class Verb
{
string uniqueID;
List<string> values;
}
class Object
{
public uniqueID; // Because this is shared with Verbs, you could do a better unique ID system, but hey...
public List<string> articles;
public List<string> adjectives;
public List<string> noun;
}
Вам также понадобится куча подклассов «Действие», которые будут сопоставляться с вводом игрока. Здесь вы «строите» свою структуру предложения, которая должна соответствовать вводу игрока.
- Action (base class)
- look
- смотреть {на} [объект]
- смотреть {на} книгу
- Прыгать
- Перейти {на/на} [объект]
.
class Action
{
string uniqueID;
List<SentenceElement> sentence;
void Execute();
bool RestrictionsCheck();
}
class Look : Action
{
override void Execute();
override bool RestrictionsCheck();
}
class LookAtObject : Action
{
override void Execute();
override bool RestrictionsCheck();
}
class LookAtBook : Action
{
override void Execute();
override bool RestrictionsCheck();
}
В базовом классе Action есть построитель предложений, использующий SentenceElements. Это может быть список, описывающий предложение по частям.
class SentenceElement
{
List<string> values;
bool isOptional;
}
class VerbID : SentenceElement {}
class ObjectID : SentenceElement {}
class ObjectAny : SentenceElement {}
class CharacterID : SentenceElement {}
class CharacterAny : SentenceElement {}
class TextOptional : SentenceElement {}
class TextRequired : SentenceElement {}
class Parameter : SentenceElement {}
Теперь вы можете выполнять поиск по своим классам «Действие», сравнивать первый SentenceElement с первым введенным игроком глаголом и сохранять список тех, которые соответствуют «потенциальным действиям». "string.Contains" будет работать.
Теперь вам нужно найти наиболее подходящее действие, пройдя через команду ввода ваших игроков и пройдясь по каждому SentenceElement, сравнивая их. Сохраняйте индекс того, где вы находитесь в каждом из них (playerInputIndex, PotentialActionsIndex, OfferingElementIndex).
Если вы найдете совпадение, увеличивайте playerInputIndex до тех пор, пока он не будет соответствовать SentenceElement, проверьте свои настройки (isOptional и т. д.), затем перейдите к следующему предложениюElementIndex и снова запустите сравнение. В конце концов вы дойдете до конца либо ввода игрока, либо SentenceElements.
Сложность добавляется, когда у вас есть SentenceElements, которые являются «isOptional», поэтому их нужно будет проверять, или действия, которые имеют SentenceElements типа ObjectAny, которые не должны совпадать с существующим, но отображают «Какой объект вы хотите кушать?" сообщение. Кроме того, объекты имеют дополнительные параметры соответствия, такие как префиксы/прилагательные/существительные, которые необходимо учитывать, в отличие от глаголов.
Эта система также потребует новый класс для каждого действия, которое вы когда-либо захотите сделать. Каждое действие будет иметь настраиваемые «Ограничения», которые оно также должно пройти, прежде чем оно будет запущено, например «Жив ли упомянутый персонаж?» и т. Д.
person
st4rdog
schedule
02.09.2015