Exercices S3 - FC
Sujet de Projet : Combat des Créatures
Objectif : Implémenter un mini-jeu où des créatures s’affrontent en utilisant les concepts de programmation orientée objet (POO) en PHP.
Contexte
Dans ce jeu, chaque créature a des caractéristiques (force, santé, défense) et des compétences spécifiques.
Votre mission est d’écrire les classes nécessaires pour permettre :
La création de différents types de créatures.
L’attaque entre les créatures.
Un fichier de test (jeu1.php) vous est fourni pour valider votre implémentation.
Première partie
Étape 1 : Classe Creature
CreatureCréez une classe Creature représentant une créature générique. Cette classe doit :
Être abstraite.
Avoir les attributs :
nom(chaîne de caractères) : Le nom de la créature.sante(entier) : Les points de santé de la créature.force(entier) : La puissance des attaques de la créature.defense(entier) : La capacité de la créature à réduire les dégâts reçus.
Avoir les méthodes :
attaquer(Creature $adversaire): Inflige des dégâts à l'adversaire. Les dégâts sont calculés commeforce - défense(minimum 0).recevoirDegats(int $degats): Réduit les points de santé en fonction des dégâts reçus.estEnVie(): Retournetruesi les points de santé sont supérieurs à 0, sinonfalse.crier()(abstraite) : Retourne une phrase propre à chaque créature.
Étape 2 : Créatures Spécifiques
Créez les classes suivantes qui héritent de Creature :
Guerrier
Santé : 150.
Force : 20.
Défense : 10.
Cri : "Pour la gloire !"
Mage
Santé : 100.
Force : 30.
Défense : 5.
Modifiez la méthode
attaquerpour infliger des dégâts supplémentaires (+10).Cri : "Abracadabra !"
Archer
Santé : 120.
Force : 15.
Défense : 8.
Ajoutez une capacité d’esquive (30 % de chances de ne pas recevoir de dégâts).
Cri : "Prêt à viser !"
Etape 3 : Création de l'Arène
L'Arène est une classe qui contient une méthode lancerCombat, qui va prendre deux créatures (quelque soit leur type) et déclencher un combat
lancerCombat(Creature $c1, Creature $c2)
La créature c1, si elle est en vie, commence le combat, puis c2, si elle est en vie continue le combat. Le combat s'arrête lorsque l'une des deux créatures n'est plus en vie.
Le fichier de test
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<?php
spl_autoload_register(function ($class_name) {
require $class_name . '.php';
});
echo "<h2>=== Création des Créatures ===</h2>";
$guerrier = new Guerrier("Thor");
$mage = new Mage("Merlin");
$archer = new Archer("Robin");
echo $guerrier->crier() . "\n";
echo $mage->crier() . "\n";
echo $archer->crier() . "\n";
echo "<h2>=== Premier Combat ===</h2>";
$arene = new Arene();
$arene->lancerCombat($guerrier, $mage);
echo "<h2>=== Deuxième combat ===</h2>";
$guerrier2 = new Guerrier("Gimli");
$arene2 = new Arene();
$arene2->lancerCombat($guerrier2, $archer);
?>
</body>
</html>Quelques explications sur l'Autoloader
Vous constaterez que nous n'avons pas de "require" pour chacune des classes dans le fichier seanceIJ.php, pour autant vos classes seront accessibles. On utilise le mécanisme d'autoload de PHP qui permet d'éviter d'avoir des requires quand on utilise la POO. Cela s'avère très pratique quand nous avons beaucoup de classes à gérer.
spl_autoload_register(function ($class_name) {
require $class_name . '.php';
});Le code ci-dessus assure le lien avec tous les fichiers nécessaires. En fait, à chaque fois que vous aller utiliser une classe (new Classe ou Classe::...), PHP, va essayer de trouver un fichier qui se nomme Classe.php et automatiquement en faire un require pour l'intégrer.
Contrainte de cette solution, vous devez avoir un fichier par classe, et votre fichier doit se nommer exactement comme votre classe. Mais nous avons vu en cours, que cette contrainte est en fait une bonne pratique.
Deuxième partie
Dans cette deuxième partie nous allons gérer un plateau permettant de positionner les Créatures et de déterminer lesquelles doivent s'affronter.
Étape 1 : Classe Coordonnee
CoordonneeCréez une classe Coordonnee pour représenter les positions des créatures sur le plateau.
Attributs :
x(entier) : La position horizontale (colonne).y(entier) : La position verticale (ligne).
Méthodes :
getX()etgetY(): Retourne la valeur dexouy.setX(int $x)etsetY(int $y): Définit une nouvelle valeur pourxouy.estAdjacente(Coordonnee $autre): Vérifie si la position actuelle est adjacente à une autre coordonnée (cases voisines).__toString(): Retourne les coordonnées sous forme de chaîne, par exemple(2, 3).
Étape 2 : Classe Plateau
PlateauCréez une classe Plateau pour gérer la disposition des créatures sur une grille.
Attributs :
largeur(entier) : Le nombre de colonnes.hauteur(entier) : Le nombre de lignes.cases(tableau bidimensionnel) : Contient les créatures positionnées sur le plateau ounullsi la case est vide.
Méthodes :
__construct(int $largeur, int $hauteur): Initialise le plateau vide.placerCreature(Creature $creature, Coordonnee $position): Place une créature à une position donnéedeplacerCreature(Creature $creature, Coordonnee $nouvellePosition): Déplace une créature d'une position à une autre.estCaseLibre(Coordonnee $position): Retournetruesi la case est libre, sinonfalse.getCase(Coordonnee $position): retourne la Creature qui est sur la case correspondante.
Étape 3 : Intégration dans la Classe Creature
CreatureAjoutez un attribut position (instance de Coordonnee) dans la classe Creature.
Méthodes :
setPosition(Coordonnee $position): Définit la position de la créature.getPosition(): Retourne la position actuelle de la créature.
Étape 4 : Classe Affichage (Fourni)
Affichage (Fourni)Une classe Affichage vous est donnée pour représenter visuellement le plateau.
<?php
abstract class Affichage {
public static function afficherPlateau(Plateau $plateau): void {
echo "<style>
table { border-collapse: collapse; }
td { width: 50px; height: 50px; text-align: center; border: 1px solid #000; }
</style>";
echo "<table>";
for ($y = 0; $y < $plateau->getHauteur(); $y++) {
echo "<tr>";
for ($x = 0; $x < $plateau->getLargeur(); $x++) {
$creature = $plateau->getCase(new Coordonnee($x, $y));
echo "<td>";
if ($creature) {
echo $creature->getNom();
} else {
echo " ";
}
echo "</td>";
}
echo "</tr>";
}
echo "</table>";
}
}Le fichier de test
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<?php
spl_autoload_register(function ($class_name) {
require $class_name . '.php';
});
echo "<h2>=== Création des Créatures ===</h2>";
$guerrier = new Guerrier("Thor");
$mage = new Mage("Merlin");
$archer = new Archer("Robin");
echo $guerrier->crier() . "\n";
echo $mage->crier() . "\n";
echo $archer->crier() . "\n";
echo "<h2>=== Placement sur le plateau ===</h2>";
$plateau = new Plateau(5, 5);
$plateau->placerCreature($guerrier, new Coordonnee(1, 1));
$plateau->placerCreature($mage, new Coordonnee(3, 1));
Affichage::afficherPlateau($plateau);
echo "<h2>=== Déplacement du guérrier sur le plateau ===</h2>";
$plateau->deplacerCreature($guerrier, new Coordonnee(2, 1));
Affichage::afficherPlateau($plateau);
echo "<h2>=== Premier Combat ===</h2>";
$arene = new Arene();
$arene->lancerCombat($guerrier, $mage);
Affichage::afficherPlateau($plateau);
//echo "<h2>=== Deuxième combat ===</h2>";
//$guerrier2 = new Guerrier("Gimli");
//$arene2 = new Arene();
//$arene2->lancerCombat($guerrier2, $archer);
?>
</body>
</html>
Etape 4 : Mise à jour du plateau
Modifier votre code pour que le perdant du combat disparaisse du plateau
Troisième partie
Actuellement, le combat est déclenché manuelle, et les créatures sont placées par le code.
On va adapter le code afin que les créatures se déplacent aléatoirement.Si deux créatures sont sur des cases adjacentes alors le combat se lance.
Modifier les fichiers nécessaires et dupliquer le fichier seance8.php pour en faire un fichier seance9.php avec ces règles.
Imaginez les méthodes à ajouter, a priori, dans la classe Plateau.
Afficher le plateau entre chaque calcul de déplacement.
Mis à jour