Le Roguelike
Objet, Hash, Set, YAML, IA, tour : six briques, un donjon — et la mort qui efface tout. Voici ta recette.
42 secondes · sous-titres Français inclus · 8.6 Mo
Les 7 trucs que tu vas savoir faire
Leçon 9 : Le Roguelike
Regarde la leçon (42 s) : l'histoire d'un genre né d'un détail — puis la recette complète, brique par brique. Tu as déjà tout ce qu'il faut.
Brique 1 : l'objet — le héros
Écris la classe `Heros` : `initialize(pv)` qui range les points de vie, et une lecture `pv`. Un seul chiffre décide de ta vie — le reste est du confort.
Brique 2 : le donjon — un tableau de tableaux
Écris `donjon(lignes, colonnes)` : un tableau de tableaux rempli de `"."` — la case vide. Une grille qui dépend des dimensions reçues, jamais une taille en dur.
Brique 3 : le butin — jamais deux fois la même épée
Écris `ramasse(objets)` qui renvoie un `Set` : les objets uniques du butin. `require "set"` en haut, et les doublons tombent tout seuls.
Brique 4 : la sauvegarde — un fichier, un YAML
Écris `sauvegarde(etat)` : l'état du héros en YAML (`pv: 20`…). Le roguelike sauvegarde tout au même endroit — et la mort le relit pour l'effacer.
Brique 5 : le monstre — un pas vers toi
Écris `chasse(pos, cible)` : le monstre avance d'UNE case vers sa cible — l'axe X d'abord, l'axe Y ensuite (avec `<=>`). Pas de diagonale : un axe à la fois, comme les fantômes.
Leçon 9 : OK
Sans aide : `tour(carte, x, y, dx, dy)` — le tour complet. Case libre → renvoie `[x + dx, y + dy]` · case `"mur"` → tu restes `[x, y]` · case `"monstre"` → `:combat`.
📄 La feuille de chute
imprime-la, colle-la à ton écran, fais semblant que c'est ton idée📄 Cheat sheet — Le Roguelike (l'histoire + ta recette)
En 1980, Rogue tenait dans un terminal vert : un donjon neuf à chaque partie, une mort qui efface tout. Le genre entier tient en six briques — et tu les as toutes.
L'histoire, en trois lignes
| Année | Ce qui s'est passé | Ce que ça a apporté |
|---|---|---|
| 1980 | Rogue sur terminal VT100 | le donjon procédural + la mort permanente |
| années 80 | NetHack, ADOM… | même recette, plus de profondeur |
| aujourd'hui | des milliers de roguelikes | ta recette à toi — leçons 1 à 9 |
Le « détail » fondateur : la partie n'est pas un niveau, c'est un générateur. Tu ne dessines pas le donjon — tu écris la règle qui le construit.
La recette : 6 briques = 6 leçons
| Brique | Leçon | Le morceau de code |
|---|---|---|
| le héros (état) | 1 — objets | initialize + lecteur |
| la sauvegarde (fichier) | 2 — formats | to_yaml |
| le donjon (grille) | 3 + 8 — conteneurs & map | Array.new + cases x,y |
| le butin (sans doublons) | 3 — Set | Set.new(objets) |
| le monstre (IA) | 5 — les 4 fantômes | un pas, un axe |
| le tour (règles) | 7 + 8 — mouvement & collisions | case/when |
Brique 1 — le héros (l'objet)
class Heros
def initialize(pv)
@pv = pv
end
def pv
@pv
end
end
Heros.new(20).pv # => 20
La vie du héros est un état rangé, jamais une variable globale.
Brique 2 — le donjon (un tableau de tableaux)
def donjon(lignes, colonnes)
Array.new(lignes) { Array.new(colonnes, ".") }
end
donjon(2, 3) # => [[".", ".", "."], [".", ".", "."]]
La case vide est "." — le mien deviendra #, le tien ce que tu veux.
Brique 3 — le butin (Set) + la sauvegarde (YAML)
Set.new(["epee", "epee", "potion"]) # => #<Set: {"epee", "potion"}>
{ "pv" => 20, "x" => 3 }.to_yaml # => "---\npv: 20\nx: 3\n"
Un inventaire qui refuse les doublons, une partie qui tient dans un fichier — format et conteneur, rien de plus.
Brique 4 — le monstre : l'IA d'avant l'IA
def chasse(pos, cible)
dx = cible[0] <=> pos[0]
dy = cible[1] <=> pos[1]
dx != 0 ? [pos[0] + dx, pos[1]] : [pos[0], pos[1] + dy]
end
chasse([5, 5], [5, 2]) # => [5, 4]
Pas de calcul trajectoire, pas de machine learning : un pas par tour, un axe à la fois. (Pac-Man, 1980 aussi — leçon 5.)
Brique 5 — le tour : tout le gameplay en un case
def tour(carte, x, y, dx, dy)
cible = "#{x + dx},#{y + dy}"
case carte[cible]
when "mur" then [x, y] # face au mur : je reste
when "monstre" then :combat # face à l'ennemi : je frappe
else [x + dx, y + dy] # case libre : j'avance
end
end
Un Hash lu une fois par tour — murs, monstres, trésors : même question, même adresse.
La mort permanente (le paradoxe du genre)
File.write("partie.yaml", sauvegarde(etat)) # enregistre
File.delete("partie.yaml") # meurt → tout recommence
La difficulté vient de ce qu'on efface, pas de ce qu'on ajoute.
À ne plus jamais dire
"il me faut un moteur / un générateur de donjons"→ une règle qui remplit un tableau de tableaux"une IA de monstre"→ unifsur la distance, comme en 1980"le roguelike c'est compliqué"→ six briques, déjà écrites, dans ce cours.
SlopCourse — du slop au code propre.