C'est bientôt Noël ! (enfin presque)

Rassurez-vous, je ne suis pas de ceux qui préparent les sapins de Noël et les cadeaux au mois de juillet, comme on voit de plus en plus. :zany_face:

Mais j’ai tout de même eu cette pensée à l’approche de Noël, des fameux programmes AutoLISP que certains d’entre nous faisaient les années passées pour dessiner soit des Père Noël, soit des sapins de Noël, une utilisation amusante de la programmation. :christmas_tree:

Et je me suis dit, tiens, mais au fait l’intelligence artificielle est très certainement capable de faire tout ça. Donc je m’suis lancé, j’ai demandé à Gemini 3 Pro de réaliser un sapin de Noël pour les fêtes. Gemini 3 Pro est la toute dernière intelligence artificielle de Google, et il est dit qu’elle surpasse très largement les autres, incluant ChatGPT. Je voulais en avoir le cœur net, je ne vais pas vous mettre ici le code qu’a produit ChatGPT, Claude ou d’autres IA, il est très pauvre comparé à ce qu’a pu réaliser ci-dessous Gemini 3 Pro.

Donc voici ce programme AutoLISP sans aucune retouche du tout, qui a fonctionné la première fois, alors évidemment vous allez me dire, comparé à ce qu’on a pu faire par le passé, le sapin de Noël est plutôt dépouillé, certes je suis bien d’accord avec vous, mais imaginez que la chose s’est faite en moins de cinq secondes… :smiling_face_with_sunglasses:

sapin.lsp (6,3 Ko)

;;; ==========================================================================
;;; JOYEUX NOEL pour AutoCAD
;;; Commande : SAPIN
;;; Description : Dessine un sapin de Noël avec décorations aléatoires,
;;;               cadeaux et une étoile.
;;; Auteur : Assistant IA (pour le plaisir des utilisateurs AutoCAD)
;;; ==========================================================================

(defun c:SAPIN (/ *error* old_osmode old_cmdecho pt_base trunk_w trunk_h 
                  levels level_height base_width i pt_curr p1 p2 p3 p4 
                  rand val_rand pt_rnd k color_rnd)

  ;; Gestionnaire d'erreur pour rétablir les variables si on annule (Echap)
  (defun *error* (msg)
    (if old_osmode (setvar "OSMODE" old_osmode))
    (if old_cmdecho (setvar "CMDECHO" old_cmdecho))
    (princ "\nJoyeux Noël ! (Commande annulée)")
    (princ)
  )

  ;; Sauvegarde des variables système
  (setq old_osmode (getvar "OSMODE"))
  (setq old_cmdecho (getvar "CMDECHO"))
  (setvar "OSMODE" 0)    ; Désactive l'accrochage pour dessiner librement
  (setvar "CMDECHO" 0)   ; Masque le défilement des commandes

  ;; --- Fonction pour générer un nombre pseudo-aléatoire ---
  ;; Basé sur l'heure actuelle
  (defun rand (n)
    (setq val_rand (getvar "DATE"))
    (setq val_rand (- val_rand (fix val_rand)))
    (setq val_rand (fix (* val_rand 10000000)))
    (rem val_rand n)
  )

  ;; --- Création des calques (Layers) ---
  (princ "\nPréparation des décorations...")
  (foreach lay '("0_NOEL_TRONC" "0_NOEL_FEUILLES" "0_NOEL_DECO" "0_NOEL_ETOILE" "0_NOEL_CADEAUX")
    (if (not (tblsearch "LAYER" lay))
      (command "_.-LAYER" "_N" lay "_M" lay "")
    )
  )
  ;; Couleurs des calques
  (command "_.-LAYER" "_C" "30" "0_NOEL_TRONC" "")     ; Marron
  (command "_.-LAYER" "_C" "3" "0_NOEL_FEUILLES" "")   ; Vert
  (command "_.-LAYER" "_C" "2" "0_NOEL_ETOILE" "")     ; Jaune
  (command "_.-LAYER" "_C" "1" "0_NOEL_DECO" "")       ; Rouge par défaut
  (command "_.-LAYER" "_C" "6" "0_NOEL_CADEAUX" "")    ; Magenta

  ;; --- Paramètres du sapin ---
  (setq pt_base (getpoint "\nOù voulez-vous planter le sapin ? (Cliquez un point) : "))
  (if (not pt_base) (setq pt_base '(0 0 0)))
  
  (setq trunk_w 20.0)    ; Largeur tronc
  (setq trunk_h 30.0)    ; Hauteur tronc
  (setq levels 4)        ; Nombre d'étages du sapin
  (setq level_height 60.0) ; Hauteur d'un étage
  (setq base_width 120.0)  ; Largeur de la base des branches

  ;; --- 1. Dessin du TRONC ---
  (setvar "CLAYER" "0_NOEL_TRONC")
  (command "_.RECTANG" 
           (list (- (car pt_base) (/ trunk_w 2)) (cadr pt_base)) 
           (list (+ (car pt_base) (/ trunk_w 2)) (+ (cadr pt_base) trunk_h))
  )
  (command "_.-HATCH" "_P" "SOLID" "_S" "_L" "" "")

  ;; --- 2. Dessin du FEUILLAGE (Les étages) ---
  (setvar "CLAYER" "0_NOEL_FEUILLES")
  (setq pt_curr (list (car pt_base) (+ (cadr pt_base) trunk_h))) ; Point de départ (haut du tronc)
  
  (setq i 0)
  (while (< i levels)
    ;; Calcul des points du triangle/trapèze
    ;; Facteur de rétrécissement progressif
    (setq w_bottom (- base_width (* i 20.0))) 
    (setq w_top (- w_bottom 30.0))
    
    (setq p1 (list (- (car pt_curr) (/ w_bottom 2)) (cadr pt_curr)))
    (setq p2 (list (+ (car pt_curr) (/ w_bottom 2)) (cadr pt_curr)))
    (setq p3 (list (+ (car pt_curr) (/ w_top 2)) (+ (cadr pt_curr) level_height)))
    (setq p4 (list (- (car pt_curr) (/ w_top 2)) (+ (cadr pt_curr) level_height)))
    
    ;; Dessin du contour
    (command "_.PLINE" p1 p2 p3 p4 "_C")
    ;; Hachurage
    (command "_.-HATCH" "_P" "SOLID" "_S" "_L" "" "")
    
    ;; --- 3. DECORATIONS (Boules et Cadeaux sur les branches) ---
    ;; On ajoute des décos aléatoires à chaque étage
    (setq k 0)
    (while (< k (+ 4 (rand 4))) ; Entre 4 et 8 décos par étage
      
      ;; Position aléatoire approximative dans l'étage
      (command "_.DELAY" 10) ; Petite pause pour varier le seed aléatoire
      (setq pt_rnd (list 
                     (+ (car p1) (rand (fix (- (car p2) (car p1)))))
                     (+ (cadr p1) (rand (fix level_height)))
                   ))
      
      ;; Choix aléatoire : Boule (0) ou Cadeau (1)
      (if (= (rand 2) 0)
        (progn
          ;; --- BOULE ---
          (setvar "CLAYER" "0_NOEL_DECO")
          ;; Couleur aléatoire pour la boule (1 à 7)
          (setq color_rnd (1+ (rand 6))) 
          (command "_.-COLOR" color_rnd)
          (command "_.CIRCLE" pt_rnd 3.0) ; Rayon 3
          (command "_.-HATCH" "_P" "SOLID" "_S" "_L" "" "")
        )
        (progn
          ;; --- CADEAU SUR BRANCHE ---
          (setvar "CLAYER" "0_NOEL_CADEAUX")
          (command "_.-COLOR" (1+ (rand 6)))
          ;; Petit carré
          (command "_.RECTANG" pt_rnd (list (+ (car pt_rnd) 6) (+ (cadr pt_rnd) 6)))
          (command "_.-HATCH" "_P" "SOLID" "_S" "_L" "" "")
          ;; Petit ruban (ligne)
          (command "_.-COLOR" "7") ; Blanc
          (command "_.LINE" (list (+ (car pt_rnd) 3) (cadr pt_rnd)) (list (+ (car pt_rnd) 3) (+ (cadr pt_rnd) 6)) "")
          (command "_.LINE" (list (car pt_rnd) (+ (cadr pt_rnd) 3)) (list (+ (car pt_rnd) 6) (+ (cadr pt_rnd) 3)) "")
        )
      )
      (setq k (1+ k))
    )
    
    ;; Préparer le prochain étage
    (setq pt_curr (list (car pt_curr) (+ (cadr pt_curr) (* level_height 0.7)))) ;; Chevauchement
    (setq i (1+ i))
  )

  ;; --- 4. L'ETOILE ---
  (setvar "CLAYER" "0_NOEL_ETOILE")
  (command "_.-COLOR" "BYLAYER")
  (setq pt_top (list (car pt_base) (+ (cadr pt_base) trunk_h (* levels (* level_height 0.7)) 15.0)))
  
  ;; Dessin simple de l'étoile (cercle jaune hachuré pour simplifier ou polygone)
  (command "_.POLYGON" 5 pt_top "_I" 12.0)
  (command "_.-HATCH" "_P" "SOLID" "_S" "_L" "" "")

  ;; --- 5. TEXTE ---
  (setvar "CLAYER" "0_NOEL_DECO")
  (command "_.-COLOR" "1") ; Rouge
  (setq pt_text (list (car pt_base) (- (cadr pt_base) 30.0)))
  (command "_.TEXT" "_J" "_MC" pt_text 15.0 0 "JOYEUX NOEL !")

  ;; Rétablissement
  (setvar "OSMODE" old_osmode)
  (setvar "CMDECHO" old_cmdecho)
  (setvar "CLAYER" "0")
  (princ "\nLe sapin est décoré ! Ho Ho Ho !")
  (princ)
)

;; Message de chargement
(princ "\n--- Tapez SAPIN pour dessiner votre arbre de Noël ---")
(princ)

Après avoir utilisé les intelligences artificielles depuis environ deux ans me semble-t-il un petit peu plus, je peux dire que celle-ci, cette dernière mouture plutôt, et il y en aura d’autres, m’a particulièrement étonnée. Le code est très propre, il a fonctionné tout de suite, il n’y a pas un seul bug, et cerise sur le gâteau, je lui ai demandé quelque chose en français, et il m’a écrit Joyeux Noël sur le sapin de Noël, ce qui est tout simplement exceptionnel pour une intelligence artificielle. Quasiment aucune des intelligences que j’ai utilisées jusqu’alors n’est capable d’écrire correctement un texte en français.

J’ajoute ici la réflexion de Gemini 3 PRO, puisqu’on peut voir la façon dont il réfléchit avant de produire le résultat:

Analyse des exigences
Je me concentre actuellement sur l’analyse de la demande de l’utilisateur pour le programme AutoLISP de sapin de Noël. J’ai identifié les aspects clés : la couleur, les ornements (boules) et les cadeaux doivent être intégrés de manière harmonieuse dans la conception de l’arbre. L’objectif est de garantir un rendu visuellement attrayant.


Définition du plan de mise en œuvre
Je priorise désormais les détails de l’implémentation. Le public cible, composé d’utilisateurs d’AutoCAD®, nécessite un code AutoLISP clair et bien commenté. Les commandes standard comme entmake sont préférables. Les fonctionnalités principales incluent la structure de l’arbre, les ornements (cercles), les cadeaux (carrés/rectangles), ainsi qu’une étoile optionnelle. L’esthétique reposera sur des couleurs en couches pour une ambiance festive. Je prévois d’utiliser des triangles ou des trapèzes empilés pour la forme de l’arbre, entmake pour les ornements, et une réflexion sur le placement des cadeaux sur les branches ou à la base.


Révision du placement des cadeaux
J’ai revu le placement des cadeaux. Initialement, je penchais pour la solution classique des « cadeaux sous le sapin », mais la consigne est explicite : les cadeaux doivent être sur les branches. Je vais les interpréter comme des décorations suspendues ou posées sur les branches, en veillant à ce qu’ils soient distincts et esthétiques. Pour améliorer l’apparence, je placerai certains cadeaux à la base et suspendrai des ornements sur l’arbre.


Développement de la structure
Le projet évolue : j’ai finalisé les éléments de base du programme. Je me concentre sur la désactivation de cmdecho et osnap pour éviter les interférences. J’ai défini des calques pour le feuillage, le bois, les ornements et les cadeaux. Mon plan :

  1. Commencer par le tronc (un rectangle simple),
  2. Ajouter une série de triangles en boucle pour les feuilles, en réduisant la taille des étages supérieurs,
  3. Couronner l’arbre d’une étoile.
    Ensuite, j’intégrerai les ornements et les cadeaux, puis les aspects décoratifs. J’utiliserai des motifs de hachures et des couleurs, et ajouterai un texte « Joyeux Noël ».

Planification de l’implémentation
J’ai structuré mentalement le code et affiné ma stratégie. La fonction c:SapinNoel pilotera le programme, avec des variables comme pt, width et height pour le paramétrage. Je sauvegarderai les variables système avant de créer les calques (feuillage, tronc, décorations, cadeaux).
Côté géométrie :

  • Rectangles et hachures pour le tronc,
  • Boucles pour le feuillage,
  • Carrés aléatoires à la base pour les cadeaux.
    Les ornements seront suspendus aux sommets et à l’intérieur des triangles pour les mettre en valeur. L’étoile sera placée au sommet, comme prévu. Il est temps de construire la géométrie.

Optimisation pour la clarté
Je me concentre sur la lisibilité et privilégie la fonction command, bien qu’entmake soit plus rapide. Mon objectif est de rendre le code accessible aux débutants et facile à modifier. Pour des designs uniques à chaque exécution, j’intègre un générateur linéaire congruentiel personnalisé, initialisé avec la date du jour. J’ai également défini les fonctions principales :

  • c:JoyeuxNoel,
  • Un générateur de nombres aléatoires,
  • Draw Branch Tier (Dessiner un étage de branche),
  • Draw Ornament (Dessiner un ornement),
  • Draw Gift (Dessiner un cadeau).

Affinement de la structure
J’implémente désormais la logique principale du programme, en suivant ces étapes :

  1. Demander un point à l’utilisateur,
  2. Dessiner le tronc,
  3. Créer les couches de feuilles,
  4. Ajouter ornements et cadeaux,
  5. Dessiner l’étoile,
  6. Insérer le texte.
    Je travaille sur la gestion des erreurs et l’autonomie du code. Pour éviter les problèmes de hachures, j’utilise _C (fermeture) dans Pline et le motif _Solid. Je garantis la compatibilité avec des couleurs indexées. Le code prend forme : il ne reste plus qu’à finaliser la sortie !

Intégration des détails décoratifs
Je traite actuellement la demande spécifique des cadeaux sur les branches. Pour cela, la boucle de décoration placera aléatoirement des cercles (boules) ou des carrés (cadeaux) dans le feuillage, afin de répondre à la consigne. Le programme guidera aussi les nouveaux utilisateurs.

Et je retombe sur une discussion en anglais qui avait lieu à l’époque sur un fameux challenge Sapin Noël, discussion qui vient compléter ce que je vous présentais ci-dessus: