@ent1k1337

Как выполнить псевдокод?

Я разрабатываю игру на unity в которой нужно составлять алгоритм из доступных команд (механика составления алгоритма взята из этих игр: 7 Billion Humans или Human Resource Machine). При построении алгоритма в файл записывается псевдокод алгоритма, в нем есть как методы, так циклы и ветвления. Как этот псевдокод выполнить на c#.

6221290a141ec043755231.jpeg
a:
if s != worker or
 sw != worker:
	step s
	jump a
endif
b:
takefrom s
if myitem < 50:
	giveto sw
	step e
	jump b
else:
	step w
	step w
endif
c:
step n
jump c

P.S. Если есть идеи как можно перенести алгоритм из игры в код избегая псевдокод поделитесь.
  • Вопрос задан
  • 402 просмотра
Пригласить эксперта
Ответы на вопрос 3
Vindicar
@Vindicar
RTFM!
Используй паттерн Компоновщик (Composite) + Интерпретатор (Interpreter) из набора паттернов Gang of Four.
Описываешь базовый интерфейс для среды выполнения и для команды:
//окружение хранит текущее состояние программы плюс предоставляет средства взаимодействия с "окружающим миром".
public interface IProgramEnvironment
{
    Dictionary<str, int> Variables {get;} //хранилище переменных
    IProgramOperator CurrentOperator {get; set;} //текущая команда - нужно для переходов
    //ну и что там ещё тебе может потребоваться? Операции ввода-вывода, и т.п.
}
//просто составной оператор
public interface ICompoundOperator: IList<IProgramOperator>
{
    void ExecuteAll(IProgramEnvironment env); //выполнить дочерние команды
    string ToString(); //для отладки
}
//абстрактный оператор, его будут реализовывать классы операторов
public interface IProgramOperator
{
    int LineNumber; //номер строки, для удобства обозначения
    IReadOnlyList<ICompoundOperator> ChildrenBlocks {get;} //списки дочерних команд, если они есть
    void Execute(IProgramEnvironment env);  //выполняем команду в окружении. Может потребоваться возвращать значение
    string ToString(); //для отладки
    void Render(); //для отображения на экране?
}

Затем описываешь отдельные команды как отдельные классы, реализующие IProgramOperator.
Если оператор составной, то у него ChildrenBlocks будет не пустым, а будет содержать списки вложенных команды. Например, у цикла будет 2 таких списка (условие и тело), а у ветвления - 3 (условие, если, иначе).
Тогда при выполнении оператор выполняет свой метод Execute(), и если надо, выполняет те или иные дочерние операторы.
Соответственно у тебя получится дерево объектов-команд. Корнем дерева будет ICompoundOperator - тело программы. В рамках исполнения программы ты, по сути, обходишь это дерево в глубину.

Будут некоторые проблемы с реализацией пошагового выполнения, но это можно решить, если превратить метод Execute() в генератор, который будет приостанавливать своё выполнение после каждой команды. Заодно решится вопрос "последнего вычисленного значения" - можно будет просто yield'ить результаты вычислений.
IEnumerable<object> Execute(IProgramEnvironment env)
Ответ написан
Комментировать
yarosroman
@yarosroman Куратор тега C#
C# the best
Копать в сторону ANTLR (antlr.org) или Gold Parcer (www.goldparser.org)
Ответ написан
Комментировать
vabka
@vabka Куратор тега C#
Токсичный шарпист
Как этот псевдокод выполнить на c#.

Ну тебе его нужно спарсить и выполнить :)
Для парсинга, кроме названного ANTLR можно ещё использовать Irony или Yoakke
Если есть идеи как можно перенести алгоритм из игры в код избегая псевдокод поделитесь.

Использовать какой-нибудь реально существующий встраиваемый язык, типа lua
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы