Qué patrones de diseño se pueden usar para crear un sistema de reglas / validación para un juego como el ajedrez (este es solo un ejemplo simple, el juego real necesita conjuntos de reglas más difíciles)
He leído varias preguntas en este sitio y no he encontrado una respuesta concluyente ni una respuesta que me señale en la dirección correcta.
Este sistema requeriría lo siguiente:
- Cada objeto que tiene reglas aplicadas debe implementar una interfaz específica con un método que sea el punto de partida para la validación
- La regla debe aplicarse en 2 pasos: primero, debe validarse (el peón A puede moverse al cuadrado D4), si es verdadero, ejecute el método A si es falso, luego ejecute el método B
- Cada objeto puede tener múltiples reglas que deben aplicarse en una secuencia específica. Cuando finaliza la regla 1, la regla 2 debería comenzar a validar, etc.
- Cada regla separada (por ejemplo: solo puede moverse 1 casilla, solo puede moverse diagonalmente, etc.) debe estar en su propia clase y debe ser reutilizable y aplicable a los objetos que necesitan reglas.
- Tenga en cuenta que esto se usará en un juego multijugador en el backend
- Tenga en cuenta que cada regla necesita varios objetos para probar su validez, por ejemplo, normalmente un peón puede moverse 1 casilla, ahora la siguiente casilla en el tablero de juego se llena con un peón de su oponente. Resultado: tu peón no puede moverse. El peón debe incluir las otras posiciones de peones, o el tablero de juego en su validación.
Otra palabra para estas reglas sería límites de comportamiento.
game-design
design-patterns
Thomas
fuente
fuente
Respuestas:
Piense en un juego como una secuencia de estados , separados por movimientos . Cada vez que un jugador hace un movimiento, se genera un nuevo estado.
(¡Es como este cómic de XKCD !)
Cómo
Crea una clase
Move
, que representa un movimiento realizado por un jugador . (En Reversi, una descripción suficiente es un conjunto de coordenadas del tablero donde se colocará una pieza. En Ajedrez, una coordenada de origen y destino es suficiente).Crea una clase
GameState
, que represente el estado del juego en cualquier momento . (En Reversi, una descripción suficiente sería el contenido del tablero y el turno de qué jugador es. En Ajedrez, también necesitarías almacenar si todavía es posible que cada jugador se enroque en el flanco de rey o en el flanco de dama).Ahora, probablemente puedas imaginar
GameState
tener unisMoveLegal(Move)
método. Después de todo, contiene toda la información que necesita para tomar esa decisión.Por qué
Este diseño aísla limpiamente la lógica de la regla, reduciendo las dependencias entre componentes.
¡También hace que la IA sea fácil! Puede generar trivialmente todos los movimientos posibles a partir de a
GameState
, verificar si son legales, generar másGameState
s de ellos y básicamente construir un árbol que pueda usar para minimax , tal vez con poda alfa-beta .fuente