Консоль Visual Basic — глобальная команда и строка ответа

Я создаю текстовую приключенческую игру и хотел бы создать несколько «глобальных» команд и ответов, которые будут работать где угодно, где бы вы ни находились. Для глобальных ответов, если мы посмотрим на этот код:

Module Module1
Private Property answer1 As String
Private Property answer2 As String
Sub Main()
    Console.WriteLine("Welocome to the training grounds!")
    Console.WriteLine("What would you like to do? 1. I would like to train on dummies")
    answer1 = Console.ReadLine()
    Console.WriteLine()
    If answer1 = "1" Then
        Console.WriteLine("Okay what now?")
        answer2 = Console.ReadLine
        If anwser2 = "1" Then Console.WriteLine("New option")
    End If
End Sub

Теперь, как вы видите, мне нужно создать строку для каждого нового пользовательского ввода. Я пытался сделать Public answer As String = Console.ReadLine, а затем заставить вещи реагировать на «ответ», но если бы я повторно использовал ключевое слово, такое как номер 1, в коде вверху, программа не ждала бы ввода пользователя и просто пошла бы по пути номер 1. Первый вариант похоже на кучу спагеттического кода, а второй вариант, похоже, не работает, или я сам не заставляю его работать, поэтому любые советы здесь были бы хороши.

Я также хочу знать, возможно ли создать глобальную строку или что-то в этом роде. Скажите, что независимо от того, был ли я в точке, где я должен был ввести данные для ответа 1 или 2, если бы я набрал «инвентарь», это открыло бы другую подпрограмму под названием «инвентарь». Теперь, если возможно, я хочу сделать это без необходимости иметь if answer = inventory then Inventory().

Заранее спасибо всем ^^

Следуя совету, данному моему b.pell, я смог создать подпрограмму «GameCommand», но я не столкнулся с проблемой, как внедрить ее в саму игру/сделать ее доступной, не нарушая игровой процесс. Я также не совсем уверен, как написать команду, которая изменит что-то в GameCommand.vb (скажем, если игрок получит предмет, как мне добавить его в список инвентаря?)

Module Module1

 Sub Main()
    Dim gc As New GameCommand

     If Console.ReadLine = "Go to dummy" Then Dummy() Else
     CallByName(gc, Console.ReadLine, CallType.Method, "")
 End Sub
 Sub Dummy()
     Console.WriteLine("I am dummy hear me roar")
     Return
 End Sub
End Module

Файл GameCommand.vb такой же, как и в комментарии p.bells.


person Brin Žvan    schedule 07.10.2015    source источник


Ответы (2)


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

interpreter("inventory")

Внутри вы можете разбить эту команду (если у нее есть аргументы). Вы можете сделать базовый оператор if и выполнить свои подпроцедуры на его основе.

Вы можете сделать все возможное (это ответ на ваш вопрос о том, что вам не нужно писать «если») и создать класс команд, в котором есть все ваши методы команд (Inventory, North, South, East, West, Look), а затем, когда пользователь вводит команду, которую вы можете использовать для проверки этого класса, чтобы увидеть, существует ли эта подпрограмма/функция (и затем вызвать ее). Преимущество этого заключается в том, что при добавлении методов в класс команд вам больше никогда не придется обновлять логику if в вашем интерпретаторе.

Например. Вы должны добавить «Public Sub Look ()» или «Public Sub Look (args as String) в класс команды. Затем ваш интерпретатор попытается вызвать команду look (и, возможно, передать ей остальные аргументы). Если он не был найден, вы сообщаете пользователю, что это не команда, если это так, она выполняется (поиск в Google для вызова) Это означает, что когда вы добавляете Sub, интерпретатор просто подбирает их.

Вот статья MSDN, которая должна вам помочь, вы можете использовать функцию VB CallByName, вы передаете ей свой класс, а затем имя процедуры, которую хотите выполнить, с аргументами:

https://msdn.microsoft.com/en-us/library/chsc1tx6(v=vs.80).aspx

Вот простой пример (консольное приложение):

Модуль 1:

Module Module1

    Sub Main()

        Dim gc As New GameCommand
        CallByName(gc, "Inventory", CallType.Method, "")

        ' Will look south
        CallByName(gc, "Look", CallType.Method, "south")

        ' Will try to look southeast, but we don't accept that as a valid direction
        CallByName(gc, "Look", CallType.Method, "southeast")

        Console.ReadKey()
    End Sub

End Module

GameCommand.vb:

Public Class GameCommand

    Sub New()

    End Sub

    Public Shared Sub Inventory(arg As String)
        Console.WriteLine("Execute code to show inventory")
    End Sub

    Public Shared Sub Look(direction As String)
        If direction <> "north" And _
            direction <> "south" And _
            direction <> "east" And _
            direction <> "west" Then
            Console.WriteLine("Invalid direction")
            Exit Sub
        End If

        Console.WriteLine("You look " & direction)
    End Sub

End Class
person b.pell    schedule 07.10.2015
comment
Обновлено командой VB для динамического вызова метода в классе. Это делает всю тяжелую работу. - person b.pell; 07.10.2015
comment
Эй, не могли бы вы предоставить мне пример кода, пожалуйста? Я не уверен, что полностью все понял. РЕДАКТИРОВАТЬ: Вау, пропустил это редактирование, дай мне секунду! - person Brin Žvan; 07.10.2015
comment
Спасибо за пример. Я совсем новичок, когда дело доходит до программирования, поэтому примеры действительно очень помогают :) - person Brin Žvan; 07.10.2015
comment
Обновлено с примером. Есть две команды: Inventory (для которой не нужен аргумент, и look, для которой требуется направление). Вы можете видеть, что я вызываю их с помощью CallByName (и вы передаете все, что читаете из Console.ReadLine). Я бы хотел, чтобы каждая команда принимала строковый аргумент.. это облегчило бы задачу. - person b.pell; 07.10.2015
comment
Вам тоже пожалуйста, рад помочь. :) У меня есть текстовая игра, над которой я работаю на C (это MUD, пользователи могут входить в систему через Интернет), поэтому я раньше работал с такими вещами на других языках. :) - person b.pell; 07.10.2015
comment
Я надеюсь, что у вас есть еще немного силы воли/энергии, чтобы ответить на другой мой вопрос, который может быть здесь немного не по теме. Во всяком случае. Как мне сделать так, чтобы они всегда были доступны пользователю вместе с дополнительными командами? Или я должен полностью избегать подспецифических команд? Я отредактирую свой текущий код в сообщении. Мне жаль, если некоторые из этих вопросов кажутся полными базовыми вещами, если вы не хотите или не хотите объяснять мне эти базовые вещи, это будет совершенно понятно. - person Brin Žvan; 08.10.2015
comment
Все хорошо. Вы имеете в виду, как вы можете иметь команды, которые являются глобальными или специфическими для человека? Разговор — это глобальная команда, но, скажем, певец клинка может использовать команду песни клинка, а воин — нет? - person b.pell; 08.10.2015
comment
Я имею в виду, как заставить игру реагировать на глобальные команды. Я знаю, что могу сделать это так: CallByName(gc, Console.ReadLine, CallType.Method) Но это будет означать, что я не могу вызывать такие команды, как Look & Direction. Кроме того, как мне заставить игру реагировать на глобальный разговор? Должен ли я кодировать это так: If CallByName(gc, Talk, CallType.Method) Then Console.WriteLine(Вы говорите со мной.) Или я что-то упустил? Я не думал о разных классах, но я уверен, что это можно сделать с помощью If/Then, который будет реагировать на переменную или нет? - person Brin Žvan; 08.10.2015

Я бы подошёл к текстовому приключению со следующей общей структурой:

В главном модуле прокручивайте процесс каждого "хода".

  1. Отобразите любой текст подсказки, если это необходимо.
  2. Чтение пользовательского ввода.
  3. Проверьте список глобальных команд и выполните их соответствующим образом.
  4. Проверьте список локальных команд и выполните их соответствующим образом.
  5. Показать сообщение об ошибке.

Каждая выполняемая вами команда должна выполнять следующие действия:

  1. Рассчитать изменения любых переменных, затронутых командой
  2. Проверяйте каждое возможное изменение статуса игры сверху вниз и выполняйте последующие команды по мере необходимости. (например, смерть игрока, успех/неудача миссии, поражение врага и т. д.)

  3. Переместите историю в нужное место.

person Josh    schedule 07.10.2015
comment
Я постараюсь следовать чему-то подобному в своей игре. В данный момент я просто тестирую и привел код в своем посте в качестве примера. - person Brin Žvan; 07.10.2015