Как я могу разобрать два предмета из строки? - PullRequest
0 голосов
/ 17 сентября 2010

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

Когда игрок вводит данные, могут быть два возможных субъекта (назовем их subject1 и subject2).Например, в следующем случае: «ударил по двери палкой», subject1 - это «дверь», а subject2 - «палка».

В этом случае и дверь, и палка относятся к типу «Предмет».Также могут быть предметы типа «Персонаж».

Проблема в том, что если я разбираю предметы, то символы, разбирающие предметы, будут находить предмет как subject1, даже если это фактически второй субъект.Код, который я использую, выглядит следующим образом:

public static void ParseForSubjects(string Input, Player CurrentPlayer, ref object Subject1, ref object Subject2)
{
    // This method doesn't really work properly, as it looks up Inventory items, Environment items and then Characters in order
    // when it may well be that a character is subject1 and an item is subject2, but they will be reversed because of the parsing order
    Input = Input.ToLower();

    // Parse items in Player inventory
    foreach (Item InventoryItem in CurrentPlayer.Inventory)
    {
        if (Input.Contains(InventoryItem.Name.ToLower()))
        {
            if (Subject1 == null)
            {
                Subject1 = InventoryItem;
            }
            else
            {
                Subject2 = InventoryItem;
            }
        }
    }

    // Parse items in environment
    foreach (Item EnvironmentalItem in CurrentPlayer.CurrentArea.Items)
    {
        if (Input.Contains(EnvironmentalItem.Name.ToLower()))
        {
            if (Subject1 == null)
            {
                Subject1 = EnvironmentalItem;
            }
            else
            {
                Subject2 = EnvironmentalItem;
            }
        }
    }

    // Parse present characters
    foreach (Character PresentCharacter in CurrentPlayer.CurrentArea.Characters)
    {
        if (Input.Contains(PresentCharacter.Name.ToLower()))
        {
            if (Subject1 == null)
            {
                Subject1 = PresentCharacter;
            }
            else
            {
                Subject2 = PresentCharacter;
            }
        }
    }
}

Я уверен, что это действительно достаточно ясно.В основном, независимо от типа, мне нужно, чтобы subject1 был первым субъектом в строке ввода, а subject2 - вторым субъектом в строке ввода.

Не стесняйтесь задавать вопросы, возможно, это не совсем ясно.

Ответы [ 4 ]

2 голосов
/ 17 сентября 2010

Просто отметьте Input.IndexOf(Subject1.Name.ToLower()) < Input.IndexOf(Subject2.Name.ToLower()) и, если false, переключите их.

1 голос
/ 17 сентября 2010

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

string[] parsedInput = Input.Split([' ']);

Теперь у вас есть массив, содержащий слово пользователя, слово за словом.Если вы всегда знаете, что subject1 - это второе слово, а subject2 - четвертое, то:

string subject1 = parsedInput[1];
// check to see if subject1 is in the Inventory or the Environment collections

Сделайте то же самое с subject2 (то есть parsedInput[3])

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

for each item in inventory/environment/characters
  did user's input mention this?

Вы говорите вместо этого:

for each item that the user mentioned
  is it in the inventory/environment/characters collections?
0 голосов
/ 17 сентября 2010

Если я правильно вас понимаю, то, что вы на самом деле говорите, так это то, что «флешка» становится «Субъектом 1», если она находится первой в коллекции инвентаризации, даже если на самом деле это «Субъект 2» в строке ввода.Если это так, то почему бы не преобразовать переменные Subject в массив, а затем заполнить этот массив в соответствии с положением существительного во входном файле?

Таким образом, Subject[] будет заполняться как: Subject[1]="door"и Subject[2]="stick".Затем вы выполняете итерацию по массиву, обрабатывая темы в порядке возрастания.

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

Эта статья также может помочь уточнить мыслительный процесс по этому вопросу: Обработка естественного языка

0 голосов
/ 17 сентября 2010

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

...