Dans cette série d'exercices sur la programmation orientée objet, vous allez concevoir les bases d'un jeu de type RPG (role playing game) en créant une classe pour les armes du jeu ainsi que pour les personnages.
Pour cette série d'exercices, vous êtes invités à télécharger des fichiers qui formeront la base de votre code.
Télécharger les fichiers de l'exercice.
Une fois les fichiers téléchargés, vous pouvez les placer dans votre espace de stockage sous le répertoire exercices/rpg.
Commençons par modéliser les armes du jeu. Dans le jeu que vous développez, chaque arme a un nom, un niveau d'attaques et une durabilité :
"Épée en fer", "Pioche en argent" ou "Arc". Le nom de l'arme ne change pas au cours du temps.0.
La durabilité baisse notamment lors de chaque attaque. Lorsque la durabilité d'une arme atteint 0 elle devient inutilisable.
Elle pourra cependant être réparée par la suite, ce qui rétablira la durabilité à sa valeur initiale.Implémentez les armes décrites ci-dessus en tant que classe Python dans le fichier nommé weapon.py :
class Weapon(object):
def __init__(self, name, attacks, durability):
pass
def get_name(self):
pass
def get_attacks(self):
pass
def get_durability(self):
pass
def get_max_durability(self):
pass
def is_usable(self):
pass
def damage(self, amount):
pass
def repair(self):
passLa méthode get_name doit retourner le nom de l'arme et la méthode get_attacks son niveau d'attaques.
La méthode get_durability retourne la durabilité courante de l'arme, tandis que la méthode get_max_durability retourne la durabilité maximale (initiale).
La méthode is_usable indique si l'arme est utilisable, c'est-à-dire si sa durabilité est plus grande que 0.
Ces cinq méthodes ne modifient pas l'état de l'arme.
La méthode damage permet de baisser la durabilité de l'arme d'un certain montant amount. À noter que la durabilité ne passera jamais en dessous de 0.
Finalement, la méthode repair permet de rétablir à son niveau initial la durabilité de l'arme.
Ces deux méthodes modifient l'état de l'arme mais ne retournent aucune valeur utile.
Afin de tester l'implémentation de votre classe, vous pouvez exécuter le script weapon-test.py. Ce fichier contient ce qu'on appelle des tests. Ces tests sont des bouts de code qui utiliseront votre classe et vérifieront si les résultats obtenus correspondent bien à ceux qui sont attendus.
Si tout est correct, vous devriez voir la sortie suivante :
.......
----------------------------------------------------------------------
Ran 7 tests in 0.000s
OKEn cas d'erreur, vous aurez des message qui indiqueront quels tests ne passent pas et pour quelle raison. Par exemple, si le nom de l'arme est retourné par erreur tout en majuscules de la classe Weapon, vous aurez un message de ce style :
....F..
======================================================================
FAIL: test_get_name (__main__.WeaponTest.test_get_name)
----------------------------------------------------------------------
Traceback (most recent call last):
File "[..]/weapon-test.py", line 9, in test_get_name
self.assertEqual("Test Weapon", test_weapon.get_name())
AssertionError: 'Test Weapon' != 'TEST WEAPON'
- Test Weapon
+ TEST WEAPON
----------------------------------------------------------------------
Ran 7 tests in 0.001s
FAILED (failures=1)L'exercice suivant se concentre autour des personnages du jeu. Les personnages du jeu ont chacun un nom, un nombre positif ou nul de points de vie et possiblement une arme d'équipée. Ils peuvent combattre contre d'autres personnages.
Pour cet exercice, la classe Character, qui représente les personnages, vous est déjà donnée. Elle se trouve dans le fichier character.py et est reproduite ci-dessous :
class Character(object):
def __init__(self, name, health, weapon):
self.name = name
self.health = health
self.weapon = weapon
def get_name(self):
return self.name
def get_health(self):
return self.health
def has_weapon(self):
return self.weapon is not None
def get_weapon(self):
return self.weapon
def is_alive(self):
return self.health > 0
def take_damage(self, amount):
self.health -= amount
if self.health == 0:
self.weapon == None
def attack(self, other):
if self.weapon.is_usable():
self.take_damage(self.weapon.get_attacks())
self.weapon.damage(1)
else:
other.take_damage(1)Les méthodes get_name, get_health, get_weapon et is_alive sont explicites.
La méthode take_damage permet de subir des dégâts sur le personnage. Si un personnage atteint 0 point de vie il perd immédiatement son arme et n'est plus considéré comme étant en vie.
La méthode attack permet d'attaquer un autre personnage passé au paramètre other. Si le personnage a une arme équipée et utilisable, il attaque l'autre personnage à l'aide de cet arme.
Autrement, il utilise ses poings et inflige un unique dégât.
À la place d'implémenter la classe Character, vous allez devoir utiliser l'implémentation donnée et la tester.
Vous allez implémenter quatre scénarios qui utilisent la classe et permettent de la tester.
Il est possible que ces tests mettent en lumière un ou plusieurs problèmes dans l'implémentation donnée, qu'il vous faudra ensuite corriger.
Pour concevoir vos tests, implémentez les méthodes test_scenario_1, test_scenario_2 et test_scenario_3 de la classe CharacterTest du fichier character-test.py. Pour tester une condition, vous avez quatre fonctions à votre disposition :
assertEqual pour tester l'égalité entre deux valeurs,assertTrue pour vérifier qu'une condition est vraie,assertFalse pour vérifier qu'une condition est fausse,asserIsNone pour tester si une valeur est None.Vous pouvez vous inspirer de ce qui est fait dans le fichier weapon-test.py.
Le premier scénario permet de tester les fonctionalités de base de la classe Character, sans inclure d'armes ni d'attaques.
Il sera implémenté dans la méthode test_scenario_1.
Pour ce premier scénario de test, créez un personnage avec un nom de votre choix, un nombre de point de vie égal à 100 et aucune arme équipée (None).
Ensuite, vérifiez que get_name, get_health, get_weapon et has_weapon retournent les résultats attendus.
Ensuite, vérifiez que is_alive retourne True.
Puis infligez 50 dégâts au personnage.
Vérifiez que is_alive retourne toujours True et que le nombre de points de vie est de 50.
Infligez cette fois 70 dégâts au personnage.
Vérifiez que is_alive retourne bien False et que le nombre de points de vie est bien égal à 0.
Si votre test décele un problème dans l'implémentation de la classe Character, corrigez l'implémentation et vérifiez que votre test passe après les changements.
Le deuxième scénario permet d'introduire les armes et les attaques.
Il sera implémenté dans la méthode test_scenario_2.
Créez une arme avec un nom de votre choix, un niveau d'attaques de 25 et une durabilité de 3.
Créez ensuite deux personnages, un qui jouera le rôle de l'attaquant et un autre du défenseur :
50 points de vie et comme arme l'arme créée plus haut.80 points de vie et aucune arme à sa disposition.Commencez par vérifier que l'attaquant a bien une arme et que le défenseur n'en a pas en utilisant has_weapon.
Ensuite, effectuez trois attaques de l'attaquant sur le défenseur. Après chaque attaque, vérifiez que le défenseur a bien perdu 25 points de vie et que la durabilité de l'arme de l'attaquant a bien baissé de 1.
Ensuite, faites encore deux attaques. Après chaque attaque, vérifiez que le nombre de points de vie du défenseur a bien baissé de 1.
Si votre test décele un problème dans l'implémentation de la classe Character, corrigez l'implémentation et vérifiez que votre test passe après les changements.
Finalement, pour le dernier scénario, vous allez vous intéresser aux combats à mains nues, sans armes.
Créez deux personnages, un qui jouera le rôle de l'attaquant et un autre du défenseur :
10 points de vie et aucune arme.5 points de vie et aucune arme.Effectuez trois attaques de l'attaquant sur le défenseur. Après chaque attaque, vérifiez que le défenseur a bien perdu 1 point de vie.
Si votre test décele un problème dans l'implémentation de la classe Character, corrigez l'implémentation et vérifiez que votre test passe après les changements.
Concevez finalement un scénario pour tester que les personnages perdent bien leur arme lorsqu'ils perdent leur dernier point de vie.