Programmation Orientée Objet avec Java – Coda 1 ère année – 2026 Version synthétique : [[bataille-javale-synthese.pdf]] # Informations pratiques ## Rendu Vous devrez rendre votre projet sous la forme: - d'un **dépôt github** auquel vous me donnerez accès : user = `marc-bouvier` sur GitHub - d'un **artefact Maven déployé** sur le nexus https://nexus.baldir.fr/#browse/browse:coda_lab > [!info] Date de rendu > Vous avez jusqu’au **Samedi 14 Mars 2026 23h59** pour rendre votre projet. > [!danger] Pénalité de retard > > **2 points** seront retirés à votre note **par jour de retard**. > > ![[combien.webp|378x210]] ### Si vous choisissez le déploiement maven Si vous choisissez le déploiement maven, votre artefact maven doit avoir **un `groupId` unique** spécifique à votre binôme pour vous différencier des autres binômes. Vous pouvez le constituer de vos prenoms respectifs : Ex. Pour Sarah et Marc : `school.coda.sarah_marc` Ce qui donnera dans votre `pom.xml` ```xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>school.coda.sarah_marc</groupId> <artifactId>bataille-javale</artifactId> <version>1.0-SNAPSHOT</version> <!-- etc. --> </project> ``` ### Repartition de la note Le projet consiste en - Une interface graphique JavaFx - Des mécaniques de jeu Je m'attends à un programme bien découpé en **plusieurs fichiers** organisés dans des **packages**. Je m'attends à **une séparation suffisante** entre l'**interface graphique**, la **mécanique de jeu** et la **persistance en base de données** (la base de données est optionnelle). Je m'attends à ce que la **duplication de code** soit réduite. > [!success] Repartition de la note > - 50% : fonctionnalités > - 25% : interface graphique > - 25% : qualité de la conception ### Critère d’évaluation > [!info] > Vous serez tout d’abord évalué sur votre capacité à **utiliser correctement les concepts de POO** dans un projet composé de **nombreuses classes**. Prenez le temps de faire les bons **choix de modélisation**. Respectez les bonnes pratiques de programmation orientée objet : - DRY (Don’t Repeat Yourself) - YAGNI (You ain't gonna need it) - Single responsability principle > [!success] Architecture > Vous devez essayer de créer une architecture **flexible** et **évolutive.** Des points vous seront retirés si vous faites de très mauvais choix de conception ou si vous ne respectez pas les pratiques de code recommandées. Le jeu est composé de nombreuses règles indépendantes et il est possible de réaliser beaucoup de taches en parallèle. > [!success] Répartition de votre travail > Un bon développeur sait travailler en équipe, organisez-vous bien avec votre binôme et **découpez astucieusement le travail**. > > ![[adulte-responsable.webp|528x312]] Vous serez également évalués sur votre capacité à réaliser **une interface dynamique**. L’architecture de vos classes doit correspondre aux besoins de l’UI. Vous pouvez développer l’UI **[[7.1 - Introduction à JavaFx|programmatiquement]]** ou en utilisant des fichiers **[[7.2 - FXML|7.2 - FXML]]**. Vous pouvez également utiliser les [[7.3 - Canvas|7.3 - Canvas]] ou encore la bibliothèque [[7.4 - Fxgl|Fxgl]] . Enfin, le projet est composé de nombreuses fonctionnalités, vous devez essayer d’aller au bout des choses et de rendre un projet abouti. > [!danger] ☢️ Ne soyez pas trop gourmand-es > N'essaye pas de faire **trop de fonctionnalités** additionelles > ou des **fonctionnalités trop difficiles** si vous n'avez pas la mécanique de jeu de base en place. > > Dans ce contexte, il vaut mieux peu de fonctionnalités bien faites que beaucoup de fonctionnalités mal faites. > > ![[Étudiant-e qui a choisi de faire trop de fonctionnalités.webp|400x225]] > *Étudiant-e qui a choisi de faire trop de fonctionnalités* > [!warning] > Il n’y a **pas une solution unique** à ce projet et des **architectures très différentes** peuvent être tout à fait **valides**. > > Vous obtiendrez une bonne note si vous **faites preuve de jugement** ### Évaluation du projet ![[IMG_0724.jpg|166x234]] Votre note dépendra des points suivants - Le nombre de fonctionnalités implémentées - Les interactions et le contenu de votre interface graphique - La qualité de votre architecture **50 % de la note** sera au prorata du nombre de fonctionnalités implémentées. > [!success] > - Si vous implémentez **toutes les fonctionnalités** de base du projet **+ 2 fonctionnalités additionnelles**, vous obtiendrez **la moitié des points** > - Si vous implémentez **toutes les fonctionnalités de l’interface graphique** vous obtiendrez **1/4 des points**. > - Votre architecture sera étudié et **1/4 des points** dépendent de **vos choix de conception** Votre architecture doit avoir du sens et **utiliser les concepts de POO** au **bon moment**: [[3.3 - Encapsulation en Java]], [[3.5 - Polymorphismes en Java]], [[3.4 - Héritages en Java]], etc... Vous devez essayer d’avoir un programme **extensible et évolutif**. ![[conception-diagrammes.webp|261]] Une **utilisation trop partielle** ou des **utilisations manquées** des concepts en POO vous feront perdre des points. Une conception **trop rigide, mal pensée ou un programme peu évolutif** influencera **négativement** votre note. Des **points bonus** vous seront accordés si vous implémentez **une fonctionnalité additionnelle** en plus mais aussi en fonction de la **qualité de votre interface** (design travaillé, responsive). > ![[nounou_ouvre_la_porte.mp4]] > Exemple d'une interface utilisateur efficace Vous serez encore et toujours évalué sur la **qualité de votre code** et devrez mettre en place les bonnes pratiques vues lors de votre formation. A savoir : - Des noms de variables, de fonctions et de classes claires - Utiliser la convention `camelCase` et `PascalCase` dans les cas appropriés - Des fonctions pas trop longues (au delà de 50 lignes ça commence à faire beaucoup) - Une indentation correcte - Un code correctement organisé - Mise en forme du code uniforme dans le projet (accolades, saut de ligne, conventions de codage) - Des commentaires si besoin > [!warning] > Des **petits écarts** peuvent être **tolérés**, cependant si aucun effort n’est réalisé ou si certaines pratiques ne sont pas mises en place, > > vous pourrez **perdre jusqu’à 5 points** sur votre note finale **même si votre projet fonctionne parfaitement**. > > ![[david-goodenough.webp|261x170]] ## Fonctionnement de la semaine ![[IMG_0920.webp|461]] ### Je suis votre collègue Considérez moi **comme un collègue** et pas seulement comme un prof. ![[IMG_0963.webp|161x270]] > [!tip] Mes clients me payent cher pour ce type de prestation > Profitez et abusez de m'avoir **gratuitement** à votre disposition Plus vous me demandez d'aide souvent meilleure sera votre note. Car vous aurez mon feed-back au plus tôt. ![[IMG_1137.webp|360x349]] Je vous donnerai pas de solution. Mais je vous donnerai des pistes et directions. Je challengerai vos propositions pour vous aider à améliorer votre conception. ### Revues de code Nous pourrons faire des **revues de code** pour nous assurer ensemble que vous allez dans la bonne direction. ![[revues-de-code.webp|358]] ### Prenez le temps de bien lire les exigences Lisez doucement les exigences, reformulez-les. Ecrivez des exemples. Dessinez des diagrammes. Confirmez avec l'enseignant votre compréhension. > [!tip] Assurez-vous de bien comprendre ce qu'il faut faire > ![[Code bien réalisé mais fonctionnalité mal comprise.webp|261x463]] > Code bien réalisé mais fonctionnalité mal comprise ### Modularité > [!tip] Modularité > > Si vous le désirez, **vous pouvez** coder une partie des mécaniques de jeu sans forcément l'intégrer tout de suite à une interface graghique. > > Cela peut vous permettre de répartir le travail de mécanique de jeu d'un côté et celui de l'interface graphique de l'autre. > > Vous pouvez demander du feed-back à votre collègue enseignant pour vous assurer que vous avez bien compris les règles. ### Code extérieur > [!info] A propos des bibliothèques externes > Vous pouvez utiliser des bibliothèques externes comme **[[7.4 - Fxgl]]**. > > Si vous souhaitez en utiliser d'autres, **confirmez avec l'enseignant** pour qu'il vous autorise ou non leur utilisation # Bataille navale ## Mécaniques de jeu L’objectif du projet est de coder la **mécanique de jeu** et **l’interface graphique** d’un simulateur de **bataille navale en JavaFX**. Vous devrez modéliser les différentes mécaniques de jeu **en suivant les principes** de **programmation orientée objet**. ### Règles générales > But du jeu : > > Être le premier joueur à couler la flotte de cinq vaisseaux de son adversaire. La bataille navale utilise un système de combat au **tour par tour** ou **2 joueurs** s’affrontent en **envoyant des tirs** aux coordonnées de leur adversaire. Chaque joueur possède **une flotte de 5 vaisseaux**. La partie se déroule en **2 phases** : - Placement des vaisseaux - Bataille Pour référence, les règles du jeu de société en version physique. > [!danger] Ces règles ne sont qu'à titre indicatif > Ce sont **les règles énoncées dans la suite de cet énoncé** qui font foi. ![[image-42.webp]] ### Phase de placement En début de partie, les joueurs placent leurs vaisseaux sur une grille de 10 x 10. Cette grille est la **grille océan**. La grille est numérotée horizontalement de 1 à 10 La grille est libellée verticalement de A à J ![[placement_correct.webp|331x311]] #### Vaisseaux - Porte-avions (5 cases) - Cuirassé (4 cases) - Destroyer (3 cases) - Sous-marin (3 cases) - Patrouilleur (2 cases) #### Placement des vaisseaux - Horizontalement - Verticalement Placements incorrects - Les vaisseaux ne peuvent pas être placés en diagonale - Les vaisseaux ne peuvent pas se chevaucher - Les vaisseaux ne doivent pas dépasser la grille océan - On ne peut placer qu'un vaisseau de chaque type par joueur Une fois les vaisseaux placés pour les 2 joueurs, la phase de bataille peut commencer. ### Phase de bataille Lors la bataille les joueurs jouent l'un après l'autre. #### Tour de bataille Au début d'un tour de bataille, chaque joueur choisit les coordonnées vers lesquelles envoyer un tir. Un tour de bataille se termine quand les 2 joueurs ont fait leur action. Ex. Tour 1 : - Joueur 1 tire en A-1 - Joueur 2 tire en E-8 Tour 2 : - Joueur 1 tire en A-2 - Joueur 2 tire en D-4 ### Grille radar Lors de la phase de bataille, les tir envoyés à l'adversaire sont enregistrés sur une grille aux dimensions similaires de la grille océan. C'est la **grille radar**. ![[grille_radar_rate.webp]] #### Raté Si la position annoncée n’est pas occupée par un vaisseau sur la grille océan de l’adversaire, **le tir est raté**. Pour éviter d’annoncer de nouveau cette position, **le joueur attaquant** insère **une torpille blanche** dans le trou correspondant sur **sa grille-radar**. ![[grille_radar_rate-1.webp]] Il n’est pas obligé d’enregistrer les tirs ratés de l’adversaire sur sa propre grille océanique. Exemple : C’est au tour de J1. - J1 annonce : « F-4 ». - J2 réponds : « Manqué. » - J1 place une torpille verte à la position F-4 de sa grille-radar. #### Touché Si la position annoncée est occupée par un vaisseau sur la grille océan de l’adversaire, le tir est réussi : **ce vaisseau est touché**. Le joueur attaquant enregistre sa frappe en insérant **une torpille rouge** dans le trou correspondant sur **sa grille-radar**. L’adversaire enregistre la frappe en insérant **une torpille rouge** dans le trou correspondant de son vaisseau touché sur **sa grille océan**. ![[grille_ocean_touche.webp]] Exemple: C'est au tour de J1. - J1 Annonce : "D-4" - J2 répond : " Touché." - J1 place la torpille rouge à la position D-4 de sa grille radar - De son côté, J2 place une torpille rouge sur D-4 de sa grille océanique. #### Couler Dès que **tous les trous d’un vaisseau** sont occupés par une torpille rouge, **ce vaisseau est coulé**. L’adversaire **révèle la nature du vaisseau coulé** (destroyer, patrouilleur, etc.). Exemple: C'est au tour de J1. J2 a un sous-marin (de taille 3) déjà touché en D-3 et D-4. Il reste donc à le toucher en D-5 pour le couler. - J1 Annonce : "D-5" - J2 répond : " Touché-coulé : sous-marin" - J1 place la torpille rouge à la position D-5 de sa grille radar - De son côté, J2 place une torpille rouge sur D-5 de sa grille océanique. ## "IA" de l'ordinateur Placement - L'IA place les vaisseaux de façon aléatoire en respectant les règles de placement Phase de bataille - L’ordinateur choisit ses attaques aléatoirement en respectant les règles de tir - Il doit tirer à un endroit où il n'a pas déjà tiré ## Extensibilité > [!tip] Extensibilité > Vous devrez **penser le système flexible** afin de pouvoir facilement ajouter de **nouvelles actions possibles** et de **nouvelles règles** sans avoir à répéter trop de code. ## Interface graphique ![[interface-graphique.webp|320x270]] > [!tip] Concevez sur papier ou outils de design > N'hésitez pas à dessiner et concevoir vos interfaces en dehors de l'écosystème java pour vous assurez qu'elles sont cohérentes. > > Je vous invite à consulter votre collègue enseignant pour feed-back de votre conception d'interface. Le projet devra contenir les interfaces graphiques suivantes: - Un menu d’accueil - Une interface de jeu permettant de faire un combat contre l'ordinateur (CPU) - la phase de placement - la phase de bataille - résultat de la partie quand elle est terminée > [!success] Le design est libre. Il faudra que les interfaces possèdent les fonctionnalités demandées. > [!danger] **L'esthétique** de l'interface ne sera pas un critère de la note. > [!tip] Outils > Vous pouvez développer l’UI **[[7.1 - Introduction à JavaFx|programmatiquement]]** ou en utilisant des fichiers **[[7.2 - FXML|7.2 - FXML]]**. Vous pouvez également utiliser les [[7.3 - Canvas|7.3 - Canvas]] ou encore la bibliothèque [[7.4 - Fxgl|Fxgl]] . ### Menu d’accueil Le menu d’accueil est **un écran de présentation** avec **un bouton** permettant de **lancer une nouvelle partie**. Vous devez aussi afficher dans un texte ou dans un écran à part **les crédits** du projet avec le **nom et prénom** des membres du projet ### Démarrer une partie Une nouvelle partie commence par la phase de placement de la flotte. #### Placer ses vaisseaux Avant de démarrer un combat, vous devez afficher **une interface pour placer les 5 vaisseaux**. Vous devez pouvoir placer les 5 vaisseaux en respectant les règles de placement. L’interface doit permettre : - d'afficher la grille océan (mes vaisseaux) - de placer ses vaisseaux - d'empêcher les placements incorrects - de voir ses vaisseaux placés sur la grille océan - de démarrer le combat si la flotte est au complet Il ne vous est pas demandé de faire une interface très élaborée graphiquement. ### Déroulement d’un combat Une fois la phase de placement terminée, l’interface doit permettre d’affronter un autre joueur au tour par tour. L’écran doit afficher les éléments suivants: - la grille océan (mes vaisseaux) - la grille radar (mes tirs) - Le numéro du tour courant - Un historique du combat Dans la version de base du projet, le joueur devra affronter l’ordinateur (CPU). Le placement des vaisseaux du CPU peut être aléatoire. Il doit être possible d’effectuer les actions suivantes sur l’interface - choisir l’attaque au prochain tour ### Historique de la bataille L’historique des combats doit afficher les choses suivantes : - Le numéro du tour courant - Quand un vaisseau adverse est coulé et son nom L’affichage du combat doit se mettre à jour à la fin de chaque action. ## Écran de fin de partie Quand le dernier vaisseau d'un des joueurs est coulé. - afficher le joueur victorieux Actions - Retourner au menu principal ## Fonctionnalités additionnelles ![[IMG_2267.webp|160x160]] --- > [!warning] Avant d'envisager les fonctionnalités additionnelles > Assurez-vous que vous avez implémenté le moteur de jeu et l'interface graphique du jeu de base. > > ![[Étudiant-e qui a choisi de faire trop de fonctionnalités.webp|400x225]] > *Étudiant-e qui a choisi de faire trop de fonctionnalités* > [!tip] Cela dit... > Il peut être utile de lire en quoi consistent certaines fonctionnalités additionnelles car cela peut vous permettre d'identifier des similiarités et des points d'extension sur le jeu de base. Il vous est demandé d’implémenter **au moins 2 fonctionnalités** de la liste suivante. Si vous implémentez une **3ème fonctionnalité** et/ou des **fonctionnalités plus difficiles**, des **points supplémentaires** vous seront accordés - [[#Multijoueur via base de données - 🏆🏆]] - [[#Interface supplémentaire en ligne de commandes (TUI) - 🏆🏆]] - [[#Mode salve]] - [[#Ravitaillement - 🏆]] - [[#Taille de carte personnalisable]] - [[#Système de récompenses (achievements)]] - [[#Événements aléatoires - 🏆]] - [[#Musique et effets sonores]] - [[#Personnalisation des préférences - 🏆]] **Légende :** - 🏆 : **Fonctionnalités difficiles**, non triviales. Peut vous faire gagner un **bonus de points**. - 🏆🏆 : **Fonctionnalités très difficiles**, nécessitent beaucoup d'efforts et de travail. Peut vous faire gagner un **bonus de points conséquent**. - ‼️ A ne considérer si vous avez réussi à terminer les mécaniques de jeu de base et l'interface graphique rapidement. ### Matrice de compatibilité des modes Ce tableau indique les compatibilités et synergies possibles entre certaines fonctionnalités additionnelles **Légende** : - ✅ **Compatibles** : les modes peuvent être **utilisés en même temps** - ❌ **Non compatibles** : les modes ne peuvent pas être **utilisés en même temps** - 🤝 **Complémentaires** : les modes débloquent des **fonctionnalités supplémentaires** ``` Ex. Evénements aléatoires + Récompenses : Evénement "Une journée ensoleillée" déclenche une récompense Ex. Multijoueur via base de données + Récompenses : possibilité de stocker les récompenses en base de données ``` | | Multi-joueur 🏆🏆 | TUI-🏆🏆 | Salve | Ravit-aille-ment 🏆 | Taille de carte custom | Récom-penses | Événe-ments aléa-toires 🏆 | Musi-que et sons | Préfé-rences 🏆 | | ---------------------- | ----------------- | -------- | ----- | ------------------- | ---------------------- | ------------ | -------------------------- | ---------------- | --------------- | | Multijoueur-🏆🏆 | | | | | | | | | | | TUI-🏆🏆 | ✅ | | | | | | | | | | Salve | ✅ | ✅ | | | | | | | | | Ravitaillement-🏆 | ✅ | ✅ | ❌ | | | | | | | | Taille de carte custom | ✅ | ✅ | ✅ | ✅ | | | | | | | Récompenses | ✅🤝 | ✅🤝 | ✅🤝 | ✅ | ✅ | | | | | | Événements-🏆 | ✅ | ✅ | ✅🤝 | ✅ | ✅ | ✅🤝 | | | | | Musique et sons | ✅ | ❌ | ✅ | ✅🤝 | ✅ | ✅🤝 | ✅🤝 | | | | Préférences-🏆 | ✅🤝 | ✅ | ✅ | ✅🤝 | ✅🤝 | ✅🤝 | ✅🤝 | ✅🤝 | | ### Multijoueur via base de données - 🏆🏆 > [!danger] 🏆🏆 : fonctionnalité très difficile > Cette fonctionnalité nécessitent beaucoup d'efforts et de travail. > > ‼️ A ne considérer si vous avez réussi à terminer les mécaniques de jeu de base et l'interface graphique rapidement. > > Peut vous faire gagner un **bonus de points conséquent**. Stocker l'état des parties en cours en base de données. > [!warning] Serveur de base de données > Vous devez utiliser une base de données **en mode serveur**. > Cela **ne fonctionnera pas avec SQLite** > > Quelques exemples de bases de données en serveur: > - PostgreSql > - MySql > - Mariadb #### Premier lancement et Nom d'utilisateur Au lancement du programme, le jeu récupère le nom d'utilsateur associé à la session de votre système d'exploitation. > [!tip] Nom d'utilisateur > Vous pouvez l'obtenir via [une propriété du système](https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/System.html#getProperties()) Lors du premier lancement de votre programme, votre profil utilisateur sera créé en base de données. Il servira - à différencier les joueurs humains dans les parties - à sauvegarder les récompenses si vous avez choisi d'implémenter le [[#Système de récompenses (achievements)]] - à sauvegarder vos préférences individuelles si vous avez choisi d'implémenter la [[#Personnalisation des préférences - 🏆]] #### Nouveaux menus Le menu principal sera agrémenté de nouveaux choix : - Configurer la base de données - Héberger une partie multijoueur - Rejoindre une partie - Sortir d'une partie en cours - Reprendre une partie en cours Utilisez la base de données comme un mécanisme pour persister l'état d'une partie en cours. Cela devrait vous permettre de lancer L'application sur 2 ordinateurs différents en les connectant à la même base de données. ##### Configurer la base de données Ce menu vous permet de configurer la chaine de connexion JDBC de votre base de données. Cette information est stockée dans un fichier dans votre dossier utilisateur > [!tip] Dossier utilisateur > Vous pouvez l'obtenir via [une propriété du système](https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/System.html#getProperties()) Lorsque vous changez de base de données, un nouveau profil utilisateur est créé dans cette base de données s'il n'existait pas déjà. ##### Héberger une partie multijoueur Lorsque ce choix est fait, vous pouvez **créer une nouvelle partie**. Un **code aléatoire unique de 6 caractères** est généré et peut être communiqué à un autre joueur pour rejoindre la partie. > [!tip] ✅🤝 Synergies > Si vous avez des modes complémentaires implémentés, vous pouvez **les activer/désactiver** > > Les modes complémentaires sont désactivés par défaut Quand l'autre joueur a rejoint la partie, vous pouvez la démarrer. ##### Rejoindre une partie Vous pouvez rejoindre une partie comme 2ème joueur en saisissant le **code aléatoire unique** fourni par le joueur qui héberge une partie. ##### Sortir de la partie en cours En cours de partie, vous pouvez sortir de celle-ci. ##### Reprendre une partie commencée En vous rendant dans ce menu, vous pouvez consulter la liste de vos parties non terminées. Pour chaque partie, vous pouvez la reprendre. ### Interface supplémentaire en ligne de commandes (TUI) - 🏆🏆 **En plus de l'interface graphique**, développer une interface textuelle pour jouer dans un terminal en mode ligne de commandes. > [!danger] 🏆🏆 : fonctionnalité très difficile > Cette fonctionnalité nécessitent beaucoup d'efforts et de travail. > > ‼️ A ne considérer si vous avez réussi à terminer les mécaniques de jeu de base et l'interface graphique rapidement. > > Peut vous faire gagner un **bonus de points conséquent**. > [!success] Conséquences sur votre conception > Si vous développez cette fonctionnalité, votre conception devrait bénéficier des propriétés suivantes > - Un meilleur découpage de votre architecture : Elle va vous obliger à séparer la logique de jeu de celle d'affichage / interfaction utilisateur > - Elle va demander d'implémenter les interactions en mode texte (menus, paramètres, saisie des actions, ...) **en plus du mode graphique** > [!tip] ✅🤝 Synergies > Si vous avec choisi de développer la fonctionnalité [[#Multijoueur via base de données - 🏆🏆]], > votre client en ligne de commande doit vous permettre de jouer aussi bien > contre > - **un adversaire dans un autre terminal** > - **un adversaire** > **utilisant votre interface graphique JavaFX**. ### Mode salve > [!danger] ❌ Modes incompatibles > Le mode ravitaillement ne peut pas être activé en même temps que le mode salve Les joueurs expérimentés apprécieront cette variante du jeu dans laquelle, à leur tour, ils tirent un nombre de missiles correspondant au nombre de vaisseaux actifs de leur flotte. Les règles suivantes s’ajoutent à celles du jeu de base : - Chaque joueur commence avec une salve de cinq tirs (un par vaisseau de sa flotte). Après chaque tir, l’adversaire signale si le tir a touché ou raté une cible. Les tirs sont marqués avec des torpilles comme pour une partie régulière. - Chaque fois qu’un de ses vaisseaux coule, le joueur déduit un tir de sa prochaine salve. Les joueurs continuent ainsi de lancer des salves jusqu’à ce qu’il y ait un gagnant. Un tour de jeu correspond desormais à - les tirs de salve successifs du premier joueur - les tirs de salve successifs du second joueur **Pensez votre architecture flexible qui permet d’ajouter et d’activer facilement de nouvelles règles de jeu.** ### Ravitaillement - 🏆 > [!warning] 🏆 : Fonctionnalité difficile > Cette fonctionnalité est non-triviale. > > ‼️ A considérer si vous vous sentez à l'aise et que vous avez terminé assez rapidement les fonctionnalités de base. > > Peut vous faire gagner un **bonus de points**. > [!danger] ❌ Modes incompatibles > Le mode ravitaillement ne peut pas être activé en même temps que le mode salve Lors de son tour de jeu, un joueur peut choisir de passer 2 tours sans tirer pour obtenir une nouvelle capacité spéciale au hasard (voir "drop rate") parmi les suivantes : > 📋 Développer au moins 4 types de ravitaillement parmi ceux proposés | Ravitaillement | Probabilité | Munitions | | ------------------------- | ----------- | --------- | | Torpille à fragmentation | 50 | 2 | | Tir éclairant | 50 | 2 | | Tir d'interception | 40 | 2 | | Raid aérien | 15 | 1 | | Bombe banane | 10 | 1 | | Ravitaillement intercepté | 5 | `_` | | Carapace bleue`*` | `*` | 1 | `*` : Voir conditions dans la section sur la carapace bleuue$ ... (à vous d'en inventer si vous le souhaitez) Les capacités additionnelles peuvent nécessiter des munitions et être sujettes à **un temps de cooldown**. **Cooldown** : Le temps minimum que le joueur doit attendre après avoir utilisé **une capacité spécifique** avant de pouvoir **l'utiliser à nouveau**. **Cooldown global** : le cooldown s'applique à **toutes les capacités**. #### Drop rate Chaque capacité à une probabilité plus ou moins forte d'être celle présente dans le ravitaillement. Ex. 1 - Torpille à fragmentation : 50 - Tir fumigène : 50 - Tir d'interception : 40 Total : 140 Probabilités de drop sont calculées en fonction des différents ravitaillements possibles : - Torpille à fragmentation : `50 / 140 = 35.7 %` - Tir fumigène : `50 / 140 = 35.7 %` - Tir d'interception : `40 / 140 = 28.6 %` --- Ex. 2 - Torpille à fragmentation : 70 - Tir fumigène : 70 - Tir d'interception : 50 - Ravitaillement intercepté : 5 Total : 195 Probabilités de drop sont calculées en fonction des différents ravitaillements possibles : - Torpille à fragmentation : `70 / 195 = 35,9 %` - Tir fumigène : `70 / 195 = 35,9 %` - Tir d'interception : `50 / 195 = 25,6 %` - Ravitaillement intercepté : `5 / 195 = 2,6 %` #### Torpille à fragmentation Une **attaque de zone** qui touche **une case** ainsi que ses **cases adjacentes horizontalement et verticalement**. Après l'utilisation de la torpille à fragmentation, on ne peut pas attaquer (tous types d'attaques) **pendant 2 tours** (**cooldown global**). Exemple. - avec un cuirassé qui occupe verticalement les cases B-3 -> E-3 - avec un patrouilleur qui occupe horizontalement les cases D-1 -> D-2 Grille océan de l'adversaire ```text 1 2 3 4 5 A ~ ~ ~ ~ ~ B ~ ~ O ~ ~ C ~ ~ O ~ ~ D O O O ~ ~ E ~ ~ 0 ~ ~ ``` Tirer la torpille à fragmentation en D-3 provoquera les effets suivants: - Patrouilleur touché - Cuirassé touché Grille radar de l'attaquant ```text 1 2 3 4 5 A ~ ~ ~ ~ ~ B ~ ~ ~ ~ ~ C ~ ~ X ~ ~ D ~ X X M ~ E ~ ~ X ~ ~ ``` Grille océan de l'adversaire ```text 1 2 3 4 5 A ~ ~ ~ ~ ~ B ~ ~ O ~ ~ C ~ ~ X ~ ~ D O X X M ~ E ~ ~ X ~ ~ ``` #### Tir éclairant La recherche débloque 2 munitions de fumigène. Consomme 1 munition de fumigène pour lancer un tir qui révèle les entités présentes sur la grille radar dans une zone carrée de 3 x 3. Il faut attendre 3 tours (cooldown) avant de pouvoir lancer de nouveau un fumigène. Lancer un fumigène n'empêche pas de faire un tir d'un autre type au tour suivant. En contrepartie, il y a 50 % de chances que l'origine du tir soit révélée à l'adversaire. Quand la recherche est débloquée, 2 tirs fumigènes sont disponibles. Lancer un tir fumigène consomme 1 munition de fumigène. Quand 0 munitions de fumigène sont disponible, le tir fumigène ne peut plus être lancé. #### Tir d'interception Le ravitaillement débloque 2 munitions de tir d'interception. Consomme 1 munition de tir d'interception pour lancer un tir de défense qui empêche le prochain tir adverse d'atteindre sa cible. Le tir est simplement annulé. #### Raid aérien Le ravitaillement permet d'obtenir 1 munition de raid aérien. Même après son obtention, le tir de raid aérien ne peut pas être utilisé avant le tour 10. Un tir de raid aérien permet de lancer rangée de bombes sur 5 cases horizontalement ou verticalement. #### Bombe banane Le ravitaillement permet d'obtenir 1 munition de bombe banane. Même après son obtention, le tir de raid aérien ne peut pas être utilisé avant le tour 5. Un tir de bombe banane permet de lancer une bombe qui touche la case visée et 3 autres cases aléatoirement dans une zone de 4 x 4 autour de l'explosion initiale. #### Ravitaillement intercepté Pas de chance ! le ravitaillement est intercepté par l'adversaire. Votre adversaire reçoit un ravitaillement à votre place (hors "Ravitaillement intercepté"). #### Carapace bleue Le ravitaillement permet d'obtenir 1 munition de carapace bleue. La carapace bleue doit être utilisée immédiatement. La carapace bleue fonctionne de la même façon que la torpille à fragmentation à l'exception des caractéristiques suivantes : - Pas de cooldown (0) : au tour qui suit un lancer de carapace bleue - La carapace est à tête chercheuse : elle touche automatiquement un vaisseau adverse à une coordonnée où il n'a pas été touché Seul le joueur ayant **le plus de retard** dans le jeu peut obtenir ce ravitaillement. C'est à dire qu'il doit avoir plus de tirs reçus qui ont touché ses vaisseaux que son adversaire. La probabilité de survenue de la carapace bleue est le nombre de tirs reçus qui ont touché des vaisseaux. Ex. Grille océan joueur 1 (4 tirs reçus ayant touché) ```text 1 2 3 4 5 A ~ ~ ~ ~ ~ B ~ ~ O ~ ~ C ~ ~ X ~ ~ D X O X ~ ~ E ~ ~ X ~ ~ ``` Taux de drop de carapace bleue pour le joueur 1 : `4` Grille océan joueur 2 (2 tirs reçus ayant touché) ```text 1 2 3 4 5 A X X ~ ~ ~ B ~ ~ ~ ~ O C ~ ~ ~ ~ O D ~ ~ ~ ~ O E ~ ~ ~ ~ O ``` Taux de drop de carapace bleue pour le joueur 2 : `0` ### Taille de carte personnalisable Au démarrage d'une partie, vous pouvez choisir le nombre de cases de la grille - En largeur - En hauteur > [!important] Taille de carte minimale > Les 5 vaisseaux doivent pouvoir être placés. > > La taille minimale possible est de `5x4` (ou `4x5`) Taille de carte maximale - `26x26` L'affichage des grilles devra être **responsive**. ### Système de récompenses (achievements) Permettre de rajouter du piquant au jeu en tentant des performances de jeu. > 📋 Développer au moins 4 récompenses parmi celles proposés Récompenses disponibles selon les autres fonctionnalités additionnelles disponibles. La fonctionnalité "Core" correspond au jeu de base. | Fonctionnalité présente | Récompense | | ----------------------- | ---------------------------------------------- | | Core | Gagner une partie | | Core | Gagner une partie en moins de 36 tours | | Core | Avoir joué 10 parties | | Core | Avoir joué 50 parties | | Core | Avoir joué 100 parties | | Core | Konami code | | Evénements aléatoires | Une journée ensoleillée | | Mode salve | Gagner une partie en mode salve | | TUI | Terminer une partie avec l'interface textuelle | Vous pouvez ajouter d'autres récompenses si vous le souhaitez. #### Notification Lorsqu'un achievement est déclenché, une notification apparait quelques secondes. > [!tip] ✅🤝 Synergie > Si vous avez choisi la fonctionnalité **[[#Musique et effets sonores]]**, > la notification est accompagnée d'un effet sonore. #### Persistance L'avancée des récompenses du joueur est stockée **dans un fichie**r dans votre **dossier utilisateur**. > [!tip] Dossier utilisateur > Vous pouvez l'obtenir via [une propriété du système](https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/System.html#getProperties()) > [!tip] ✅🤝 Synergie > Si vous avez choisi la fonctionnalité [[#Multijoueur via base de données - 🏆🏆]]. > Vous pouvez stocker l'avancée des récompenses **par utilisateur** en base de données. #### Tableau des récompenses Un écran permet de voir les récompenses déjà obtenues. On peut voir les récompenses pas encore obtenues en grisé. #### Gagner une partie La récompense est obtenue lorsque le joueur gagne une partie pour la première fois. #### Gagner une partie en moins de 36 tours La récompense est obtenue lorsque le joueur gagne une partie en moins de 36 tours. #### Gagner 10 parties La récompense est obtenue lorsque le joueur gagne sa 10ème partie. #### Gagner 50 parties La récompense est obtenue lorsque le joueur gagne sa 50ème partie. #### Gagner 100 parties La récompense est obtenue lorsque le joueur gagne sa 100ème partie. #### Konami code La récompense est obtenue quand le joueur déclenche [la combinaison de touches du code Konami](https://fr.wikipedia.org/wiki/Code_Konami) pour la première fois. #### Une journée ensoleillée > [!tip] ✅🤝 Synergie > Vous pouvez implémenter cette récompense si vous avez **développé** et **activé** le mode [[#Événements aléatoires - 🏆]]. La récompense est obtenue quand l'événement **"Une journée ensoleillée"** survient pour la première fois. #### Gagner une partie (Mode salve) > [!tip] ✅🤝 Synergie > Vous pouvez implémenter cette fonctionnalité si vous avez **implémenté** et **activé** le [[#Mode salve]]. La récompense est obtenue lorsque le joueur **gagne une partie en mode salve** pour la **première fois**. ### Événements aléatoires - 🏆 > [!warning] 🏆 : Fonctionnalité difficile > Cette fonctionnalité est non-triviale. > > ‼️ A considérer si vous vous sentez à l'aise et que vous avez terminé assez rapidement les fonctionnalités de base. > > Peut vous faire gagner un **bonus de points**. Mécanique : A la fin d'un tour de bataille, un événement aléatoire survient. > 📋 Développer au moins 4 types d'événements aléatoires parmi ceux proposés Les événements affectent les 2 joueurs. Événements disponibles selon les autres fonctionnalités additionnelles disponibles. La fonctionnalité "Core" correspond au jeu de base. | Fonctionnalité présente | Evénément | Probabilité | | ----------------------- | ----------------------------- | ----------- | | Core | Rien ne se passe | 80 | | Core | Brouillage radar | 20 | | Core | Apocalypse | `*` | | Core | Pluie de météores | 5 / `**` | | Ravitaillement | Capacités bloquées | 10 | | Ravitaillement | Ravitaillement gratuit | 5 | | Système de récompenses | Juste une journée ensoleillée | | | Mode salve | Salve boostée | 10 | `*` se déclenche automatiquement au tour 30. `**` Probabilité de 5. A lieu 100% du temps à chaque tour au-delà du tour 30. > [!tip] ✅🤝 Synergie > Vous pouvez implémenter cette fonctionnalité si vous avez **implémenté** et **activé** le [[#Musique et effets sonores]]. #### Probabilité de survenue des événements Chaque capacité à une probabilité plus ou moins forte d'être celle présente dans le ravitaillement. Ex. 1 - Rien ne se passe : 80 - Brouillage radar : 20 - Pluie de météores : 5 Total : 105 Probabilités de survenue d'événement sont calculées en fonction des différents événements possibles : - Rien ne se passe : 80 / 105 = 76,0 % - Brouillage radar : 20 / 105 = 19,0 % - Pluie de météores : 5 / 105 = 5,0 % --- Ex. 2 - Torpille à fragmentation : 70 - Tir fumigène : 70 - Tir d'interception : 50 - Ravitaillement intercepté : 5 Total : 195 Probabilités de drop sont calculées en fonction des différents ravitaillements possibles : - Torpille à fragmentation : 70 / 195 = 35,9 % - Tir fumigène : 70 / 195 = 35,9 % - Tir d'interception : 50 / 195 = 25,6 % - Ravitaillement intercepté : 5 / 195 = 2,6 % #### Rien ne se passe C'est l'événement qui a lieu le plus souvent. Il ne se passe rien. #### Brouillage radar La grille radar et l'historique ne sont pas disponibles pendant 2 tours. C'est-à-dire qu'on ne peut pas voir les tirs qu'on a faits. Il faudra faire appel à sa mémoire. #### Pluie de météores Une pluie de météorite s'abat sur les 2 joueurs. 2 météorites tombent sur une case aléatoire de la grille océan de chaque joueur. Quand un météore tombe sur un vaisseau, l'adversaire n'en sera pas informé sur sa grille radar Ex. Grille océan du joueur 1 - 1 météore tombe aléatoirement en C-2 : à l'eau - 1 météore tombe aléatoirement en E-5 : touché ```text 1 2 3 4 5 1 2 3 4 5 A O O ~ ~ ~ A O O ~ ~ ~ B ~ ~ ~ ~ O B ~ ~ ~ ~ O C ~ ~ ~ ~ O --> C ~ M ~ ~ O D ~ ~ ~ ~ O D ~ ~ ~ ~ O E ~ ~ ~ ~ O E ~ ~ ~ ~ X ``` Grille radar du joueur 2 (il ne voit pas où les météores ont touché le joueur 1) ```text 1 2 3 4 5 1 2 3 4 5 A ~ ~ ~ ~ ~ A ~ ~ ~ ~ ~ B ~ ~ ~ ~ ~ B ~ ~ ~ ~ ~ C ~ ~ ~ ~ ~ --> C ~ ~ ~ ~ ~ D ~ ~ ~ ~ ~ D ~ ~ ~ ~ ~ E ~ ~ ~ ~ ~ E ~ ~ ~ ~ ~ ``` #### Apocalypse Si la partie n'est pas encore terminée au bout de 30 tours, l'apocalypse se déclenche. Au début de chaque prochain tour, l'événement "Pluie de météores" a lieu 100% du temps. Les autres événements que "Pluie de météore" **ne peuvent plus avoir lieu**. #### Ravitaillement gratuit (Ravitaillement) > [!tip] ✅🤝 Synergie > Vous pouvez implémenter cette fonctionnalité si vous avez **implémenté** et **activé** le [[#Ravitaillement - 🏆]]. Chaque joueur dispose d'un ravitaillement gratuit immédiat. #### Capacités bloquées (Ravitaillement) > [!tip] ✅🤝 Synergie > Vous pouvez implémenter cette fonctionnalité si vous avez **implémenté** et **activé** le [[#Ravitaillement - 🏆]]. Pendant 2 tours, seuls les tirs standard (jeu de base) sont possibles. Les autres capacités spéciales sont bloquées. #### Juste une journée ensoleillée > [!tip] ✅🤝 Synergie > Vous pouvez implémenter cette fonctionnalité si vous avez **implémenté** et **activé** le [[#Système de récompenses (achievements)]]. Les joueurs obtiennent la récompense "Une journée ensoleillée". #### Salve boostée (Mode salve) > [!tip] ✅🤝 Synergie > Vous pouvez implémenter cette fonctionnalité si vous avez **implémenté** et **activé** le [[#Mode salve]]. La **prochaine salve** correspond au **nombre de vaisseaux initial** (quel que soit le nombre de vaisseaux coulés). ### Musique et effets sonores Ajouter une musique de fond et des effets sonores. - Lorsqu'un tir est lancé - Lorsqu'un tir rate (tombe à l'eau) - Lorsqu'un tir touche un vaisseau - Lorsqu'un tir coule un vaisseau - Lorsqu'un tir coule le dernier vaisseau de la flotte de l'adversaire. > [!tip] ✅🤝 Synergies : Effets applicables en présence d'autres modules > Vous pouvez implémenter ces effets sonores / musiques > > - [[#Événements aléatoires - 🏆|Événement aléatoire]], un son est joué lors de l'événement selon le type d'événement > - [[#Apocalypse]] : en plus de jouer un son, la musique change jusqu'à la fin de la partie > - [[#Ravitaillement - 🏆]] : un son est joué selon lors du ravitaillement > - Chaque nouvelle action est associée à un effet sonore distinct > - [[#Système de récompenses (achievements)]] : Un effet sonore est joué lorsqu'une récompense est débloquée ### Personnalisation des préférences - 🏆 > [!warning] 🏆 : Fonctionnalité difficile > Cette fonctionnalité est non-triviale. > > ‼️ A considérer si vous vous sentez à l'aise et que vous avez terminé assez rapidement les fonctionnalités de base. > > Peut vous faire gagner un **bonus de points**. - Options au lancement d'une partie - Options Générales #### Persistance Cette information est stockée dans un fichier dans votre dossier utilisateur > [!tip] Dossier utilisateur > Vous pouvez l'obtenir via [une propriété du système](https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/System.html#getProperties()) > [!tip] ✅🤝 Synergie > Si vous avez implémenté [[#Multijoueur via base de données - 🏆🏆]], > vous pouvez stocker la personnalisation des options dans la base de données. #### Au démarrage d'une partie Au démarrage d'une nouvelle partie, ajouter la possibilité d'en configurer les paramètres. - Types de vaisseaux disponibles - Taille de la grille #### Options générales Accessibles depuis le menu principal - Modules actifs - Musique et effets sonores - Ravitaillement - Evénements aléatoires - Système de récompenses ##### Core - Enregistrement automatique des tirs ratés dans la grille océan ##### Module multijoueur en réseau via base de données - Chaine de connexion de la base de données ##### Module musique et effets sonores - Volume général - Volume des effets - Volume de la musique ##### Module ravitaillement - Types de ravitaillement activés - Probabilité pour chaque type de ravitaillement ##### Module événements aléatoires - Types d'événements activés - Probabilité pour chaque type d'événement - Apocalypse : nombre de tours seuil de déclenchement de l'apocalypse ##### Module système de récompenses - Rémise à zéro des récompenses ##### Taille de carte custom par défaut - Pouvoir déterminer une taille de carte par défaut