cours n°9 · Découverte

Le Roguelike

Objet, Hash, Set, YAML, IA, tour : six briques, un donjon — et la mort qui efface tout. Voici ta recette.

~11 min7 stations
▶ vidéo🧩 exercices📄 cheat sheet

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`.

Partage la leçon

← tous les cours

📄 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" → un if sur la distance, comme en 1980
  • "le roguelike c'est compliqué" → six briques, déjà écrites, dans ce cours.

SlopCourse Microduck — du slop au code propre.