Я пишу какой-то AI для принятия решений для игры, и я придумал следующий фрагмент кода.
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" (edit: у меня здесь было "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);
Там certianly более хороший способ написать код оценки (и альтернативные способы забить его тоже). И тогда все еще вопрос выбора, что делать, как только счет рассчитывается. И, конечно, может быть лучший метод целиком, который не включает в себя оценку.
Обновить 2: Я отправил и принял свой собственный ответ здесь (поскольку Superpig не является полным решением, и до сих пор никакой другой ответ даже удаленно на правильном пути). Вместо того, чтобы подсчитывать различные результаты, я выбрал подход исключения с использованием битового поля. Это позволяет принять решение, используя только одно целое для памяти.