¿Cómo implementar las "cartas de efectos especiales" del juego de cartas coleccionables?

16

Estoy tratando de escribir una especie de juego de cartas coleccionables aquí, de alguna manera, es similar a Magic The Gathering , o Yu-Gi-Oh! juego de cartas.

Para aquellos de ustedes que no están familiarizados con él, básicamente, en el juego, hay un tipo especial de tarjeta (cartas de hechizo / cartas de trampa / etc.), que tiene efectos especiales que pueden cambiar las reglas del juego. Lo que no tengo ni idea es cómo implementar la lógica de estas tarjetas. Tengo una idea de almacenar los datos de la tarjeta con algunas banderas que pueden indicar qué tipo de habilidad tiene, pero eso sería muy limitado en lo que puede hacer (solo algunas modificaciones simples de estadísticas, tal vez).

Para darte una idea de qué tipo de efectos pueden tener estas cartas, aquí hay un ejemplo de los efectos de las cartas de hechizo que están presentes en Yu-Gi-Oh! juego de cartas:

  • Revive una criatura que ha sido destruida
  • Toma el control de la criatura del oponente
  • Modifique las estadísticas de la criatura en función de algunas condiciones (por ejemplo, número de criaturas con ciertos nombres que han sido destruidos)
  • Invocación especial de ciertas criaturas si se cumplen algunas condiciones.
  • Fusiona dos o más criaturas en una criatura más fuerte.
  • Inmunidad a algunos de los efectos de las cartas especiales.

Konami ha realizado varios videojuegos del juego, completos con la IA y la variedad de miles de cartas. No creo que sea posible codificar la base de datos completa, ¿verdad?

Ahora, por supuesto, lo que intento hacer es en ningún lugar tan complejo como esos juegos, pero tengo curiosidad, ¿cómo implementan estos?

hndr
fuente

Respuestas:

17

Hay varios proyectos de código abierto de esta naturaleza, con diferentes enfoques para implementar las reglas. Aquí hay una entrada de blog del creador de una de las implementaciones de MtG más conocidas, CardForge. Puede que no sea una lista completa, pero contiene varios proyectos de código abierto en los que simplemente puede navegar por el código o visitar los foros para preguntas específicas.

Como respuesta real: su mejor apuesta para un marco robusto es emplear estrictamente la programación orientada a objetos. Cada acción, cada disparador, cada habilidad es un objeto. Zonas como Mano, Biblioteca también son objetos, no hace falta decirlo. En el motor de Reglas, nunca pase objetos tontos como cadenas o enteros para describir objetos del juego, sino solo sus objetos.

Cada acción pone un número de disparadores en una pila, donde cualquier otra habilidad puede verificar si les importa o no ese disparador en particular, y si lo hacen, disparan sus propias acciones, creando potencialmente nuevos disparadores, etc.

Luego, trabajas esas pilas de acuerdo con las reglas del juego, hasta que la pila esté vacía, momento en el que se pueden tomar nuevas acciones, etc.

Idealmente, si implementa perfectamente las reglas del juego, su código de reglas no contiene una sola tarjeta codificada. Las tarjetas de codificación rígida pueden crear accesos directos convenientes, pero a la larga, esto hinchará su código y creará posibles dificultades, como cuando se lanzan nuevas tarjetas que interactúan con esas tarjetas de una manera novedosa. En un juego como MtG con más de 12,000 cartas únicas y sin fin a la vista, hay MUCHAS interacciones de este tipo.

Hackworth
fuente
1
Buena respuesta. Desde el mundo de la programación funcional, quisiera que cada tarjeta fuera un cierre sobre el entorno del juego, para ser aún más ridículamente genérico. Por ejemplo, una tarjeta podría crear aceptablemente una nueva "Área" agregando una lista de tarjetas a la lista de áreas. Concretamente: Zombie Monster Mayhem: todas las criaturas derrotadas son revividas en el nuevo "Cementerio Comunal" sin sus habilidades especiales, y atacan al azar a un jugador en base al lanzamiento de un dado.
brice
Enlace adicional: github.com/Fluorohydride/ygopro-core para una famosa implementación de código abierto de YGO, ya que YGO también se mencionó en la pregunta.
SK19
2

Es una tarea bastante inútil intentar incorporar todo eso solo con modificadores y variables. Tendría que codificar las funciones o, más probablemente, tener un script que interprete durante el tiempo de ejecución. Expondría las funciones necesarias para verificar el estado del tablero y las cubiertas y cementerios al script y las funciones para ejecutar acciones, y así sucesivamente. La secuencia de comandos es solo una cadena simple para almacenar junto con las otras variables asociadas con la tarjeta.

Toni
fuente
O, como sugirió Hackworth, tener algún tipo de bloque común que se combina para obtener el comportamiento requerido. Creo que también requeriría algunos bloques lógicos además de lo que sugirió. Tener bloques de comportamiento compartidos podría facilitar el filtrado de tarjetas que tienen algún tipo de cualidades compartidas.
Toni
1

También estoy planeando un juego de cartas usando lenguajes web con mysql db. Actualmente estoy optando por una configuración muy genérica, por lo que se mantiene muy flexible para nuevas tarjetas únicas. Por ejemplo en lugar de:

reduceHitPoints() { } 
reduceMana() { }
reduceSpeed() { }

podría ser fácilmente:

reduce($attacker, $target, $reduceWhat, $amount) { }
massReduce($attacker, Array $targets, $reduceWhat, $amount) { }

aplicar este concepto para todas las acciones simplificará las clases, permitirá la creación de nuevas tarjetas simplemente agregando una sola fila a la tabla de tarjetas.

Todas las opciones y habilidades se definirán en la base de datos en esa única fila.

appthat
fuente