Comment implémenter les «cartes d'effets spéciaux» du jeu de cartes à collectionner?

16

J'essaie d'écrire une sorte de jeu de cartes à collectionner ici, d'une certaine manière, il est similaire à Magic The Gathering ou Yu-Gi-Oh! jeu de cartes.

Pour ceux d'entre vous qui ne la connaissent pas, en gros, dans le jeu, il existe un type spécial de carte (Cartes Magie / Cartes Piège / etc.), qui ont des effets spéciaux qui peuvent déformer les règles du jeu. Ce que je ne sais absolument pas, c'est comment implémenter la logique de ces cartes. J'ai une idée de stocker les données de la carte avec des indicateurs qui peuvent signaler le type de capacité dont elle dispose, mais cela serait très limité dans ce qu'elle peut faire (seulement une simple modification des statistiques, peut-être).

Pour vous donner une idée du type d'effets que ces cartes peuvent avoir, voici un exemple des effets des cartes de sorts qui sont présents dans Yu-Gi-Oh! jeu de cartes:

  • Ravivez une créature qui a été détruite
  • Prenez le contrôle de la créature de l'adversaire
  • Modifier les statistiques de la créature en fonction de certaines conditions (par exemple, le nombre de créatures avec certains noms qui ont été détruites)
  • Invoquez spécialement certaines créatures si certaines conditions sont remplies.
  • Fusionnez deux créatures ou plus en une créature plus forte.
  • Immunité contre certains effets spéciaux des cartes.

Konami a réalisé plusieurs jeux vidéo du jeu, avec l'intelligence artificielle et une variété de milliers de cartes. Je ne pense pas qu'il soit réellement possible de coder en dur la base de données entière, n'est-ce pas?

Maintenant, bien sûr, ce que j'essaie de faire n'est nulle part aussi complexe que ces jeux, mais je suis curieux, comment les implémentent-ils?

hndr
la source

Réponses:

17

Il existe plusieurs projets open source de cette nature, avec différentes approches de mise en œuvre des règles. Voici une entrée de blog du créateur de l'une des implémentations MtG les plus connues, CardForge. Ce n'est peut-être pas une liste complète, mais il contient plusieurs projets open-source où vous pouvez simplement parcourir le code ou visiter les forums pour des questions spécifiques.

En tant que réponse réelle: votre meilleur pari pour un cadre robuste est d'utiliser strictement la programmation orientée objet. Chaque action, chaque déclencheur, chaque capacité est un objet. Des zones comme Hand, Library sont également des objets, il va sans dire. Dans le moteur de règles, ne passez jamais autour d'objets stupides comme des chaînes ou des entiers pour décrire des objets de jeu, mais uniquement vos objets.

Chaque action place un certain nombre de déclencheurs sur une pile, où toutes les autres capacités peuvent vérifier si elles se soucient de ce déclencheur particulier, et si c'est le cas, elles déclenchent leurs propres actions, créant potentiellement de nouveaux déclencheurs, etc.

Ensuite, vous réduisez ces piles selon les règles du jeu, jusqu'à ce que la pile soit vide, auquel cas de nouvelles actions peuvent être prises, etc.

Idéalement, si vous implémentez parfaitement les règles du jeu, votre code de règles ne contient pas une seule carte codée en dur. Les cartes de codage en dur peuvent créer des raccourcis pratiques, mais à long terme, cela gonflera votre code et créera des pièges potentiels, comme lorsque de nouvelles cartes sont publiées qui interagissent avec ces cartes d'une manière nouvelle. Dans un jeu comme MtG avec plus de 12 000 cartes uniques et sans fin en vue, il y a BEAUCOUP de telles interactions.

Hackworth
la source
1
Bonne réponse. En venant du monde de la programmation fonctionnelle, je voudrais que chaque carte soit une fermeture sur l'environnement de jeu, pour être encore plus ridiculement générique. Par exemple, une carte pourrait créer de manière acceptable une nouvelle "zone" en ajoutant une liste de cartes à la liste des zones. Concrètement: Zombie Monster Mayhem: toutes les créatures vaincues sont relancées dans le nouveau "cimetière communal" sans leurs capacités spéciales, et attaquent aléatoirement un joueur sur la base d'un lancer de dés.
brice
Lien supplémentaire: github.com/Fluorohydride/ygopro-core pour une implémentation YGO open source célèbre, puisque YGO a également été mentionné dans la question.
SK19
2

Il est assez futile d'essayer d'incorporer tout cela avec des commutateurs et des variables seuls. Vous devez soit avoir des fonctions de code en dur, soit, plus probablement, avoir un script que vous interprétez pendant l'exécution. Vous exposeriez les fonctions nécessaires pour vérifier l'état du plateau et des ponts et cimetières du script et les fonctions pour exécuter des actions, etc. Le script n'est alors qu'une simple chaîne à stocker avec les autres variables associées à la carte.

Toni
la source
Ou, comme l'a suggéré hackworth, avoir une sorte de blocs communs qui sont combinés pour obtenir le comportement requis. Cela nécessiterait également des blocs logiques en plus de ce qu'il a suggéré, je pense. Le fait d'avoir des blocs de comportement partagés pourrait faciliter le filtrage des cartes ayant des qualités communes.
Toni
1

Je prévois également un jeu de cartes utilisant des langages Web avec mysql db. J'opte actuellement pour une configuration très générique afin qu'elle reste très flexible pour de nouvelles cartes uniques. Par exemple au lieu de:

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

cela pourrait facilement être:

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

appliquer ce concept à toutes les actions simplifiera les classes, permettra de créer de nouvelles cartes en ajoutant simplement une seule ligne dans votre tableau de cartes.

Toutes les options et capacités seront définies dans la base de données de cette seule ligne.

appthat
la source