1°/ Attendus techniques

 

NB : ces attendus viennent en sus de ceux qui ont été précisés dans l'article général : Présentation générale (objectifs, attendus, organisation)

 

1.1°/ Choix du mode de jeu

  • Le mode de jeu représente qui joue : 2 humains, 2 ordinateurs, ou 1 humain+1 ordinateur. Ce choix doit être effectué grâce au premier paramètre de votre programme (cf. le tutoriel "The Hole - console" comme exemple).
  • La façon de nommer les joueurs peut être soit en dur dans le code, soit via des paramètres du programme, soit au travers d'une saisie clavier. Dans ce cas, il faut que ce principe de saisie soit compatible avec le fait de lancer le jeu avec un fichier d'entrée (cf. 1.4°)
  •  Cas particulier de la bataille navale : la variante de jeu peut être soit choisie via un paramètre du programme, soit via une saisie. Dans ce cas, il faut que ce principe de saisie soit compatible avec le fait de lancer le jeu avec un fichier d'entrée (cf. 1.4°)

1.2°/ Visualisation du plateau de jeu

  • Le plateau principal du jeu doit faire apparaître un système de localisation simple permettant d'identifier chaque emplacement possible pour un élément du jeu (généralement un pion)
  • Cela peut être comme dans le tutoriel "The Hole - console", avec des coordonnées 2D lettre+chiffre, ou bien un tout autre système qui soit suffisamment simple et compréhensible par n'importe qui.
  • Ce système de coordonnées doit être utilisé lors de la saisie des ordres de jeu (cf. ci-après).

1.3°/ Saisie des ordres de jeu

  • Lorsqu'un joueur humain doit jouer, la saisie de son (ou ses) coup doit se faire via le clavier, grâce à une unique ligne de texte.
  • La syntaxe de cette ligne est laissé libre (sauf exception du stop, ci-dessous), mais il doit faire intervenir le système de coordonnées utilisé pour l'affichage.
  • Il doit également tenir compte des règles du jeu, ce qui peut donner lieu à une syntaxe variée, notamment quand les actions de jeu sont plus complexe qu'un simple déplacement. C'est le cas par exemple avec le placement des bateaux dans la bataille (c.a.d. besoin de spécifier l'orientation du bateau), ou bien pour le "roi des roses", quand on veut utiliser un carte héros ou piocher.

Exception : si la ligne tapée contient la chaîne "stop", la partie et le jeu doivent d'arrêter immédiatement.

  • Quel que soit le jeu, si un ordre de jeu est invalide, le programme doit redemander un ordre.
  • Cela implique donc de toujours vérifier la validité d'un coup en fonction du format de saisie ET des règles du jeu.

 

1.4°/ Fichiers d'entrée

  • Quand le jeu est exécuté en mode 2 humains, il faut pouvoir utiliser un fichier texte en entrée standard.
  • Ce fichier texte contient la suite des ordres de jeu à jouer, comme si les 2 humains les tapaient au clavier. 
  • Exemple, dans l'archive de la solution de 'The Hole - console', il y a un fichier HoleConsole/out/production/HoleConsole/in.txt, avec dedans :
1A1
4B1
3B2
3C1
4B3
2C2
2A2
1C3
  • Ce sont les 8 ordres de jeu nécessaires pour terminer une partie.
  • Si on se place dans HoleConsole/out/production/HoleConsole, et que l'on tape : java HoleConsole <in.txt, la partie se déroule sans intervention clavier, mais avec tous les affichages.

 

  • Dans le rendu du jalon 1, vous devez créer plusieurs fichiers d'entrée, permettant d'illustrer notamment :
    • une partie normale et sa terminaison,
    • les possibilités de coups particuliers (par ex, jouer influence+héros dans le roi des roses),
    • les prises de pions (ou bateau) si le jeu le permet,
    • des ordres de jeux invalides, à cause d'une mauvaise syntaxe
    • des ordres de jeux invalides, à cause des règles (par ex, impossible de prendre un pion protégé),
  • Vous veillerez à ce que votre programme s'arrête (grâce à "stop") juste après la démonstration.
  • Quand un ordre est invalide, il faudra également que votre programme affiche clairement ce qui pose problème afin de rendre la démonstration convaincante.

 

  • Vous veillerez à donner un nom pertinent à chacun de ces fichiers afin que l'on identifie facilement ce qu'il vise à démontrer.

1.5°/ Cas particulier de la bataille navale

  • C'est le seul jeu où il y a deux phases de jeu : le placement des bateaux puis la bataille proprement dite.
  • Pour la première phase, on suppose que le joueur 1 place d'abord tout ses bateaux et c'est ensuite le tour du joueur 2.
  • Après le placement, la bataille commence automatiquement avec la saisie du premier tir du premier joueur.
  • Ce processus implique que les fichiers d'entrée doivent d'abord contenir X lignes concernant le placement des bateaux du joueur 1, puis X lignes pour le joueur 2, et ensuite directement des lignes représentant les ordres de tir des joueurs.

  

2°/ Méthodologie

 

2.1°/ préambule sur les framework

L'implémentation correcte d'un jeu ne se fait pas au hasard, sinon on est rapidement bloqué lorsque l'on veut ajouter des fonctionnalités. Le paradigme MVC permet d'éviter ce genre de problèmes, à condition de l'utiliser correctement, et en tenant compte du langage et des bibliothèques employés. C'est pourquoi il est très compliqué de développer un jeu "à partir de zéro" quand on ne connait pas très bien les avantages et limitations du langage et des bibliothèques. Cette problématique est d'ailleurs commune à quasi tous les types d'application.

La solution la plus simple consiste à utiliser un framework de développement , c.a.d. au sens strict une collection de fichiers formant la base de l'application + éventuellement quelques utilitaires pour aider à la compilation, test, ... Un framework va fortement cadrer la façon de structurer le code, voire fournir des fonctionnalités de gestion de l'application plus ou moins complètes. L'inconvénient d'un framework est justement le cadre qu'il impose, qui parfois ne correspond pas à l'envie naturelle du développeur de coder une fonctionnalité comme-ci ou comme-ça. L'autre inconvénient est le temps d'apprentissage nécessaire pour découvrir les facilités et limitations de ce framework, surtout quand la documentation est sommaire.

Mais dans l'ensemble, au niveau professionnel, l'utilisation d'un framework accélère de façon drastique le développement d'une application et permet d'avoir une cohérence entre les applications produites par une même entreprise. Cela limite également les "fantaisies" propres à chaque développeur, ce qui limite les bugs, favorise l'intégration continue, la maintenance, l'évolutivité, etc.

C'est pourquoi apprendre à utiliser un framework fait partie de la formation de tout informaticien. Dans le cadre du projet, ce framework est écrit en Java (+javaFx pour la deuxième version du jeu), mais vous aurez l'occasion de découvrir d'autres framework au cours de votre formation, notamment dans le domaine du Web ou du mobile.

 

2.2°/ découverte de boardifier-console

Pour cela, un tutoriel est disponible : Tutoriel 1 : créer un jeu de plateau en mode texte avec boardifier-console

Chaque étudiant DOIT le suivre. Ce tutoriel permet de créer un jeu de plateau très basique et peu intéressant, mais il présente la plupart des étapes nécessaires au codage de jeux plus complexes. A noter que dans ce tutoriel, il n'y a pas de partie test unitaire. Comme cela est demandé pour le jalon 1, il est également indispensable de suivre le tutoriel : Tutoriel 2 : ajouter JUnit à un projet IDEA

 

2.3°/ conception de la partie modèle

Après avoir suivi le tutoriel sur boardifier-console, vous devriez être capable de déterminer les classes qui vont être nécessaires pour représenter le modèle de votre jeu, ainsi que la plupart des attributs/méthodes de ces classes. Par exemple, quel que soit le jeu choisi, il y aura forcément :

  • une ou plusieurs classes représentant les pions/pièces du jeu (cf. classe Pawn du tutoriel),
  • une classe représentant l'unique "stage" du jeu (cf. classe HoleStageModel du tutoriel),
  • une classe permettant de créer les éléments du "stage" (cf. classe HoleStageFactory du tutoriel)
  • une ou plusieurs classes représentant les différentes zones sur le plateau de jeu (cf. classes HoleBoard et HolePawnPot du tutoriel).

 

Remarque 1 : le plateau de jeu peut comporter différentes zones, certaines avec la même fonction (par ex. les réservoir de murs dans le corridor), d'autres avec des fonctions différentes. Par exemple, dans le tutoriel, il y a deux zones différentes et pour chacune il y a une classe associée. C'est à vous de déterminer le nombre de classes nécessaires pour gérer toutes les zones du jeu. Globalement, un découpage avec de nombreuses zones + classes facilitera le codage de leur représentation graphique mais complexifiera la vérification de si un (dé)placement de pion est valide ou non. Qui plus est, cela générera sans doute pas mal de code copié/collé = pas génial. Ce sera l'inverse avec peu de zones. A vous de trouver le bon équilibre en fonction du jeu.

Remarque 2 : dans boardifier-console, chaque zone est représentée par une grille, avec plus ou moins de lignes et colonnes. Si l'on se réfère à la classe modélisant une grille (cf. GridElement), il est possible de stocker plusieurs éléments du jeu dans la même case d'une grille. Cependant, les 5 jeux proposés n'ont pas besoin d'utiliser cette possibilité. C'est même fortement déconseillé.

 

Concernant les attributs, la principale difficulté est de déterminer lesquels sont nécessaires pour représenter tous les états possibles du jeu, et dans quelle classe les mettre. Fort heureusement, grâce à l'architecture MVC, si l'on s'aperçoit qu'il manque un attribut, il est facile de l'ajouter au modèle sans que cela remette en question le reste de l'application. Il est donc possible de faire du développement incrémental en définissant certains attributs associés à des fonctionnalités précise, et par la suite, d'ajouter des attributs associés à d'autres fonctionnalités. C'est exactement le procédé utilisé dans le tutoriel.

La même remarque peut être faite à propos des méthodes. D'après le tutoriel, on voit qu'il y a principalement 4 types de méthode à définir, qui vont être appelées par la partie contrôle :

  • celles qui déterminent si une action est valide,
  • celles qui changent éventuellement l'état du jeu après : un (dé)placement de pion, la suppression d'un pion.

Il est parfaitement possible de développer ces fonctions l'une après l'autre.

 

2.4°/ conception de la prise de décision

Dans le tutoriel, l'ordinateur utilise une stratégie aléatoire pour jouer. Comme mentionné plus haut, ce n'est pas ce qui est demandé dans le projet. Cependant, cela permet d'illustrer comment créer une sous-classe de Decider et comment utiliser le modèle pour prendre la décision et transformer celle-ci en une suite d'actions de jeu.

L'énorme difficulté de cette conception est plutôt d'ordre algorithmique, à savoir trouver une stratégie et la coder. Il existe déjà toute une littérature dans le domaine de la théorie des jeux, notamment avec les jeux à alternance de 2 joueurs (dames, échecs, ...) et les algorithmes de type minimax, les méthodes de monte-carlo, ... Mais ces méthodes ne s'appliquent pas forcément au jeu que vous avez choisi ! A vous de trouver quelque chose d'adapté. Et sinon, vous pouvez toujours inventer votre propre algorithme de décision.

Dans tous les cas, pour trouver des stratégies de jeu, il est quasi obligatoire de maîtriser un minimum le jeu, donc de faire suffisamment de parties. Pour cela, il existe des versions en ligne et sinon, il est possible de se bricoler facilement un plateau en papier/carton pour tester..

Une fois 2 (ou plus) type de stratégies trouvées, il est possible de créer une sous-classe de Decider pour chacune. La seule contrainte est que le découpage en zones (mentionné dans la section précédente) soit déjà fixé. En effet, pour prendre une décision, il faut connaître l'emplacement des pions donc dans quelle case de quelle zone ils se trouvent.

A part cette contrainte, le codage des stratégies peut être fait en parallèle de celui du modèle.

 

2.5°/ conception des test unitaires

Pourquoi et comment créer des test unitaires sera essentiellement abordé lors des cours. En revanche, il est impératif que l'écriture des tests unitaires doit se faire en parallèle de celle du modèle et de la prise de décision. Il ne faut donc surtout attendre qu'une classe soit entièrement écrite pour commencer à la tester.

 

2.6°/ conception de la partie vue

Afin de mener à bien la conception et le codage de la partie vue, il est impératif de créer des maquettes précises du visuel du jeu. Cela implique notamment de définir :

  • l'apparence sous forme de textuelle de chaque zone, avec notamment leur taille 2D, les couleurs utilisées, le design,
  • la position 2D de ces zones,
  • l'apparence des autres éléments (pions, murs, ...), et ce pour chacun de leur état possible.

Au minimum, il est demandé de créer un visuel à taille et structuration constante, donc qui respecte les maquettes. Cependant, il est possible de définir le visuel pour plusieurs tailles possibles. Dans ce dernier cas, cela complexifie grandement le codage de la partie vue et n'est donc pas vraiment conseillé. Comme pour les autres parties optionnelles, cela comptera comme un bonus dans l'évaluation. 

 

2.7°/ conception de la partie contrôle général

La classe représentant le contrôle général sera à priori très similaire à celle du tutoriel (cf. HoleController), à part la méthode analyseAndPlay() qui sera spécifique aux règles du jeu et à la syntaxe de saisie des coups choisis.

Pour le mastermind, il faudra en plus tenir compte de la saisie de la combinaison initiale et ne pas utiliser à chaque tour model.setNextPlayer() car cette fonction fait alterner les joueurs, alors qu'il faut faire jouer plusieurs fois le même joueur.