Máquinas de estado: Objeto de estado versus verificación secuencial: ¿cuáles son las ventajas y desventajas?

8

No sé mucho sobre la máquina de estados finitos en IA u otros comportamientos del juego en el juego, excepto este tutorial rápido con un minero: http://www.ai-junkie.com/architecture/state_driven/tut_state1.html que está orientado a objetos.

Realmente no sé si este tutorial describe el patrón de estado o no, ¿qué te parece?

No estoy hablando de otras cosas más orientadas a la aritmética, como la dirección o la física o la búsqueda de caminos o colisiones, sino más bien sobre la lógica del juego, la inteligencia artificial impulsada por el estado y cosas que involucran muchos estados ify / o switches simultáneos

¿Cuáles son las ventajas y desventajas de utilizar un patrón de estado o una verificación secuencial de una estructura de estado simple como esta:

struct States
{
bool is_walking, is_running, holds_a_weapon, is_crouch;
int weapon_id, int id_team;
};

void HandleStates (States state)
{
//etc
}
jokoon
fuente
2
Creo que es posible que necesite formular su pregunta un poco mejor, pero una respuesta rápida a lo anterior para que pueda hacerlo es que, en general, el estado elimina las verificaciones If. cambie (estado) {case blah} para crear una tabla de salto, o mi forma personal favorita de hacer las cosas, punteros de función o delegados en una pila o cola si la IA debe volver a lo que estaban haciendo antes o pasar a lo siguiente. ..
James

Respuestas:

10

Trataré de responder esto lo mejor que pueda, pero hay ciertas "mejores prácticas" de las que no estoy seguro, pero trataré de analizarlo de la manera más limpia posible.

FSM

En primer lugar, el tutorial de Miner es de Programming Game AI by Example de Mat Buckland (que recomiendo que consigas como introducción a AI). Él usa una enumeración para cada estado, NO una estructura. Con la estructura en su ejemplo, tiene booleanos como estados, por lo que podría tener cualquier número de estos al mismo tiempo. Esto puede conducir al comportamiento que desea, pero la mayoría de las veces con FSM (máquinas de estado finito) conduce a un comportamiento indeseable.

Por ejemplo:

enum
{
WANDER_AROUND,
ATTACK,
RUN_AWAY,
};

En segundo lugar, esa no es la única forma en que describe los estados. La forma en que personalmente prefiero (dependiendo de la situación) es crear una clase abstracta llamada State que tenga las funciones Enter (), Exit () y Update (). Luego crea mis estados como subclases de la clase State.

Como esta imagen (que se encuentra en la página 2 de ese enlace en realidad): texto alternativo

Patrón de estado

En mi opinión personal, el patrón de estado es solo una parte del diseño del software donde el software tiene varios estados. La implementación depende del desarrollador. No creo que haya una diferencia adecuada entre usar una declaración de cambio grande o crear una máquina de estado completa para ejecutar todos sus estados como he descrito anteriormente. Básicamente están haciendo lo mismo. En ese sentido, la respuesta a una de sus preguntas es sí, creo que esa página describe el patrón de estado.

Pros contras

Hay ventajas y desventajas de cualquier método que use para implementar un diseño basado en el estado.

Uso de una declaración If / Else o Switch

Pros:

  • Muy fácil de agregar y verificar las condiciones de los estados
  • Puede ser prototipo muy rápido

Contras:

  • Cuando tienes una gran cantidad de estados, puede volverse muy feo, muy rápidamente.
  • Hacer un seguimiento de las transiciones, los efectos cuando el estado ingresa / sale o cualquier cosa específica del estado es difícil

Usando una máquina de estado orientada a objetos

Pros:

  • Altamente extensible: lo único que debe hacer es crear un nuevo estado que herede la clase de estado abstracto
  • Fácilmente mantenible: no tiene que preocuparse por el código de aspecto de espagueti ya que cada estado reside en su propia clase. Puede ver fácilmente las condiciones asociadas con ese estado sin preocuparse por los otros estados.
  • Intuitivo: si está trabajando en un proyecto de equipo con este tipo de máquina de estados, será mucho más fácil para la persona que lee su código. No tendrán que leer líneas sobre líneas de código solo para llegar a un cierto estado ("Siempre programe como si el programador que mantiene su código sea un psicópata que sabe dónde vive!" :))

Contras:

  • Ligera curva de aprendizaje: este diseño puede demorar un poco en comprender completamente al implementar
  • Sinceramente, no puedo pensar en nada más, ya que prefiero de esta manera, pero si alguien desea agregarle algo, solo comente y lo agregaré.

Espero que conteste todas sus preguntas. De hecho, acabo de abrir mi copia de Programming Game AI con Example y Mat menciona que la máquina de estado se conoce como el "patrón de diseño de estado". Personalmente, no estoy de acuerdo, pero a cada uno lo suyo.

Espero eso ayude :)

Ray Dey
fuente
1
+1 esto describe esencialmente cómo creé mi máquina de estado. Está funcionando bien.
Kyle C
¿Podría argumentar que hay un impacto en el rendimiento con el patrón de "máquina de estado orientada a objetos", por muy leve que sea?
Noob Saibot
@NoobSaibot Sí, pero puedes discutir eso sobre cualquier cosa. El if-else podría sufrir una pobre predicción de rama, el patrón de estado como se describió anteriormente puede sufrir la sobrecarga de búsqueda de vtable. Ambos son poco probables a menos que tenga muchos estados. Entonces, la verdadera respuesta a su pregunta es "depende".
Ray Dey