Я пишу ИИ для принятия решений в игре и придумал следующий фрагмент кода.
if(pushedLeft && leftFree && leftExists)
GoLeft();
else if(pushedRight && rightFree && rightExists)
GoRight();
else if(leftFree && leftExists)
GoLeft();
else if(rightFree && rightExists)
GoRight();
else if(pushedLeft && leftExists)
GoLeft();
else if(pushedRight && rightExists)
GoRight();
else if(leftExists)
GoLeft();
else if(rightExists)
GoRight();
// else do nothing...
Довольно длинный поток if
операторов с похожими условными операторами!
Обратите внимание, что это создает хороший шаблон:
L1 L2 L3 -> L
R1 R2 R3 -> R
L2 L3 -> L
R2 R3 -> R
L1 L3 -> L
R1 R3 -> R
L3 -> L
R3 -> R
(nothing) -> 0
Цель этого кода — решить, должен ли объект двигаться влево или вправо (или не двигаться вообще), на основе некоторых входящих информация о состоянии. Каждая часть информации имеет различный приоритет. Я мог бы записать это в упорядоченном списке следующим образом:
Highest Priority
----------------
Don't ever move into an invalid space
Prefer to move into an unoccupied space
Prefer to move in the push direction
Prefer to move left
----------------
Lowest Priority
Кажется очевидным, что добавление дополнительных информационных входов, на основании которых принимается это решение, удвоит количество условных выражений. количество возможных значений для этих входных данных (например, разрешение вверх/вниз/влево/вправо) также удвоит количество условных выражений (то есть это n×m 2условных выражений, верно?)
Итак, мой вопрос:
Есть ли хороший, удовлетворительный, элегантный способ закодировать это?
Я думаю, что должен быть хороший способ "n×m" сделать это (редактировать: Изначально у меня здесь было «n+m», но это кажется невозможным, так как входных условий n×m). Что-то, что применимо как к моему коду здесь, так и к проблеме в целом?
Предпочтительно что-то, что будет работать так же хорошо или лучше, чем условная версия выше.В идеале что-то, что позволяет избежать выделения кучи, что важно для использования в сценариях разработки игр (хотя при необходимости их всегда можно оптимизировать с помощью кэширования и т.п.).
А также: Существуют ли для этой проблемы какие-либо «удобные для Google термины»? Подозреваю, что это нередкая проблема, но я не знаю, как ее назвать.
Обновление:Идея, благодаря ответу Superpig, состоит в том, чтобы рассчитать баллы для различных вариантов. Что-то вроде этого:
int nothingScore = 1 << 4;
int leftScore = (1 << 1) + (pushedLeft ? 1 << 2 : 0) + (leftFree ? 1 << 3 : 0) + (leftExists ? 1 << 5 : 0);
int rightScore = (pushedRight ? 1 << 2 : 0) + (rightFree ? 1 << 3 : 0) + (rightExists ? 1 << 5 : 0);
Безусловно, есть более приятный способ написания кода оценки (а также альтернативные способы его оценки). И еще остается вопрос выбора того, что делать после подсчета очков. И, конечно же, может быть лучший метод, полностью не связанный с подсчетом очков.
Обновление 2:Я опубликовал и принял свой собственный ответ здесь(поскольку Superpig не является полным решением, и до сих пор нет другого ответа, даже удаленнона правильном пути). Вместо того, чтобы оценивать различные результаты, я выбрал подход исключения вариантов с использованием битового поля. Это позволяет принимать решение, используя только одно целое число для памяти.