Système de personnages de jeu
Fait partie de la section Programmation Orientée Objet du Journey GO de Coddy. Leçon 107 sur 107.
Défi
FacileConstruisons un système de personnages de jeu qui réunit l’intégration de structures, les interfaces et le modèle Strategy afin de créer des mécaniques de combat flexibles ! Vous concevrez différents types de personnages capables d’attaquer et de se défendre de manière unique, avec des capacités pouvant être remplacées à l’exécution.
Vous organiserez votre code sur cinq fichiers :
character.go: définissez une structureCharacterde base avec des champs communs :Name(string),Health(int) etMaxHealth(int). Incluez un constructeurNewCharacteret les méthodes suivantes :IsAlive() bool: renvoie true si la santé est supérieure à 0Status() string: renvoie le format :[Name]: [Health]/[MaxHealth] HP
interfaces.go: définissez les interfaces de combat qui permettent le polymorphisme :- interface
AttackeravecAttack() int: renvoie les dégâts infligés - interface
DefenderavecTakeDamage(damage int) int: applique une réduction des dégâts et renvoie les dégâts réellement subis - interface
AbilityavecUse() string: renvoie une description de l’effet de la capacité
- interface
characters.go: créez trois types de personnages qui intègrentCharacteret implémentent à la foisAttackeretDefender:Warrior: possède les champsStrength(int) etArmor(int). L’attaque renvoie Strength comme dégâts. TakeDamage réduit les dégâts entrants de la valeur d’Armor (avec un minimum de 1 dégât subi).Mage: possède les champsIntelligence(int) etMagicResist(int). L’attaque renvoie Intelligence * 2 comme dégâts. TakeDamage réduit les dégâts entrants de MagicResist / 2 (avec un minimum de 1 dégât subi).Archer: possède les champsAgility(int) etEvasion(int). L’attaque renvoie Agility + 5 comme dégâts. TakeDamage : si Evasion > 10, réduit les dégâts de 25 % (division entière), sinon les dégâts complets sont subis (avec un minimum de 1 dégât subi).Incluez des constructeurs pour chacun d’eux :
NewWarrior,NewMage,NewArcher, qui prennent le nom, la santé et les valeurs de statistiques spécifiques à leur type.abilities.go: implémentez le modèle Strategy avec des capacités interchangeables :structure
FireSpellavecPower(int). SonUse()renvoie :Casts fireball for [Power] damagestructure
IceSpellavecPower(int). SonUse()renvoie :Casts ice shard for [Power] damagestructure
PowerStrikeavecMultiplier(int). SonUse()renvoie :Performs power strike at [Multiplier]x damageAjoutez un champ
ability(de typeAbility) à la structure Mage, avec les méthodesSetAbility(a Ability)etUseAbility() string. UseAbility renvoieNo ability setsi ability vaut nil.main.go: créez des personnages et démontrez les mécaniques de combat.Lisez le type du personnage (
warrior,mageouarcher), puis lisez le nom, la santé et les statistiques propres à son type. Créez le personnage approprié.Lisez ensuite le nombre d’actions. Chaque action est l’une des suivantes :
status: affiche l’état du personnageattack: affiche[Name] attacks for [damage] damagedefend [amount]: applique les dégâts et affiche[Name] takes [actual] damagesetability [type] [power]: pour les mages uniquement, définit la capacité (type :fire,iceoustrike)useability: pour les mages uniquement, affiche le résultat de Use() de la capacité
Les entrées suivantes seront fournies :
- Le type, le nom, la santé et les statistiques propres au type du personnage
- Le nombre d’actions, puis chaque action sur une ligne distincte
Par exemple, avec :
warrior
Thorin
100
15
8
5
status
attack
defend 20
status
defend 100Votre sortie doit être :
Thorin: 100/100 HP
Thorin attacks for 15 damage
Thorin takes 12 damage
Thorin: 88/100 HP
Thorin takes 92 damageEt avec :
mage
Gandalf
80
25
10
6
attack
useability
setability fire 30
useability
setability ice 25
useability
defend 40Votre sortie doit être :
Gandalf attacks for 50 damage
No ability set
Casts fireball for 30 damage
Casts ice shard for 25 damage
Gandalf takes 35 damageEt avec :
archer
Legolas
90
18
15
4
status
attack
defend 24
statusVotre sortie doit être :
Legolas: 90/90 HP
Legolas attacks for 23 damage
Legolas takes 18 damage
Legolas: 72/90 HPRemarquez comment l’intégration de structures permet à chaque type de personnage de partager les champs et les méthodes de base de Character, tandis que les interfaces permettent un combat polymorphe où tout Attacker peut infliger des dégâts et tout Defender peut en subir. Le modèle Strategy se révèle particulièrement utile avec les capacités interchangeables du Mage : le même personnage peut utiliser différents sorts sans modifier son implémentation principale !
Essayez vous-même
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
// Lire le type de personnage
scanner.Scan()
charType := strings.TrimSpace(scanner.Text())
// Lire le nom du personnage
scanner.Scan()
name := strings.TrimSpace(scanner.Text())
// Lire la santé
scanner.Scan()
health, _ := strconv.Atoi(strings.TrimSpace(scanner.Text()))
// Lire la première statistique spécifique au type
scanner.Scan()
stat1, _ := strconv.Atoi(strings.TrimSpace(scanner.Text()))
// Lire la deuxième statistique spécifique au type
scanner.Scan()
stat2, _ := strconv.Atoi(strings.TrimSpace(scanner.Text()))
// TODO: Créer le personnage approprié en fonction de charType
// Utiliser les variables : charType, name, health, stat1, stat2
// Pour warrior : stat1 = Strength, stat2 = Armor
// Pour mage : stat1 = Intelligence, stat2 = MagicResist
// Pour archer : stat1 = Agility, stat2 = Evasion
// Lire le nombre d'actions
scanner.Scan()
numActions, _ := strconv.Atoi(strings.TrimSpace(scanner.Text()))
// Traiter chaque action
for i := 0; i < numActions; i++ {
scanner.Scan()
line := strings.TrimSpace(scanner.Text())
parts := strings.Fields(line)
action := parts[0]
// TODO: Gérer chaque type d'action :
// - "status": afficher le Status() du personnage
// - "attack": afficher "[Name] attacks for [damage] damage"
// - "defend [amount]": appliquer les dégâts et afficher "[Name] takes [actual] damage"
// - "setability [type] [power]": pour les mages, définir la capacité (fire, ice, or strike)
// - "useability": pour les mages, afficher le résultat de UseAbility()
_ = action // Supprimer cette ligne lors de l'implémentation
_ = fmt.Println // Supprimer cette ligne lors de l'implémentation
}
}
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO en Go
Fichiers externesEspace de travail et modules GoPackages et importsNoms exportés et non exportésIntroduction à la POO en GoStructs comme classesDéfinir des méthodes sur des structsRécepteurs pointeurs ou par valeurInitialisation des structsFonctions constructeursRécapitulatif - Calculatrice simple4Interfaces
Introduction aux interfacesImplémentation impliciteL’interface comme contratInterface vide (any)Assertion de typeCommutation de typeComposition d’interfacesInterfaces Stringer et ErrorRécapitulatif - Calculateur de formes7Encapsulation
Champs exportés vs non exportésEncapsulation au niveau du packageMéthodes Getter et SetterDissimulation de l’information en GoRécapitulatif – Fiches d’étudiants10Génériques (Go 1.18+)
Introduction aux génériquesParamètres de typeContraintes de typeStructures génériquesSolution de contournement pour les méthodes génériquesRécapitulatif - Collection générique2Plongée approfondie dans les types et les structs
Types de base et compositesDéfinitions de types personnalisésTags de structStructs anonymesStructs imbriquésValeurs zéro et valeurs par défautRécapitulatif - Carnet de contacts5La composition plutôt que l’héritage
Pourquoi Go n’a pas d’héritageBases de l’inclusion de structsPromotion des méthodesInclure plusieurs structsInclusion ou agrégationMasquage des méthodes inclusesRécapitulatif : hiérarchie des employés8Gestion des erreurs et POO
L’interface errorTypes d’erreurs personnalisésEnrobage des erreurs (fmt.Errorf)Erreurs sentinelleserrors.Is() et errors.As()Panic, Defer et RecoverRécapitulatif - Analyseur de fichiers11Bibliothèque standard et POO
io.Reader et io.Writersort.InterfaceInterface fmt.Stringerencoding/json avec des structsInterface http.HandlerRécapitulatif - Modèles d’API REST14Modèles de conception – Partie 2
Modèle CommandeModèle AdaptateurModèle DécorateurModèle Méthode modèleModèle ÉtatModèle CompositeMiddleware comme décorateur3Pointeurs et mémoire
Notions de base des pointeurs en GoPointeurs vers des structuresPassage par valeur ou par référenceLa fonction new()Garbage collection en GoRécapitulatif - Constructeur de listes chaînées6Polymorphisme en Go
Polymorphisme via les interfacesDuck typing en GoRègles de satisfaction des interfacesCollections polymorphesInjection de dépendancesRécapitulatif – Processeur de paiements9Concurrence et POO
Bases des GoroutinesCanaux et communicationCanaux tamponnés ou non tamponnésInstruction selectsync.Mutex et sync.RWMutexsync.WaitGroupConception de structures thread-safeRécapitulatif - Pool de workersEntraînez-vous par vous-même : Compilateur Go en ligne