J'essaie d'avoir une idée de la façon de concevoir et de penser de manière orientée objet et je souhaite obtenir des commentaires de la communauté sur ce sujet. Ce qui suit est un exemple de jeu d'échecs que je souhaite concevoir de manière OO. Il s'agit d'une conception très large et mon objectif à ce stade est simplement d'identifier qui est responsable de quels messages et comment les objets interagissent pour simuler le jeu. Veuillez indiquer s'il y a des éléments de mauvaise conception (couplage élevé, mauvaise cohésion, etc.) et comment les améliorer.
Le jeu d'échecs a les classes suivantes
- Planche
- Joueur
- Pièce
- Carré
- Jeu d'échecs
Le tableau est composé de carrés et le tableau peut donc être chargé de la création et de la gestion des objets Square. Chaque pièce est également sur un carré, donc chaque pièce a également une référence au carré sur lequel elle se trouve. (Est-ce que ça a du sens?). Chaque pièce est alors responsable de se déplacer d'une case à l'autre. La classe de joueur contient des références à toutes les pièces qu'il possède et est également responsable de leur création (le joueur doit-il créer des pièces?). Player a une méthode takeTurn qui à son tour appelle une méthode movePiece qui appartient à la classe de pièce qui change l'emplacement de la pièce de son emplacement actuel à un autre emplacement. Maintenant, je ne sais pas exactement de quoi la classe du Conseil doit être responsable. J'ai supposé qu'il était nécessaire de déterminer l'état actuel du jeu et de savoir quand le jeu est terminé. Mais quand un morceau le change ' s emplacement comment le tableau doit-il être mis à jour? devrait-il maintenir un tableau séparé de carrés sur lesquels les pièces existent et qui sont mises à jour au fur et à mesure que les pièces se déplacent?
De plus, ChessGame crée initialement le plateau et les objets du joueur qui à leur tour créent respectivement des carrés et des pièces et démarrent la simulation. En bref, cela pourrait ressembler au code de ChessGame
Player p1 =new Player();
Player p2 = new Player();
Board b = new Board();
while(b.isGameOver())
{
p1.takeTurn(); // calls movePiece on the Piece object
p2.takeTurn();
}
Je ne sais pas comment l'état du conseil d'administration sera mis à jour. La pièce doit-elle avoir une référence à la planche? Où devrait être la responsabilité? Qui détient quelles références? Veuillez m'aider avec vos entrées et signaler les problèmes dans cette conception. Je ne me concentre délibérément sur aucun algorithme ou sur d'autres détails du jeu car je ne m'intéresse qu'à l'aspect design. J'espère que cette communauté pourra fournir des informations précieuses.
takeTurn()
si le mouvement de p1 met fin à la partie. Commentaire moins pointilleux: je trouve plus naturel d'appeler les joueurswhite
etblack
.canMove()
fonction. Et lorsque le déplacement est terminé, toutes les autres pièces mettent à jour leur propre copie interne du tableau. Je sais que ce n'est pas optimal, mais c'était intéressant à l'époque d'apprendre le C ++. Plus tard, un ami non joueur d'échecs m'a dit qu'il en auraitclasses
pour chaque case au lieu de chaque pièce. Et ce commentaire m'a semblé très intéressant.Réponses:
En fait, je viens d' écrire une implémentation C # complète d'un échiquier, de pièces, de règles, etc. Voici à peu près comment je l'ai modélisé (implémentation réelle supprimée car je ne veux pas prendre tout le plaisir de votre codage):
L'idée de base est que Game / Board / etc stocke simplement l'état du jeu. Vous pouvez les manipuler pour créer une position par exemple, si c'est ce que vous voulez. J'ai une classe qui implémente mon interface IGameRules qui est responsable de:
Séparer les règles des classes de jeu / plateau signifie également que vous pouvez implémenter des variantes relativement facilement. Toutes les méthodes de l'interface de règles prennent un
Game
objet qu'elles peuvent inspecter pour déterminer quels mouvements sont valides.Notez que je ne stocke pas d'informations sur les joueurs
Game
. J'ai une classe distincteTable
qui est chargée de stocker les métadonnées du jeu telles que qui jouait, quand le jeu a eu lieu, etc.EDIT: Notez que le but de cette réponse n'est pas vraiment de vous donner un code de modèle que vous pouvez remplir - mon code contient en fait un peu plus d'informations stockées sur chaque élément, plus de méthodes, etc. Le but est de vous guider vers le objectif que vous essayez d'atteindre.
la source
Move
est une classe qui vous permet de stocker l'historique complet des mouvements dans une liste deGame
délégation à un réalisateurIGameRules
ou vous appliquez des règles en dehors de l'objet? Ce dernier semble inapproprié puisque le jeu ne peut pas protéger son propre état non?Voici mon idée, pour une partie d'échecs assez basique:
la source
J'ai récemment créé un programme d'échecs en PHP ( site Web cliquez ici , source cliquez ici ) et je l'ai orienté objet. Voici les classes que j'ai utilisées.
generate_legal_moves()
code ici. Cette méthode reçoit une carte, dont c'est le tour, et quelques variables pour définir le niveau de détail de la sortie, et elle génère tous les mouvements légaux pour cette position. Il renvoie une liste de ChessMoves.int
s.J'essaie actuellement de transformer ce code en une IA d'échecs, il doit donc être RAPIDE. J'ai optimisé la
generate_legal_moves()
fonction de 1500 ms à 8 ms et je travaille toujours dessus. Les leçons que j'en ai tirées sont ...int
lorsque cela est possible. C'est pourquoiChessSquare
stocke le rang et le fichier en tant queint
, plutôt que de stocker également un alphanumériquestring
avec une notation carrée lisible par l'homme, telle que "a4".Je sais que c'est vieux, mais j'espère que cela aide quelqu'un. Bonne chance!
la source