J'ai récemment commencé le cours sur la programmation en Ruby, je suis au dernier exercice et je bloque complètement sur certaines méthodes, notamment les méthodes attaque et subit_attaque ...
Si certains peuvent me mettre sur la voie (pas me donner la correction hein ^^) je leur en serai reconnaissant :)
Poste ton code en utilisant les balises de code. Que penses tu qu’il faille faire dans la méthode attaque ? Et dans dégâts ? J’ai pas lu ce cours mais je crois qu’il y a des commentaires qui disent ce que la méthode doit faire, non ?
Ok, avec ce que tu me dis là, je comprends ton incompréhension, les noms des méthodes sont mal choisis. En fait, attaque doit appeler subit_attaque en lui donnant en paramètre le nombre de dégâts à infliger. Quant à l'attribut en_vie, c'est une aberration qui devrait être remplacé par une méthode vivant? qui retourne points_de_vie > 0.
Non, il n'y a pas de composition dans l'histoire (la composition, c'est par exemple une classe Train qui contient un attribut locomotive), juste de la mauvaise conception.
Je suis tout nouveau dans le monde de l'informatique et la programmation. Pardonnez-moi si je ne poste pas au bon endroit.
J'ai installé Ruby une premiere fois tout fonctionnait bien jusqu’à la partie boucle du cours, où il faut creer du code dans un fichier. Je n'arrivais pas à faire le lien entre la console et le fichier boucle.rb. J'ai consulté des forums et il était conseillé de supprimer puis d'installer à nouveau Ruby pour réparler le probleme.
C'est ce que j'ai sauf que depuis, quand je tape "irb" dans la console l'ordinateur ne reconnait plus ruby et m'affiche ça:
C:/Programmation/Ruby/lib/ruby/site_ruby/rbreadline.rb:6135:in `delete': invalid byte sequence in UTF-8 (ArgumentError)
from C:/Programmation/Ruby/lib/ruby/site_ruby/rbreadline.rb:6135:in `alloc_history_entry'
from C:/Programmation/Ruby/lib/ruby/site_ruby/rbreadline.rb:6168:in `add_history'
from C:/Programmation/Ruby/lib/ruby/site_ruby/readline.rb:368:in `<<'
from C:/Programmation/Ruby/lib/ruby/2.4.0/irb/ext/save-history.rb:76:in `block (2 levels) in load_history'
from C:/Programmation/Ruby/lib/ruby/2.4.0/irb/ext/save-history.rb:76:in `each'
from C:/Programmation/Ruby/lib/ruby/2.4.0/irb/ext/save-history.rb:76:in `block in load_history'
from C:/Programmation/Ruby/lib/ruby/2.4.0/irb/ext/save-history.rb:75:in `open'
from C:/Programmation/Ruby/lib/ruby/2.4.0/irb/ext/save-history.rb:75:in `load_history'
from C:/Programmation/Ruby/lib/ruby/2.4.0/irb/ext/save-history.rb:65:in `extended'
from C:/Programmation/Ruby/lib/ruby/2.4.0/irb/ext/save-history.rb:21:in `extend'
from C:/Programmation/Ruby/lib/ruby/2.4.0/irb/ext/save-history.rb:21:in `init_save_history'
from C:/Programmation/Ruby/lib/ruby/2.4.0/irb/ext/save-history.rb:45:in `save_history='
from C:/Programmation/Ruby/lib/ruby/2.4.0/irb/context.rb:92:in `initialize'
from C:/Programmation/Ruby/lib/ruby/2.4.0/irb.rb:412:in `new'
from C:/Programmation/Ruby/lib/ruby/2.4.0/irb.rb:412:in `initialize'
from C:/Programmation/Ruby/lib/ruby/2.4.0/irb.rb:383:in `new'
from C:/Programmation/Ruby/lib/ruby/2.4.0/irb.rb:383:in `start'
from C:/Programmation/Ruby/bin/irb.cmd:19:in `<main>'
Quelqu'un sait ce qu'il faut faire dans ce cas la?
Le conseil de réinstaller Ruby était quand même assez mauvais. Pour ton problème, essaie de supprimer le fichier .irb_history (il est dans le dossier C:\Users\<nom_utilisateur>.</nom_utilisateur>
Comme beaucoup apparemment, j'ai un petit souci pour relier le fichier boucles.rb à la console.
Voici ce que je dois faire :
créer un fichier vide boucles.rb ;
l'ouvrir dans votre éditeur de texte à côté de votre console ;
placer votre console dans le dossier qui contient votre fichier boucles.rb (pour cela tapez cd nom_du_dossier dans votre console)
Voici ce que je fais :
je créé un fichier boucles.rb où je ne mets rien dedans. Je l'enregistre dans un dossier qui s'appelle test qui est sur mon bureau.
je l'ouvre avec sublim text
dans ma console je tape tout ce qui me paraît approcher du chemin de mon dossier ... mais non, ça ne fonctionne pas ... (voir pièce jointe copie écran)
Avez-vous une idée ? (j'ai évidemment parcouru les précédents topics du forum en quête d'une solution qui fonctionnerait pour moi mais non, ça ne marche pas...)
J'en suis à la première partie du cours avec les voyages et je voulais m'amuser, une fois le code fait, a changé quelques trucs et à vouloir des informations plus précise.
Mon but est donc de sélectionner la donnée Bali et et automatiquement la donnée 365 jours.
j'ai essayé ça :
puts "Cette personne veut aller à #{voyage[:4] }" + " " + "pour" + " " + "#{voyage[:4]} jours" ( pour dire la 4eme valeur dans le tableau) mais ça ne fonctionne pas..
Auriez-vous des idées ?
Merci d'avance :)
- Edité par MustaphaAitOuayhou 14 septembre 2018 à 15:59:48
bonjour j'ai un souci sur un exo qui demande l'année de naissance d'un utilisateur et qui va afficher chaque année depuis son année de naissance jusqu'en 2017. Pour chaque année affichée, le programme devra annoncer l'age que l'utilisateur a eu cette année voici mon code:
J'ai un petit souci pour réaliser le TP final. J'ai suivi le cours, j'ai compris dans l'ensemble, mais à la pratique, c'est là qu'on voit que la marge de progression est énorme
J'obtiens l'affichage suivant:
Ainsi débutent les aventures de Jean-Michel Paladin
Jean-Michel Paladin attaque Balrog
jeu2.rb:22:in `subit_attaque': undefined method `-' for nil:NilClass (NoMethodError)
from jeu2.rb:15:in `attaque'
from jeu2.rb:52:in `<main>'
La méthode "subit_attaque" n'est pas définie... Allons bon, je capte pas pourquoi...
Je vous mets mon code:
class Personne
attr_accessor :nom, :points_de_vie, :en_vie
def initialize(nom)
@nom = nom
@points_de_vie = 100
@en_vie = true
end
def attaque(personne)
# - Fait subir des dégats à la personne passée en paramètre
# - Affiche ce qu'il s'est passé
puts "#{nom} attaque #{personne.nom}"
deg = 1
personne.subit_attaque(deg)
end
def subit_attaque(degats_recus)
# - Réduit les points de vie en fonction des dégats reçus
# - Affiche ce qu'il s'est passé
# - Détermine si la personne est toujours en_vie ou non
points_de_vie -= degats_recus
puts "#{nom} subit #{degats_recus} hp de dégâts"
#if points_de_vie <= 0
#en_vie = false
#end
end
end
class Joueur < Personne
attr_accessor :degats_bonus
def initialize(nom)
# Par défaut le joueur n'a pas de dégats bonus
@degats_bonus = 0
# Appelle le "initialize" de la classe mère (Personne)
super(nom)
end
end
class Ennemi < Personne
end
joueur = Joueur.new("Jean-Michel Paladin")
ennemi = Ennemi.new("Balrog")
puts "Ainsi débutent les aventures de #{joueur.nom}\n"
joueur.attaque(ennemi)
Si vous pouvez me filer un coup de main et me mettre sur la bonne voie, ça me rendrait service.
@Xt0f ça vient certainement du fait que tu modifies la valeur de point_de_vie sans préciser self.point_de_vie. Le self est implicite pour récupérer la valeur pas pour la modifier ou la redéfinir.
Pour compléter ce que dit @necros211, on n'a aucun besoin de savoir combien de points de vie a une personne, ça fait partie de son fonctionnement interne. Nous ce qu'on veut, c'est pouvoir savoir s'il est en vie et pouvoir le frapper. Et ceci indépendamment de comment c'est codé en interne (par exemple, il pourrait ne pas y avoir de points de vie, et c'est juste qu'au bout d'un temps aléatoire il n'est pas en vie, il pourrait avoir des points de santé, des points d'énergie et des points de mental et dès qu'il n'a plus de points pour un des trois il est mort, etc.).
Ceci passe par exemple par avoir une méthode alive? plutôt qu'une variable d'instance @en_vie. Avec les points de vie alive? serait juste @hp > 0.
De plus, ce serait bien de ne pas pouvoir modifier @nom ; on aimerait bien qu'un personnage garde le même nom pendant toute la partie. Et donc, il faudrait utiliser attr_reader pour le nom et pas attr_accessor.
Je viens de commencer les cours depuis quelques heures... C'est aussi beau que l'on me l'avait décrit, j'ai hâte de voir ce que veut dire "puissant" maintenant ! Merci pour les cours, c'est clair et très agréable à lire / regarder !
Ben « puissant », ça veut surtout dire tout et n'importe quoi en terme de langage de programmation. Sinon, attention à ne pas juste lire et regarder, sans pratique, ça permettra difficilement de progresser. Donc, ne pas hésiter à faire des exercices et à demander des avis à leur sujet sur le forum. Et bien sûr, ne pas hésiter à poser des questions sur le forum.
Merci du précieux conseil, j'ai longtemps fait cette erreur... Ruby me plaît beaucoup jusque là (quelques heures :p), ça donne envie de manipuler du code !
D'ailleurs, j'en suis au TD de fin de chapitre (le jeu avec Jean-Michel Paladin), j'essaye de l'aborder petit bout par petit bout... mais je bloque déjà ! Si les coups de mains sont autorisés, j'suis pas contre une petite pichenette pour avancer ce soir !
J'ai décidé d'attaquer par la méthode "soin" :
def soin
# A faire:
points_de_vie += rand(25)
puts "#{nom} s'est soigné de #{hp_soignes} points de vie (#{points_de_vie}HP)"
# - Gagner de la vie
# - Affiche ce qu'il s'est passé
end
Lorsque j’exécute le code, j'ai une erreur "jeu.rb:49:in `soin': undefined method `+' for nil:NilClass (NoMethodError)" (49 étant "point_de_vie += rand(25)).
Quand je compare l'héritage de "Personne" et "Joueur" à celui de "Animal" et "Chat" (exercice précédent), tout me semble pourtant similaire :
j'accède directement aux variables concernées ("point_de_vie" et "nom" pour le jeu, "nom" pour les animaux), présentent dans les constructeurs ("Personne" / "Animal").
les méthodes sont définies dans la classe héritée ("Joueur" pour le jeu, "Chat"/"Chien" pour les animaux)
Du coup je comprends pas vraiment pourquoi il n'arrive pas à accéder à la méthode... J'ai essayé des variantes comme "Joueur.point_de_vie", "joueur.point_de_vie", "Personne.point_de_vie"... Mais le problème ne semble pas venir de là !
Si quelqu'un pouvait me guider un petit peu ce serait vraiment apprécié ... Sinon j'me gratterai la tête et referai les cours
Et bien sûr, quand tu fournis du code, il vaut mieux fournir le code nécessaire à la compréhension (par exemple le code de la classe Personnage pour ton problème précédent. Pour ton problème, la variable d'instance pour le nom, c'est @nom pas nom (ou tu crées l'accesseur nécessaire avec attr_reader, ce qui, pour le cas du prénom, n'est pas déconnant ).
Non, les arobases indiquent qu'il s'agit d'une variable d'instance. On peut accéder et modifier une variable d'instance dans les méthodes de classe.
class Personne
def initialize(nom, prenom)
@nom = nom.upcase
@prenom = prenom.capitalize
end
def to_s
return "#{@nom} #{@prenom}"
end
end
Mais, on ne peut pas y accéder depuis l'extérieur.
p = Personne.new("aa", "bb")
print(p) # On obtient "AA Bb"
print(p.nom) # Une erreur, la méthode nom n'existe pas
Il nous faut donc définir une méthode pour donner accès à @nom.
class Personne
def nom
@nom
end
# Le reste du code.
end
Cette fois, après avoir créé une personne p, on peut faire p.nom, la méthode p existe.
Mais, on ne peut pas modifier nom, pour cela, il nous faut créer une autre méthode qui prend en paramètre le nouveau nom et fait @nom = nouveau_nom. Généralement, on appelle cette méthode nom_attribut=, donc ici nom= et prenom=Et là, c'est OK (en fait, comme je l'ai dit plus haut, on préférerait ne pas pouvoir modifier les noms et donc on ne créerait pas nom=.
Mais, Ruby est gentil et avec attr_reader, attr_writer et attr_accessor, on peut créer ces méthodes plus facilement. attr_reader crée seulement nom (donc en gros, permet d'accéder à la variable d'instance en lecture), attr_writer crée nom= (et permet donc d'accéder à la variable d'instance en écriture), et attr_accessor crée les deux.
Wow c'est super clair, merci de répondre aux questions que je ne m'étais pas encore posé !
Si j'essaye de reformuler et de synthétiser, les variables d'instance sont donc des variables "verrouillées" et nécessaires à l'instanciation, dont on peut ajuster les propriétés (lecture/écriture) attr_ ?
Du coté de Jean-Michel Paladin ça avance, c'est "fini avec plein de bug" ! J'ai des petits soucis avec l'état mort ou vivant des ennemis et des petits soucis d'affichage... Mais j'me pencherai dessus demain, en espérant réussir à terminer ! J'ai pas défini ni utiliisé la méthode (fonction ?) "Personne.subit_attaque" par contre... c'est peut être pour ça que ça bug
Merci beaucoup en tout cas, bonne fin de soirée à toi
Bon, j'ai l'impression de bloquer à la dernière ligne de code des Aventures de Jean-Michel. Tout fonctionne à merveille, sauf si j'ai mal débuggé, sauf une condition de victoire : "tout les ennemis sont morts".
Le soucis que lorsque je veux déterminé si les conditions de victoire sont remplies ou non, la méthode "Jeu.est_fini" renvoie "true" (alors que je m'attends à ce qu'elle renvoie false : il reste des ennemis en vie) J'ai pas touché aux conditions du break en fin de boucle :
break if Jeu.est_fini(joueur, monde)
def self.est_fini(joueur, monde)
# Renvoi "true" si le jeu doit se finir # A faire:
# - Déterminer la condition de fin du jeu
joueur.en_vie == false
monde.ennemis do |ennemi|
ennemi.en_vie == false
end
end
end
J'ai également tenté
joueur.en_vie == false && monde.ennemis.each do |ennemi|
ennemi.en_vie == false
et naïvement, j’espérais accéder à la propriété qui m’intéresse via "monde.ennemis.en_vie", mais je semble être contraint d'utiliser un ".each do ||"...
Pourtant, un "puts ennemi.en_vie" dans ma methode "ennemis_en_vie" retourne bien "false" une fois les ennemis tués
def ennemis_en_vie
# A faire:
# - Ne retourner que les ennemis en vie
ennemis.each do |ennemi|
puts ennemi.en_vie
if ennemi.en_vie == true
puts "#{ennemi.nom} inflige #{ennemi.degats} dégats\n"
else
ennemi.en_vie = false
end
end
end
Mais impossible de d'utiliser ce booléen pour créer ma condition de victoire
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Architecte logiciel - Software craftsmanship convaincu.
Architecte logiciel - Software craftsmanship convaincu.
Architecte logiciel - Software craftsmanship convaincu.