CoddyRun
Blog

Articles & Actualités

Les publications CoddyRun : nouveautés du logiciel, astuces de pseudo-code, retours d'expérience et actualités de l'environnement pédagogique.

69 publications

Une horloge pixel‑art en temps réel
Article

Une horloge pixel‑art en temps réel

Quand le code devient design

Lire l'articleReplier l'article

Dans ce projet, l’heure n’est plus simplement affichée : elle est reconstruite, stylisée et animée sous forme de pixel‑art. Chaque chiffre, chaque deux‑points, chaque changement de seconde devient un petit événement graphique.

Le résultat est une horloge numérique rétro‑moderne, colorée, vivante et entièrement générée par code.

Une police bitmap 5×7 conçue pour le temps

Au cœur du système se trouve une police bitmap 5×7, spécialement définie pour les chiffres de 0 à 9 et le symbole « : ».
Chaque caractère est décrit comme un motif de 35 bits, représentant des pixels allumés ou éteints. Cette approche minimaliste rappelle les écrans LED des années 80, tout en offrant une grande liberté de stylisation.

Cette police n’est pas importée : elle est codée à la main, ligne par ligne, pixel par pixel. Une manière de maîtriser totalement le rendu visuel.

Une palette de couleurs vibrante

Pour donner du rythme à l’affichage, chaque position de l’heure adopte une couleur différente.
La palette utilisée mélange :

  • rose vif
  • orange brûlant
  • jaune lumineux
  • violet profond
  • bleu électrique
  • vert turquoise
  • rose framboise

Ces couleurs alternent à chaque caractère, créant une horloge dynamique, presque musicale dans sa composition visuelle.

Une toile pensée pour HH:MM:SS

L’horloge affiche huit caractères : deux chiffres pour les heures, deux pour les minutes, deux pour les secondes, séparés par deux « : ».
La toile est dimensionnée pour accueillir ces huit blocs pixelisés, avec des marges harmonieuses et un fond sombre (#161B26) qui met en valeur les couleurs éclatantes.

Un rafraîchissement en temps réel

Le programme fonctionne en boucle continue :

  • Il récupère l’heure courante.
  • Il formate les valeurs pour garantir l’affichage sur deux chiffres.
  • Il efface la toile.
  • Il redessine chaque caractère pixel par pixel.
  • Il affiche la bannière.
  • Il attend un court instant avant de recommencer.

Ce cycle rapide donne l’impression d’une horloge animée, fluide, qui vit au rythme des secondes.

Un dessin pixel par pixel

Pour chaque caractère :

  • le programme lit son motif bitmap,
  • parcourt les 7 lignes et 5 colonnes,
  • dessine un petit rectangle coloré pour chaque pixel actif,
  • avance le curseur pour placer le caractère suivant.

Cette construction minutieuse donne un rendu propre, net, parfaitement lisible, tout en conservant le charme du pixel‑art.

Une horloge rétro‑moderne, expressive et entièrement générée par code Ce projet combine :

  • une police bitmap artisanale,
  • une palette contemporaine,
  • un rafraîchissement en temps réel,
  • un rendu pixelisé élégant.

Le résultat est une horloge unique, à la fois technique et artistique, qui transforme le temps en une expérience visuelle.

Programme :

@ Police bitmap 5x7 (chiffres 0 à 9 et deux - points)
police est un tableau
// Index 0 à 9 : chiffres '0' à '9', Index 10 : ':' (35 caractères chacun)
police ajoute '01110100111010110101101011100101110' // 0 (index 0)
police ajoute '00100011000010000100001000010001110' // 1 (index 1)
police ajoute '01110100010000100110010001000011111' // 2 (index 2)
police ajoute '11111000100010000010000011000101110' // 3 (index 3)
police ajoute '00010001100101010010111110001000010' // 4 (index 4)
police ajoute '11111100001111000001000011000101110' // 5 (index 5)
police ajoute '00110010001000011110100011000101110' // 6 (index 6)
police ajoute '11111000010001000100010000100001000' // 7 (index 7)
police ajoute '01110100011000101110100011000101110' // 8 (index 8)
police ajoute '01110100011000101111000010001001100' // 9 (index 9)
police ajoute '00000001100011000000001100011000000' // : (index 10)

@ Réglages et Palette
taille_case, marge_x, marge_y, espacement est un nombre
taille_case vaut 12
marge_x vaut 20
marge_y vaut 25
espacement vaut 1

couleurs est un tableau
couleurs vaut [#FF006E, #FB5607, #FFBE0B, #8338EC, #3A86FF, #06D6A0, #EF476F]

@ toile dimensionnée pour le format HH:MM:SS (8 caractères)
nb, larg, haut est un nombre
nb vaut 8
larg vaut marge_x * 2 + nb * (5 + espacement) * taille_case
haut vaut marge_y * 2 + 7 * taille_case
larg vaut limiter(larg, 1, 1000)

Banniere est une toile
dimension(Banniere, larg, haut)

@ processus de rafraîchissement temps réel
processus Horloge()
  tant que vrai
    // Récupération de l'heure courante via maintenant()
    maint est une heure
    maint vaut maintenant()

    h_num, m_num, s_num est un nombre
    h_num vaut heure_de(maint)
    m_num vaut minute_de(maint)
    s_num vaut seconde_de(maint)

    // Formate en 2 chiffres (01, 02, etc.)
    str_h, str_m, str_s est un texte
    si h_num < 10 alors
      str_h vaut "0" + convertir_texte(h_num)
    sinon
      str_h vaut convertir_texte(h_num)
    fin si

    si m_num < 10 alors
      str_m vaut "0" + convertir_texte(m_num)
    sinon
      str_m vaut convertir_texte(m_num)
    fin si

    si s_num < 10 alors
      str_s vaut "0" + convertir_texte(s_num)
    sinon
      str_s vaut convertir_texte(s_num)
    fin si

    texte_heure est un texte
    texte_heure vaut str_h + ":" + str_m + ":" + str_s

    // Effacement et redessin
    effacer(Banniere)
    remplir(Banniere, #161B26)

    curseur_x est un nombre
    curseur_x vaut marge_x

    pour n de 1 à nb
      lettre est un texte
      lettre vaut copier(texte_heure, n, 1)

      // Indexation directe sans alphabet
      idx est un nombre
      si lettre = ":" alors
        idx vaut 10
      sinon
        idx vaut convertir_nombre(lettre)
      fin si

      g est un texte
      g vaut police[idx]

      ic, pos, px, py est un nombre
      bit, coul est un texte

      ic vaut (n - 1) mod longueur(couleurs)
      coul vaut couleurs[ic]

      pour li de 0 à 6
        pour co de 0 à 4
          pos vaut li * 5 + co + 1
          bit vaut copier(g, pos, 1)
          si bit = '1' alors
            px vaut curseur_x + co * taille_case
            py vaut marge_y + li * taille_case
            rectangle(Banniere, px, py, taille_case - 2, taille_case - 2, coul)
          fin si
        fin pour
      fin pour

      curseur_x ajoute (5 + espacement) * taille_case
    fin pour

    affiche Banniere
    pause 250
  fin tant que
fin processus

@ Démarrage de l'horloge
Horloge()
Pas encore noté
Un programme qui transforme un mot en bannière pixel‑art
Article

Bannière pixel‑art

Un programme qui transforme un mot en bannière pixel‑art

Lire l'articleReplier l'article

Ce projet propose une idée aussi simple qu’élégante : demander à l’utilisateur un mot, puis le transformer en une bannière graphique composée de lettres pixelisées.

Chaque caractère est dessiné à partir d’une police bitmap artisanale, et mis en couleur grâce à une palette vive et moderne. Le résultat est une image au style rétro, rappelant les premiers écrans numériques.

Une police bitmap faite à la main

Le cœur du programme repose sur une police 5×7 entièrement codée manuellement.
Chaque lettre, chaque chiffre et même l’espace sont décrits sous forme de motifs composés de 0 et de 1. Ces motifs représentent des pixels : les 1 sont dessinés, les 0 restent vides. Cette approche donne un rendu minimaliste, très proche du pixel‑art classique.

Une palette de couleurs vibrante

Pour éviter la monotonie, le programme utilise une série de couleurs éclatantes. Chaque lettre reçoit une couleur différente, créant un rythme visuel dynamique. Les teintes choisies — rose vif, orange brûlant, jaune lumineux, violet profond, bleu électrique, vert turquoise, rose framboise — apportent une énergie moderne à l’esthétique rétro du pixel‑art.

Une bannière construite lettre par lettre

Une fois le mot saisi par l’utilisateur, le programme parcourt chaque caractère :

  • il identifie son motif dans la police bitmap,
  • il choisit une couleur dans la palette,
  • il dessine les pixels un par un sous forme de petits rectangles,
  • puis il avance pour placer la lettre suivante.

Cette construction progressive donne l’impression que la bannière se tisse sous les yeux, comme un textile numérique.

Un fond sombre pour un contraste parfait

La bannière est posée sur un fond bleu‑noir profond. Ce choix renforce le contraste avec les couleurs vives des lettres et met en valeur le style pixelisé. Le résultat est une image nette, lisible et visuellement percutante.

Un projet simple, créatif et rétro‑moderne

Ce programme est un bel exemple de création graphique générée par code.
Il combine :

  • une police bitmap artisanale,
  • une palette contemporaine,
  • une logique de dessin pixel par pixel,
  • et une mise en forme élégante.

Le tout permet de transformer n’importe quel mot en une bannière unique, colorée et pleine de caractère.

Programme :

@ Demander le mot
saisie, mot est un texte
demande 'Quel mot veux-tu afficher ?' dans saisie
mot vaut majuscules(normaliser(saisie))

@ Alphabet et Police bitmap 5x7
alpha est un texte
alpha vaut 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 '

police est un tableau
// A à Z, 0 à 9, espace (chaque entrée = 35 caractères)
police ajoute '01110100011000111111100011000110001' // A
police ajoute '11110100011000111110100011000111110' // B
police ajoute '01111100001000010000100001000001111' // C
police ajoute '11110100011000110001100011000111110' // D
police ajoute '11111100001000011110100001000011111' // E
police ajoute '11111100001000011110100001000010000' // F
police ajoute '01111100001000010111100011000101111' // G
police ajoute '10001100011000111111100011000110001' // H
police ajoute '11111001000010000100001000010011111' // I
police ajoute '00111000100001000010100101001001100' // J
police ajoute '10001100101010011000101001001010001' // K
police ajoute '10000100001000010000100001000011111' // L
police ajoute '10001110111010110101100011000110001' // M
police ajoute '10001110011010110011100011000110001' // N
police ajoute '01110100011000110001100011000101110' // O
police ajoute '11110100011000111110100001000010000' // P
police ajoute '01110100011000110001101011001001101' // Q
police ajoute '11110100011000111110101001001010001' // R
police ajoute '01111100001000001110000010000111110' // S
police ajoute '11111001000010000100001000010000100' // T
police ajoute '10001100011000110001100011000101110' // U
police ajoute '10001100011000110001100010101000100' // V
police ajoute '10001100011000110101101011101110001' // W
police ajoute '10001100010101000100010101000110001' // X
police ajoute '10001100010101000100001000010000100' // Y
police ajoute '11111000010001000100010001000011111' // Z
police ajoute '01110100111010110101101011100101110' // 0
police ajoute '00100011000010000100001000010001110' // 1
police ajoute '01110100010000100110010001000011111' // 2
police ajoute '11111000100010000010000011000101110' // 3
police ajoute '00010001100101010010111110001000010' // 4
police ajoute '11111100001111000001000011000101110' // 5
police ajoute '00110010001000011110100011000101110' // 6
police ajoute '11111000010001000100010000100001000' // 7
police ajoute '01110100011000101110100011000101110' // 8
police ajoute '01110100011000101111000010001001100' // 9
police ajoute '00000000000000000000000000000000000' // espace

@ Réglages et Palette
taille_case, marge_x, marge_y, espacement est un nombre
taille_case vaut 12
marge_x vaut 20
marge_y vaut 25
espacement vaut 1

couleurs est un tableau
// Couleurs en hexadécimal sans guillemets
couleurs vaut [#FF006E, #FB5607, #FFBE0B, #8338EC, #3A86FF, #06D6A0, #EF476F]

@ Toile dimensionnée selon la longueur du mot
nb, larg, haut est un nombre
nb vaut longueur(mot)
larg vaut marge_x * 2 + nb * (5 + espacement) * taille_case
haut vaut marge_y * 2 + 7 * taille_case

// Borne la largeur de la toile entre 1 et 1000 pixels maximum
larg vaut limiter(larg, 1, 1000)

Banniere est une toile
dimension(Banniere, larg, haut)
remplir(Banniere, #161B26)

@ Dessin lettre par lettre
curseur_x est un nombre
curseur_x vaut marge_x

pour n de 1 à nb
  lettre est un texte
  lettre vaut copier(mot, n, 1)
  
  // position() renvoie 1 pour 'A', donc on retire 1 pour avoir l'index du tableau (0)
  idx est un nombre
  idx vaut position(lettre, alpha) - 1
  
  // Si la lettre est inconnue (idx < 0), on utilise l'espace (dernier élément : index 36)
  si idx < 0 alors
    idx vaut 36
  fin si
  
  g est un texte
  g vaut police[idx]
  
  ic, pos, px, py est un nombre
  bit est un texte
  coul est un texte
  
  ic vaut (n - 1) mod longueur(couleurs)
  coul vaut couleurs[ic]
  
  pour li de 0 à 6
    pour co de 0 à 4
      pos vaut li * 5 + co + 1
      bit vaut copier(g, pos, 1)
      si bit = '1' alors
        px vaut curseur_x + co * taille_case
        py vaut marge_y + li * taille_case
        rectangle(Banniere, px, py, taille_case - 2, taille_case - 2, coul)
      fin si
    fin pour
  fin pour
  
  // Utilisation de ajoute pour incrémenter le curseur
  curseur_x ajoute (5 + espacement) * taille_case
fin pour

affiche Banniere
Pas encore noté
Version 3.4 en approche : Une mise à jour majeure de l’interpréteur
Article

Version 3.4 en approche

Une mise à jour majeure de l’interpréteur

Lire l'articleReplier l'article

La version 3.4 de l’interpréteur marque une avancée significative, tant sur le plan des fonctionnalités que de l’expérience utilisateur.

Cette mise à jour introduit de nouveaux mots-clés, enrichit les capacités graphiques et améliore l’interface pour offrir un environnement de développement plus fluide, plus puissant et plus moderne.

Prise en charge des couleurs hexadécimales avec transparence

L’interpréteur supporte désormais les couleurs hexadécimales au format #AARRGGBB, soit 8 chiffres, permettant de définir non seulement la couleur mais aussi son niveau de transparence (Alpha).

Exemple : #80FF0000 correspond à un rouge semi-transparent.

Cette amélioration ouvre la voie à des interfaces plus raffinées, des effets visuels avancés et une meilleure gestion des superpositions.

Nouveaux mots-clés

La version 3.4 introduit quatre mots-clés essentiels qui enrichissent la logique d’exécution et permettent de structurer des programmes plus dynamiques.

processus
Définit un bloc de code qui s’exécute en parallèle du programme principal.
Idéal pour gérer des tâches simultanées, des animations ou des opérations de fond.

pause
Suspend l’exécution pendant un nombre de millisecondes.

pause 1000 équivaut à une seconde d’attente.
Parfait pour temporiser des actions ou synchroniser des événements.

suspendre
Met un processus en pause.
Permet de contrôler finement l’exécution parallèle, notamment pour stopper temporairement une tâche.

reprendre
Relance un processus précédemment suspendu.
Complète le duo suspendre/reprendre pour une gestion précise des processus.

Nouvelle fonction intégrée

paramètre
Cette fonction permet d’enregistrer et de relire des paramètres persistants.
Elle est particulièrement utile pour :

  • mémoriser des préférences utilisateur,
  • conserver des états entre deux exécutions,
  • gérer des configurations internes.

Interface améliorée

La version 3.4 ne se contente pas d’ajouter des fonctionnalités : elle améliore aussi l’expérience visuelle et ergonomique.

Palette de couleurs optimisée
La palette a été revue pour offrir une sélection plus intuitive, plus cohérente et plus agréable à utiliser.

Suppression du mini-menu d’Edge

Le mini-menu qui apparaissait lors d’un double-clic sur la toile a été retiré.
Résultat : une interaction plus fluide, sans éléments parasites.

Conclusion

La mise à jour 3.4 apporte des améliorations majeures, tant sur le plan technique que visuel. Avec la gestion avancée des couleurs, les nouveaux mots-clés orientés vers l’exécution parallèle, la fonction paramètre et une interface plus propre, cette version renforce la puissance et la modernité de l’interpréteur.

Pas encore noté
Count War : l'art de créer un runner stratégique moderne
Article

Count War

L'art de créer un runner stratégique moderne

Lire l'articleReplier l'article

Créer un jeu comme Count War ne consiste pas seulement à faire avancer des personnages sur une route. C’est un mélange subtil de stratégie, rythme, anticipation, et mise en scène.

Voici comment on conçoit un Count War de A à Z, en se concentrant sur les idées, les mécaniques et la logique de conception.

Définir l’expérience de jeu

Un Count War repose sur une idée simple :
le joueur dirige une foule qui doit survivre à une série d’épreuves pour atteindre un boss final.

L’expérience doit être :

  • rapide
  • lisible
  • addictive
  • basée sur des choix instantanés

Le joueur ne contrôle pas tout : il influence la trajectoire, mais la foule avance seule.
C’est ce mélange entre automatisme et décision immédiate qui crée la tension.

Concevoir la progression du niveau

Un Count War est structuré comme un parcours d’obstacles.
Pour le construire, on imagine une succession d’éléments :

Les portails
Ils modifient la taille de la foule.
Ce sont les moments stratégiques : le joueur doit choisir le bon côté.

Les obstacles
Ils punissent les mauvais choix ou les erreurs de trajectoire.

Les ennemis
Ils déclenchent des combats automatiques qui réduisent la foule.

Le boss final
Il représente l’objectif ultime : survivre jusqu’à lui avec assez de soldats.

La clé est de rythmer le niveau :
un portail ? un obstacle ? un ennemi ? un portail ? un obstacle…
Le joueur doit sentir une montée en tension.

Ajouter de la variété grâce au hasard

Pour éviter que chaque partie soit identique, on introduit :

  • des valeurs différentes sur les portails
  • des positions aléatoires des obstacles
  • des ennemis plus ou moins résistants
  • des mini-boss occasionnels

Le hasard doit être contrôlé :
il surprend le joueur, mais ne doit jamais rendre la partie injuste.

Imaginer les mécaniques de combat

Dans un Count War, le combat est automatique.
Le joueur ne frappe pas : il observe la confrontation.

Combat contre un ennemi simple
La foule perd un certain nombre d’unités par seconde.
L’ennemi aussi.
Le combat s’arrête quand l’un des deux tombe à zéro.

Combat contre un boss
Même principe, mais avec :

  • une barre de vie visible
  • un rythme de combat plus lent
  • une mise en scène plus forte

Le joueur doit sentir que c’est le moment décisif.

Penser les interactions avec les portails

Les portails sont le cœur du gameplay.
Ils doivent être :

  • lisibles
  • rapides à comprendre
  • visuellement distincts

Chaque portail représente une opération :

  • ajouter
  • retirer
  • multiplier
  • diviser

Le joueur doit pouvoir anticiper l’effet en un coup d’œil.
C’est là que se joue la stratégie : choisir le bon côté pour maximiser la survie.

Créer une illusion de profondeur

Même sans code, on peut décrire le principe :

  • les objets proches sont grands
  • les objets éloignés sont petits
  • leur position verticale dépend de leur distance
  • leur largeur diminue avec la profondeur

Cette perspective donne l’impression que la foule avance dans un tunnel ou une route en 3D.

Le décor doit être simple mais dynamique :

  • lignes de route
  • ombres
  • silhouettes
  • éléments répétitifs pour donner du mouvement

Définir les contrôles du joueur

Un Count War doit rester accessible :

  • un mouvement à gauche
  • un mouvement à droite
  • éventuellement une touche pour abandonner

Le joueur doit pouvoir réagir vite, sans réfléchir.
La simplicité des contrôles renforce la tension :
tout se joue en une fraction de seconde.

Construire une interface claire

L’interface doit afficher :

  • le nombre de soldats
  • la progression dans le niveau
  • le niveau actuel
  • le record du joueur
  • les barres de vie en combat

Elle doit être lisible même en plein mouvement.

Soigner la fin de partie

Un Count War doit offrir une conclusion nette :

Victoire
Le boss est vaincu ? célébration, couleurs chaudes, message clair.

Défaite
La foule tombe à zéro ? ton sombre, message fataliste.

Abandon
Le joueur quitte volontairement ? message neutre.

On peut aussi ajouter :

  • un record
  • un classement
  • une récompense visuelle

Conclusion : développer un Count War, c’est créer un parcours stratégique rythmé

Pour concevoir un Count War, il faut penser :

  • comme un designer (rythme du niveau)
  • comme un stratège (portails et choix rapides)
  • comme un metteur en scène (boss, combats, perspective)

Ce type de jeu fonctionne parce qu’il combine :

  • simplicité des contrôles
  • profondeur des choix
  • satisfaction visuelle
  • progression rapide
5,0 / 5 (1 avis)
Les couleurs hexadécimales gèrent désormais la transparence
Nouveauté

Les couleurs hexadécimales gèrent désormais la transparence

Disponible dans la prochaine version de CoddyRun v3.4

Lire l'articleReplier l'article

CoddyRun accepte maintenant la notation hexadécimale à 8 chiffres : #RRGGBBAA.

Les deux derniers caractères représentent le canal alpha, exactement comme en CSS :

  • 00 : totalement transparent
  • FF : totalement opaque

La couleur peut provenir d’un littéral, d’une variable ou d’un calcul, sans aucune modification de syntaxe.

Pourquoi c’est utile

L’alpha permet de hiérarchiser visuellement un rendu sans multiplier les teintes.
C’est aussi un excellent moyen de manipuler concrètement la base 16 :
quatre informations encodées dans une seule chaîne, deux chiffres par canal.

Cette notation est déjà utilisée en CSS et dans la majorité des outils graphiques.
L’intégrer dans CoddyRun rend l'apprentissage plus cohérent et plus proche des standards professionnels.

Compatibilité

Cette évolution est entièrement additive :

  • Les scripts en #RRGGBB fonctionnent exactement comme avant.
  • #0 rétablit toujours la valeur par défaut.
  • Les codes ASCII courts (#65) restent inchangés.
  • Les longueurs invalides sont toujours rejetées, avec un message d’erreur unifié.

Aucun script existant n’a besoin d’être modifié.

Pas encore noté
Make7 Puzzle Hexa : Analyse technique complète d’un puzzle hexagonal à fusions en chaîne
Article

Make7 Puzzle Hexa

Analyse technique complète d’un puzzle hexagonal à fusions en chaîne

Lire l'articleReplier l'article

Make7 est un jeu de puzzle basé sur un pavage hexagonal irrégulier, où le joueur place des pièces composées de deux blocs. Le programme repose sur une architecture claire : géométrie hexagonale, système de tirage probabiliste, algorithme de propagation, gestion d’état, et pipeline de rendu graphique.

Voici une analyse détaillée de sa conception.

Structure du plateau : un hexagone irrégulier mais régulier dans sa logique

Le plateau est défini par :

  • larg = [3, 4, 5, 4, 3]
  • NBRANG = 4

Chaque rangée possède un nombre différent d’alvéoles, ce qui crée un hexagone parfait.
Le programme calcule la position de chaque alvéole via deux fonctions clés :

abscisseDe(rang, col, nbCases)

Calcule la position horizontale en centrant chaque rangée sur CENX.

ordonneeDe(rang)

Décale verticalement chaque rangée selon PASY.

Ces deux fonctions sont la base de toute la géométrie du jeu :
elles permettent de dessiner, détecter les clics, trouver les voisins et propager les fusions.

Tirage des pièces : distribution pondérée

Le tirage utilise une distribution volontairement biaisée :

  • 1 sort 40 % du temps
  • 2 sort 32 %
  • 3 sort 18 %
  • 4 sort 10 %

Une pièce sur quatre contient deux fois le même numéro.

Ce système est reproduit pour la pièce suivante (sA, sB), ce qui crée un flux constant de pièces faibles, mais avec des opportunités de monter en puissance.

Rendu graphique : pipeline de dessin

Le jeu utilise une série de primitives graphiques :

  • dessinerHexa pour les hexagones pleins
  • dessinerCaseVide pour les alvéoles libres
  • dessinerBloc pour les blocs numérotés
  • dessinerPiece pour la pièce en main
  • dessinerPoubelle pour l’UI
  • dessinerPieceOr pour les pièces (monnaie)

Chaque bloc possède :

  • une couleur claire (couleurDeBloc)
  • une couleur sombre (couleurSombreDeBloc)
  • un numéro ou un rendu spécial (bombe)

Le rendu est propre, lisible, et entièrement vectoriel.

Placement des pièces : gestion des 6 directions hexagonales

La pièce comporte deux blocs.
Le premier se place sur l’alvéole cliquée, le second dans une direction parmi six orientations :

0 : droite
1 : bas-droite
2 : bas-gauche
3 : gauche
4 : haut-gauche
5 : haut-droite

Le calcul du voisin (l2, c2) dépend :

  • de la direction,
  • de la longueur de la rangée d’arrivée,
  • du fait que les rangées plus longues commencent plus à gauche.

Cette partie du code est l’une des plus techniques : elle gère un pavage hexagonal irrégulier sans jamais perdre la cohérence géométrique.

Algorithme de fusion : propagation hexagonale

Une fois la pièce posée, le programme recherche des groupes de blocs identiques.

Étape 1 : marquage
Un tableau parallèle marque[][] est utilisé pour marquer les blocs connectés.

Étape 2 : propagation
Pour chaque bloc marqué, le programme teste les six voisins, en recalculant les décalages selon la géométrie du plateau.

Étape 3 : fusion
Si un groupe contient = 3 blocs :

les blocs disparaissent,
un bloc supérieur apparaît à un emplacement choisi,

le score augmente selon :
val × nbGroupe × 10 × (chaine + 1),

des pièces sont ajoutées.

Cas spéciaux
Trois 7 ? une BOMBE

Trois bombes ? explosion totale du plateau
? tous les blocs sont supprimés
? gain massif
? reset des coordonnées de fusion

Réactions en chaîne
Le programme relance la recherche tant qu’une fusion est possible.
Cela permet des cascades spectaculaires.

Détection de fin de partie

Après chaque pose, le programme vérifie s’il reste au moins deux alvéoles voisines libres.

Il teste chaque alvéole vide, puis ses six voisins.
Si aucune paire libre n’existe :

  • finPartie = vrai
  • affichage de l’écran de fin
  • mise à jour du record

Gestion de l’état du jeu

Le jeu maintient un ensemble de variables globales :

  • plateau[][] : état du plateau
  • marque[][] : marquage pour les fusions
  • valA, valB : pièce en main
  • sA, sB : pièce suivante
  • orient : orientation de la pièce
  • pieces : monnaie
  • score, record
  • meilleurBloc : plus haut bloc obtenu
  • derLig, derCol : dernière pose (pour fusion)
  • finPartie, aide : états d’interface

Cette structure est simple mais efficace :

  • elle permet de gérer le jeu sans objets complexes ni classes.

Conclusion

Make7 est un excellent exemple de jeu de puzzle hexagonal :

  • géométrie maîtrisée,
  • algorithme de propagation robuste,
  • gestion d’état claire,
  • interface vectorielle propre,
  • système de fusion riche,
  • réactions en chaîne,
  • mécaniques spéciales (bombes, explosion totale).

Le code est dense mais bien structuré, et démontre une compréhension fine des pavages hexagonaux et des mécaniques de puzzle modernes.

Programme :

@ CONFIGURATION
graph est une toile
dimension(graph, 400, 550)

NHEX est un nombre
NHEX vaut 2
NBRANG est un nombre
NBRANG vaut 4

// Géométrie d un hexagone à pointe en haut
RAY est un nombre
DEMIL est un nombre
PASX est un nombre
PASY est un nombre
CENX est un nombre
CENY est un nombre
RAY vaut 38
DEMIL vaut 33
PASX vaut 66
PASY vaut 57
CENX vaut 200
CENY vaut 216

COUT_POUBELLE est un nombre
COUT_POUBELLE vaut 10

// 8 est la bombe : trois bombes réunies font sauter tout le plateau
BOMBE est un nombre
BOMBE vaut 8

score est un nombre
score vaut 0
record est un nombre
record vaut 0
pieces est un nombre
pieces vaut 20
meilleurBloc est un nombre
meilleurBloc vaut 1

// La pièce en main : deux blocs et une direction de 0 à 5
valA est un nombre
valB est un nombre
sA est un nombre
sB est un nombre
orient est un nombre
orient vaut 0

derLig est un nombre
derCol est un nombre
der2Lig est un nombre
der2Col est un nombre
derLig vaut - 1
derCol vaut - 1
der2Lig vaut - 1
der2Col vaut - 1

finPartie est un booléen
finPartie vaut faux
aide est un booléen
aide vaut faux

message est un texte
message vaut "Clique la pièce pour la tourner, une alvéole pour la poser"

@ LE PLATEAU EN NID D ABEILLE
// larg[i] donne le nombre d alvéoles de la rangée i.
// Les rangées n ont pas toutes la même longueur : c est ce qui
// donne au plateau sa forme hexagonale.
larg est un tableau
plateau est un tableau
marque est un tableau
larg ajoute 3
larg ajoute 4
larg ajoute 5
larg ajoute 4
larg ajoute 3
pour i de 0 à NBRANG
    ligG est un tableau
    ligM est un tableau
    pour j de 0 à larg[i] - 1
        ligG ajoute 0
        ligM ajoute faux
    fin pour
    plateau ajoute ligG
    marque ajoute ligM
fin pour

@ TIRAGE DES PIÈCES
// Les petits numéros sortent bien plus souvent que les grands,
// et une pièce sur quatre porte deux fois le même numéro.
tirage est un nombre
tirage vaut hasard(1, 100)
si tirage <= 40 alors
    valA vaut 1
sinon si tirage <= 72 alors
    valA vaut 2
sinon si tirage <= 90 alors
    valA vaut 3
sinon
    valA vaut 4
fin si
si hasard(1, 100) <= 25 alors
    valB vaut valA
sinon
    tirage vaut hasard(1, 100)
    si tirage <= 40 alors
        valB vaut 1
    sinon si tirage <= 72 alors
        valB vaut 2
    sinon si tirage <= 90 alors
        valB vaut 3
    sinon
        valB vaut 4
    fin si
fin si

tirage vaut hasard(1, 100)
si tirage <= 40 alors
    sA vaut 1
sinon si tirage <= 72 alors
    sA vaut 2
sinon si tirage <= 90 alors
    sA vaut 3
sinon
    sA vaut 4
fin si
si hasard(1, 100) <= 25 alors
    sB vaut sA
sinon
    tirage vaut hasard(1, 100)
    si tirage <= 40 alors
        sB vaut 1
    sinon si tirage <= 72 alors
        sB vaut 2
    sinon si tirage <= 90 alors
        sB vaut 3
    sinon
        sB vaut 4
    fin si
fin si

@ LES COULEURS DES BLOCS
fonction couleurDeBloc(val)
    si val = 1 alors
        retourne #A855F7
    fin si
    si val = 2 alors
        retourne #FF8A2B
    fin si
    si val = 3 alors
        retourne #FF3B6B
    fin si
    si val = 4 alors
        retourne #2D9CFF
    fin si
    si val = 5 alors
        retourne #12C7B0
    fin si
    si val = 6 alors
        retourne #FFC93C
    fin si
    si val = 7 alors
        retourne #7CE04A
    fin si
    retourne #4B4C52
fin fonction

fonction couleurSombreDeBloc(val)
    si val = 1 alors
        retourne #7E3BC4
    fin si
    si val = 2 alors
        retourne #CC6A15
    fin si
    si val = 3 alors
        retourne #C92B52
    fin si
    si val = 4 alors
        retourne #1B76CC
    fin si
    si val = 5 alors
        retourne #0C9285
    fin si
    si val = 6 alors
        retourne #CC9A18
    fin si
    si val = 7 alors
        retourne #5AA832
    fin si
    retourne #2E2F34
fin fonction

@ L ABSCISSE D UNE ALVÉOLE
// Chaque rangée est centrée sur CENX : sa première alvéole se
// décale donc de la moitié de sa longueur. C est cette formule,
// et elle seule, qui donne au plateau sa forme d hexagone.
fonction abscisseDe(rang, col, nbCases)
    retourne CENX - (nbCases - 1) * PASX / 2 + col * PASX
fin fonction

fonction ordonneeDe(rang)
    retourne CENY + (rang - NHEX) * PASY
fin fonction

@ UN HEXAGONE PLEIN
procédure dessinerHexa(t, cx, cy, dl, ha, coul)
    p est un tableau
    p ajoute cx + dl
    p ajoute cy - ha / 2
    p ajoute cx + dl
    p ajoute cy + ha / 2
    p ajoute cx
    p ajoute cy + ha
    p ajoute cx - dl
    p ajoute cy + ha / 2
    p ajoute cx - dl
    p ajoute cy - ha / 2
    p ajoute cx
    p ajoute cy - ha
    polygone(t, p, coul)
fin procédure

@ UNE ALVÉOLE VIDE
procédure dessinerCaseVide(t, cx, cy)
    appelle dessinerHexa(t, cx, cy, DEMIL - 4, RAY - 4, #3A3B43)
fin procédure

@ UN BLOC NUMÉROTÉ
// Un hexagone sombre décalé vers le bas sert de socle : c est ce
// qui donne l épaisseur. Le numéro est écrit par-dessus.
procédure dessinerBloc(t, cx, cy, dl, ha, val, taillePolice)
    appelle dessinerHexa(t, cx, cy + 4, dl, ha, couleurSombreDeBloc(val))
    appelle dessinerHexa(t, cx, cy, dl, ha, couleurDeBloc(val))

    si val = BOMBE alors
        cercle(t, cx, cy + 2, ha * 55 / 100, #1A1B20)
        rectangle_arrondi(t, cx + 2, cy - ha * 75 / 100, 4, ha * 40 / 100, 2, #8A6A3A)
        cercle(t, cx + 5, cy - ha * 85 / 100, ha * 12 / 100, #FF9A2B)
        cercle(t, cx - ha * 20 / 100, cy - ha * 10 / 100, ha * 12 / 100, rgba(255, 255, 255, 0.5))
    sinon
        label(t, cx - taillePolice * 30 / 100, cy + taillePolice * 35 / 100, "" + val, #1A1B20, taillePolice)
    fin si
fin procédure

@ LA PIÈCE À DEUX BLOCS
// En pixels, les six directions ont toujours le même décalage,
// quelle que soit la rangée.
procédure dessinerPiece(t, cx, cy, dl, ha, v1, v2, dir, taillePolice)
    // JEU : quelques pixels d écart pour que les deux hexagones de
    // la pièce ne se touchent pas et restent distincts à l oeil.
    jeu est un nombre
    jeu vaut 5
    ex est un nombre
    ey est un nombre
    si dir = 0 alors
        ex vaut dl * 2 + jeu
        ey vaut 0
    sinon si dir = 1 alors
        ex vaut dl + jeu / 2
        ey vaut ha * 3 / 2 + jeu
    sinon si dir = 2 alors
        ex vaut 0 - dl - jeu / 2
        ey vaut ha * 3 / 2 + jeu
    sinon si dir = 3 alors
        ex vaut 0 - dl * 2 - jeu
        ey vaut 0
    sinon si dir = 4 alors
        ex vaut 0 - dl - jeu / 2
        ey vaut 0 - ha * 3 / 2 - jeu
    sinon
        ex vaut dl + jeu / 2
        ey vaut 0 - ha * 3 / 2 - jeu
    fin si
    appelle dessinerBloc(t, cx, cy, dl, ha, v1, taillePolice)
    appelle dessinerBloc(t, cx + ex, cy + ey, dl, ha, v2, taillePolice)
fin procédure

@ UNE PIÈCE D OR
procédure dessinerPieceOr(t, cx, cy, r)
    cercle(t, cx, cy + 1, r, #C99A19)
    cercle(t, cx, cy, r, #FFC93C)
    cercle(t, cx, cy, r * 3 / 5, #FFE9A8)
fin procédure

@ LA POUBELLE
procédure dessinerPoubelle(t, x, y, actif)
    fond est un texte
    cIcone est un texte
    si actif = vrai alors
        fond vaut #55565C
        cIcone vaut #E8EAF0
    sinon
        fond vaut #414248
        cIcone vaut #6B6D75
    fin si
    rectangle_arrondi(t, x, y + 2, 44, 48, 11, rgba(0, 0, 0, 0.3))
    rectangle_arrondi(t, x, y, 44, 48, 11, fond)
    rectangle_arrondi(t, x + 8, y + 11, 28, 4, 2, cIcone)
    rectangle_arrondi(t, x + 17, y + 7, 10, 4, 2, cIcone)
    rectangle_arrondi(t, x + 11, y + 17, 22, 23, 4, cIcone)
    rectangle(t, x + 17, y + 22, 3, 13, fond)
    rectangle(t, x + 25, y + 22, 3, 13, fond)
fin procédure

@ BOUCLE PRINCIPALE

tant que vrai

    // ================= AFFICHAGE =================
    effacer(graph)
    contour(graph, #0)
    remplir(graph, #2E2F34)

    // ---------- BANDEAU DU HAUT ----------
    rectangle_arrondi(graph, 12, 8, 376, 46, 12, #35363C)
    appelle dessinerPieceOr(graph, 32, 30, 10)
    label(graph, 46, 36, "" + pieces, #FFFFFF, 14)
    label(graph, 150, 38, "" + score, #FF9A2B, 22)
    label(graph, 252, 36, "??", #FFFFFF, 14)
    label(graph, 274, 37, "" + record, #FF9A2B, 17)

    rectangle_arrondi(graph, 346, 12, 32, 32, 9, #4B4C52)
    rectangle_arrondi(graph, 354, 18, 5, 19, 2, #E8EAF0)
    rectangle_arrondi(graph, 365, 18, 5, 19, 2, #E8EAF0)

    // ---------- LE NID D ABEILLE ----------
    rectangle_arrondi(graph, 12, 62, 376, 308, 16, #35363C)
    pour i de 0 à NBRANG
        pour j de 0 à larg[i] - 1
            cxk est un nombre
            cyk est un nombre
            cxk vaut abscisseDe(i, j, larg[i])
            cyk vaut ordonneeDe(i)
            si plateau[i][j] = 0 alors
                appelle dessinerCaseVide(graph, cxk, cyk)
            sinon
                appelle dessinerBloc(graph, cxk, cyk, DEMIL - 4, RAY - 4, plateau[i][j], 30)
            fin si
        fin pour
    fin pour

    label(graph, 20, 384, message, #8A8C94, 10)

    // ---------- ZONE DU BAS ----------
    rectangle_arrondi(graph, 12, 392, 376, 148, 14, #35363C)

    actifP est un booléen
    actifP vaut faux
    si pieces >= COUT_POUBELLE alors
        actifP vaut vrai
    fin si
    appelle dessinerPoubelle(graph, 26, 424, actifP)
    appelle dessinerPieceOr(graph, 32, 490, 7)
    label(graph, 44, 495, "" + COUT_POUBELLE, #B9BCC4, 11)

    // La pièce en main : un clic dessus la fait tourner
    label(graph, 112, 414, "clique la pièce pour la tourner", #6B6D75, 9)
    appelle dessinerPiece(graph, 178, 468, 20, 23, valA, valB, orient, 20)

    // La pièce suivante, en petit
    label(graph, 320, 424, "suiv.", #8A8C94, 9)
    appelle dessinerPiece(graph, 332, 456, 12, 13, sA, sB, 1, 12)

    // ---------- SURCOUCHES ----------
    si aide = vrai alors
        rectangle(graph, 0, 0, 400, 550, rgba(0, 0, 0, 0.72))
        rectangle_arrondi(graph, 26, 96, 348, 358, 16, #4B4C52)
        label(graph, 54, 142, "COMMENT JOUER", #FFFFFF, 20)
        label(graph, 54, 182, "Chaque pièce porte deux blocs numérotés.", #D6D8DE, 12)
        label(graph, 54, 204, "Clique la pièce en bas pour la faire tourner :", #D6D8DE, 12)
        label(graph, 54, 226, "un nid d abeille offre six directions.", #D6D8DE, 12)
        label(graph, 54, 262, "Clique une alvéole libre pour la poser. Le", #D6D8DE, 12)
        label(graph, 54, 284, "second bloc va dans la direction choisie.", #D6D8DE, 12)
        label(graph, 54, 320, "Trois blocs identiques qui se touchent", #D6D8DE, 12)
        label(graph, 54, 342, "fusionnent en un numéro supérieur.", #D6D8DE, 12)
        label(graph, 54, 378, "Trois 7 donnent une BOMBE.", #FF9A2B, 13)
        label(graph, 54, 400, "Trois bombes font sauter tout le plateau !", #FF3B6B, 13)
        label(graph, 54, 434, "Clique pour fermer", #FFC93C, 13)
    fin si

    si finPartie = vrai alors
        rectangle(graph, 0, 0, 400, 550, rgba(0, 0, 0, 0.78))
        rectangle_arrondi(graph, 40, 160, 320, 230, 16, #4B4C52)
        label(graph, 86, 212, "PLUS DE PLACE !", #FFFFFF, 24)
        label(graph, 86, 256, "Score : " + score, #FF9A2B, 20)
        label(graph, 86, 300, "Meilleur bloc :", #D6D8DE, 14)
        appelle dessinerBloc(graph, 276, 292, 20, 23, meilleurBloc, 20)
        label(graph, 86, 356, "Clique pour rejouer", #FFC93C, 15)
    fin si

    affiche graph

    // ================= LA SOURIS =================
    xc est un nombre
    yc est un nombre
    cliquer graph dans xc, yc

    si finPartie = vrai alors
        pour i de 0 à NBRANG
            pour j de 0 à larg[i] - 1
                plateau[i][j] vaut 0
            fin pour
        fin pour
        score vaut 0
        pieces vaut 20
        meilleurBloc vaut 1
        orient vaut 0
        derLig vaut - 1
        derCol vaut - 1
        finPartie vaut faux
        message vaut "Clique la pièce pour la tourner, une alvéole pour la poser"

    sinon si aide = vrai alors
        aide vaut faux

    sinon si xc >= 346 et xc <= 378 et yc >= 12 et yc <= 44 alors
        aide vaut vrai

    sinon si xc >= 110 et xc <= 258 et yc >= 400 et yc <= 536 alors
        // ---------- TOURNER LA PIÈCE ----------
        orient vaut orient + 1
        si orient > 5 alors
            orient vaut 0
        fin si
        message vaut "Direction " + (orient + 1) + " sur 6"

    sinon si xc >= 26 et xc <= 70 et yc >= 424 et yc <= 472 alors
        // ---------- JETER LA PIÈCE ----------
        si pieces >= COUT_POUBELLE alors
            pieces vaut pieces - COUT_POUBELLE
            valA vaut sA
            valB vaut sB
            tirage vaut hasard(1, 100)
            si tirage <= 40 alors
                sA vaut 1
            sinon si tirage <= 72 alors
                sA vaut 2
            sinon si tirage <= 90 alors
                sA vaut 3
            sinon
                sA vaut 4
            fin si
            si hasard(1, 100) <= 25 alors
                sB vaut sA
            sinon
                tirage vaut hasard(1, 100)
                si tirage <= 40 alors
                    sB vaut 1
                sinon si tirage <= 72 alors
                    sB vaut 2
                sinon si tirage <= 90 alors
                    sB vaut 3
                sinon
                    sB vaut 4
                fin si
            fin si
            message vaut "Pièce jetée : - " + COUT_POUBELLE + " pièces"
        sinon
            message vaut "Il te faut " + COUT_POUBELLE + " pièces pour jeter"
        fin si

    sinon si yc >= 62 et yc <= 370 alors
        // ---------- QUELLE ALVÉOLE A ÉTÉ CLIQUÉE ? ----------
        // On cherche le centre le plus proche : sur un pavage
        // hexagonal, c est exact et bien plus simple qu un calcul.
        l1 est un nombre
        c1 est un nombre
        l1 vaut - 1
        c1 vaut - 1
        meilleureDist est un nombre
        meilleureDist vaut 9999

        pour i de 0 à NBRANG
            pour j de 0 à larg[i] - 1
                dist est un nombre
                dist vaut hypotenuse(xc - abscisseDe(i, j, larg[i]), yc - ordonneeDe(i))
                si dist < meilleureDist alors
                    meilleureDist vaut dist
                    l1 vaut i
                    c1 vaut j
                fin si
            fin pour
        fin pour

        si meilleureDist > RAY alors
            message vaut "Clique bien au centre d une alvéole"
        sinon
            // ---------- L ALVÉOLE VOISINE, SELON LA DIRECTION ----------
            // Vers le bas, la rangée suivante est plus longue tant qu on
            // n a pas dépassé le milieu ; ensuite elle est plus courte.
            // Le décalage des colonnes en dépend.
            dLi est un nombre
            dCo est un nombre

            si orient = 0 alors
                dLi vaut 0
                dCo vaut 1
            sinon si orient = 3 alors
                dLi vaut 0
                dCo vaut 0 - 1
            sinon si orient = 1 ou orient = 2 alors
                // Vers le bas. Le décalage dépend de la longueur de la
                // rangée d arrivée, pas de sa position : une rangée plus
                // longue commence une demi-alvéole plus à gauche.
                dLi vaut 1
                plusLongue est un booléen
                plusLongue vaut faux
                si l1 + 1 <= NBRANG alors
                    si larg[l1 + 1] > larg[l1] alors
                        plusLongue vaut vrai
                    fin si
                fin si
                si orient = 1 alors
                    si plusLongue = vrai alors
                        dCo vaut 1
                    sinon
                        dCo vaut 0
                    fin si
                sinon
                    si plusLongue = vrai alors
                        dCo vaut 0
                    sinon
                        dCo vaut 0 - 1
                    fin si
                fin si
            sinon
                // Vers le haut, même raisonnement
                dLi vaut 0 - 1
                plusLongue vaut faux
                si l1 - 1 >= 0 alors
                    si larg[l1 - 1] > larg[l1] alors
                        plusLongue vaut vrai
                    fin si
                fin si
                si orient = 5 alors
                    si plusLongue = vrai alors
                        dCo vaut 1
                    sinon
                        dCo vaut 0
                    fin si
                sinon
                    si plusLongue = vrai alors
                        dCo vaut 0
                    sinon
                        dCo vaut 0 - 1
                    fin si
                fin si
            fin si

            l2 est un nombre
            c2 est un nombre
            l2 vaut l1 + dLi
            c2 vaut c1 + dCo

            horsPlateau est un booléen
            horsPlateau vaut faux
            si l2 < 0 ou l2 > NBRANG alors
                horsPlateau vaut vrai
            sinon si c2 < 0 ou c2 > larg[l2] - 1 alors
                horsPlateau vaut vrai
            fin si

            si horsPlateau = vrai alors
                message vaut "La pièce sort du plateau : tourne-la"
            sinon si plateau[l1][c1] <> 0 ou plateau[l2][c2] <> 0 alors
                message vaut "Il faut deux alvéoles libres côte à côte"
            sinon
                plateau[l1][c1] vaut valA
                plateau[l2][c2] vaut valB
                derLig vaut l1
                derCol vaut c1
                der2Lig vaut l2
                der2Col vaut c2
                message vaut "Pièce posée"

                valA vaut sA
                valB vaut sB
                tirage vaut hasard(1, 100)
                si tirage <= 40 alors
                    sA vaut 1
                sinon si tirage <= 72 alors
                    sA vaut 2
                sinon si tirage <= 90 alors
                    sA vaut 3
                sinon
                    sA vaut 4
                fin si
                si hasard(1, 100) <= 25 alors
                    sB vaut sA
                sinon
                    tirage vaut hasard(1, 100)
                    si tirage <= 40 alors
                        sB vaut 1
                    sinon si tirage <= 72 alors
                        sB vaut 2
                    sinon si tirage <= 90 alors
                        sB vaut 3
                    sinon
                        sB vaut 4
                    fin si
                fin si

                // ---------- FUSIONS EN CHAÎNE ----------
                chaine est un nombre
                chaine vaut 0
                encore est un booléen
                encore vaut vrai

                tant que encore = vrai
                    encore vaut faux

                    pour i de 0 à NBRANG
                        pour j de 0 à larg[i] - 1
                            si plateau[i][j] > 0 et encore = faux alors
                                val est un nombre
                                val vaut plateau[i][j]

                                pour r de 0 à NBRANG
                                    pour c de 0 à larg[r] - 1
                                        marque[r][c] vaut faux
                                    fin pour
                                fin pour
                                marque[i][j] vaut vrai

                                propage est un booléen
                                propage vaut vrai
                                tant que propage = vrai
                                    propage vaut faux
                                    pour r de 0 à NBRANG
                                        pour c de 0 à larg[r] - 1
                                            si marque[r][c] = vrai alors
                                                // Les six voisines de l alvéole
                                                pour d de 0 à 5
                                                    eLi est un nombre
                                                    eCo est un nombre
                                                    si d = 0 alors
                                                        eLi vaut 0
                                                        eCo vaut 1
                                                    sinon si d = 3 alors
                                                        eLi vaut 0
                                                        eCo vaut 0 - 1
                                                    sinon
                                                        // Bas ou haut : le décalage dépend de la
                                                        // longueur de la rangée voisine.
                                                        longVoisine est un booléen
                                                        longVoisine vaut faux
                                                        si d = 1 ou d = 2 alors
                                                            eLi vaut 1
                                                        sinon
                                                            eLi vaut 0 - 1
                                                        fin si
                                                        si r + eLi >= 0 et r + eLi <= NBRANG alors
                                                            si larg[r + eLi] > larg[r] alors
                                                                longVoisine vaut vrai
                                                            fin si
                                                        fin si
                                                        si d = 1 ou d = 5 alors
                                                            si longVoisine = vrai alors
                                                                eCo vaut 1
                                                            sinon
                                                                eCo vaut 0
                                                            fin si
                                                        sinon
                                                            si longVoisine = vrai alors
                                                                eCo vaut 0
                                                            sinon
                                                                eCo vaut 0 - 1
                                                            fin si
                                                        fin si
                                                    fin si

                                                    vr est un nombre
                                                    vc est un nombre
                                                    vr vaut r + eLi
                                                    vc vaut c + eCo
                                                    si vr >= 0 et vr <= NBRANG alors
                                                        si vc >= 0 et vc <= larg[vr] - 1 alors
                                                            si plateau[vr][vc] = val et marque[vr][vc] = faux alors
                                                                marque[vr][vc] vaut vrai
                                                                propage vaut vrai
                                                            fin si
                                                        fin si
                                                    fin si
                                                fin pour
                                            fin si
                                        fin pour
                                    fin pour
                                fin tant que

                                nbGroupe est un nombre
                                nbGroupe vaut 0
                                ligNaiss est un nombre
                                colNaiss est un nombre
                                ligNaiss vaut i
                                colNaiss vaut j
                                pour r de 0 à NBRANG
                                    pour c de 0 à larg[r] - 1
                                        si marque[r][c] = vrai alors
                                            nbGroupe ajoute 1
                                        fin si
                                    fin pour
                                fin pour

                                si der2Lig >= 0 alors
                                    si marque[der2Lig][der2Col] = vrai alors
                                        ligNaiss vaut der2Lig
                                        colNaiss vaut der2Col
                                    fin si
                                fin si
                                si derLig >= 0 alors
                                    si marque[derLig][derCol] = vrai alors
                                        ligNaiss vaut derLig
                                        colNaiss vaut derCol
                                    fin si
                                fin si

                                si nbGroupe >= 3 alors
                                    pour r de 0 à NBRANG
                                        pour c de 0 à larg[r] - 1
                                            si marque[r][c] = vrai alors
                                                plateau[r][c] vaut 0
                                            fin si
                                        fin pour
                                    fin pour

                                    gain est un nombre
                                    gain vaut val * nbGroupe * 10 * (chaine + 1)

                                    si val = BOMBE alors
                                        // ===== TROIS BOMBES : TOUT SAUTE =====
                                        nbSautes est un nombre
                                        nbSautes vaut 0
                                        pour r de 0 à NBRANG
                                            pour c de 0 à larg[r] - 1
                                                si plateau[r][c] > 0 alors
                                                    nbSautes ajoute 1
                                                    plateau[r][c] vaut 0
                                                fin si
                                            fin pour
                                        fin pour
                                        gain vaut 500 + nbSautes * 50
                                        pieces ajoute 10
                                        derLig vaut - 1
                                        derCol vaut - 1
                                        der2Lig vaut - 1
                                        der2Col vaut - 1
                                        message vaut "EXPLOSION TOTALE ! " + nbSautes + " blocs pulvérisés, + " + gain

                                    sinon si val = 7 alors
                                        // ===== TROIS 7 : UNE BOMBE NAÎT =====
                                        plateau[ligNaiss][colNaiss] vaut BOMBE
                                        derLig vaut ligNaiss
                                        derCol vaut colNaiss
                                        der2Lig vaut - 1
                                        der2Col vaut - 1
                                        meilleurBloc vaut BOMBE
                                        pieces ajoute 5
                                        gain vaut gain * 2
                                        message vaut "UNE BOMBE ! Réunis-en trois pour tout faire sauter"

                                    sinon
                                        plateau[ligNaiss][colNaiss] vaut val + 1
                                        derLig vaut ligNaiss
                                        derCol vaut colNaiss
                                        der2Lig vaut - 1
                                        der2Col vaut - 1
                                        si val + 1 > meilleurBloc alors
                                            meilleurBloc vaut val + 1
                                        fin si
                                        si val >= 4 alors
                                            pieces ajoute 3
                                        sinon
                                            pieces ajoute 1
                                        fin si
                                        si chaine > 0 alors
                                            message vaut "Réaction en chaîne x" + (chaine + 1) + " : + " + gain
                                        sinon
                                            message vaut "Fusion de " + nbGroupe + " blocs : + " + gain
                                        fin si
                                    fin si

                                    score ajoute gain
                                    chaine ajoute 1
                                    encore vaut vrai
                                fin si
                            fin si
                        fin pour
                    fin pour
                fin tant que

                // ---------- RESTE-T-IL DEUX ALVÉOLES VOISINES LIBRES ? ----------
                placeRestante est un booléen
                placeRestante vaut faux
                pour i de 0 à NBRANG
                    pour j de 0 à larg[i] - 1
                        si plateau[i][j] = 0 alors
                            pour d de 0 à 5
                                fLi est un nombre
                                fCo est un nombre
                                si d = 0 alors
                                    fLi vaut 0
                                    fCo vaut 1
                                sinon si d = 3 alors
                                    fLi vaut 0
                                    fCo vaut 0 - 1
                                sinon
                                    longV2 est un booléen
                                    longV2 vaut faux
                                    si d = 1 ou d = 2 alors
                                        fLi vaut 1
                                    sinon
                                        fLi vaut 0 - 1
                                    fin si
                                    si i + fLi >= 0 et i + fLi <= NBRANG alors
                                        si larg[i + fLi] > larg[i] alors
                                            longV2 vaut vrai
                                        fin si
                                    fin si
                                    si d = 1 ou d = 5 alors
                                        si longV2 = vrai alors
                                            fCo vaut 1
                                        sinon
                                            fCo vaut 0
                                        fin si
                                    sinon
                                        si longV2 = vrai alors
                                            fCo vaut 0
                                        sinon
                                            fCo vaut 0 - 1
                                        fin si
                                    fin si
                                fin si
                                gr est un nombre
                                gc est un nombre
                                gr vaut i + fLi
                                gc vaut j + fCo
                                si gr >= 0 et gr <= NBRANG alors
                                    si gc >= 0 et gc <= larg[gr] - 1 alors
                                        si plateau[gr][gc] = 0 alors
                                            placeRestante vaut vrai
                                        fin si
                                    fin si
                                fin si
                            fin pour
                        fin si
                    fin pour
                fin pour

                si placeRestante = faux alors
                    finPartie vaut vrai
                    si score > record alors
                        record vaut score
                    fin si
                fin si
            fin si
        fin si
    fin si
fin tant que
5,0 / 5 (1 avis)