Console
Clique sur « Exécuter » pour lancer le programme.
Aucune exécutionCtrl+Entrée : exécuter · Échap : arrêter
Code CoddyRun
@ Symboles mathématiques
SYM_RACINE est un texte
SYM_RACINE vaut U+221A // Racine carrée
SYM_CARRE est un texte
SYM_CARRE vaut U+00B2 // Exposant deux
SYM_FOIS est un texte
SYM_FOIS vaut U+00D7 // Signe multiplier
SYM_DIVISE est un texte
SYM_DIVISE vaut U+00F7 // Signe diviser
SYM_MOINS est un texte
SYM_MOINS vaut U+2212 // Signe moins mathématique
SYM_PLUSMOINS est un texte
SYM_PLUSMOINS vaut U+00B1 // Plus ou moins
SYM_POURCENT est un texte
SYM_POURCENT vaut U+0025 // Pourcentage
@ Disposition
L_TOUCHE est un nombre
L_TOUCHE vaut 48
H_TOUCHE est un nombre
H_TOUCHE vaut 42
@ État
ecran est une toile
dimension(ecran, 300, 440)
affichage est un texte
accumulateur, operation, memoire est un nombre
nouvelleSaisie, modeExp, expSaisi est un nombre
enJeu est un booleen
i, j, cx, cy est un nombre
val, erreur est un nombre
teinte, etiq est un texte
action, ptX, ptY est un nombre
affichage vaut "0"
accumulateur vaut 0
operation vaut 0
memoire vaut 0
nouvelleSaisie vaut 1
modeExp vaut 0
expSaisi vaut 0
enJeu vaut vrai
@ position des touches
fonction toucheX(col)
retourne 12 + col * 57
fin fonction
fonction toucheY(rang)
retourne 104 + rang * 50
fin fonction
@ Lecture de l'affichage
fonction puissanceDix(n)
p est un nombre
k2 est un nombre
p vaut 1
pour k2 de 1 à n
p vaut p * 10
fin pour
retourne p
fin fonction
// Conversion texte vers nombre, faite à la main. On parcourt les
// caractères un par un : un signe moins éventuel, les chiffres, puis
// la virgule et les décimales. Plus sûr que de dépendre du séparateur
// décimal de la machine.
fonction valeurAffichee()
v est un nombre
d est un nombre
sg est un nombre
k est un nombre
c est un texte
v vaut 0
d vaut 0
sg vaut 1
pour k de 1 à longueur(affichage)
c vaut copier(affichage, k, 1)
si c = "-" alors
sg vaut - 1
sinon si c = "," alors
d vaut 1
sinon
si code(c) >= 48 et code(c) <= 57 alors
si d = 0 alors
v vaut v * 10 + code(c) - 48
sinon
v vaut v + (code(c) - 48) / puissanceDix(d)
d vaut d + 1
fin si
fin si
fin si
fin pour
retourne v * sg
fin fonction
procédure afficherNombre(v)
// Un résultat entier ne doit pas traîner de décimales inutiles.
si v = arrondi(v) et absolue(v) < 1000000000 alors
affichage vaut convertir_texte(arrondi(v))
sinon
affichage vaut convertir_texte(v)
fin si
fin procédure
@ Logique de la calculatrice
procédure appliquerOperation()
erreur vaut 0
val vaut valeurAffichee()
si modeExp = 1 alors
val vaut val * puissanceDix(expSaisi)
modeExp vaut 0
expSaisi vaut 0
fin si
si operation = 1 alors
accumulateur vaut accumulateur + val
sinon si operation = 2 alors
accumulateur vaut accumulateur - val
sinon si operation = 3 alors
accumulateur vaut accumulateur * val
sinon si operation = 4 alors
// division par zéro : on affiche l'erreur au lieu de planter
si val = 0 alors
accumulateur vaut 0
affichage vaut "erreur"
operation vaut 0
nouvelleSaisie vaut 1
erreur vaut 1
sinon
accumulateur vaut accumulateur / val
fin si
sinon
accumulateur vaut val
fin si
si erreur = 0 alors
appelle afficherNombre(accumulateur)
fin si
fin procédure
procédure taperChiffre(c)
si modeExp = 1 alors
expSaisi vaut limiter(expSaisi * 10 + c, 0, 99)
sinon
si nouvelleSaisie = 1 alors
affichage vaut convertir_texte(c)
nouvelleSaisie vaut 0
sinon si affichage = "0" alors
affichage vaut convertir_texte(c)
sinon si longueur(affichage) < 12 alors
affichage vaut affichage + convertir_texte(c)
fin si
fin si
fin procédure
procédure toucheOperation(op)
appelle appliquerOperation()
operation vaut op
nouvelleSaisie vaut 1
fin procédure
procédure toucheEgal()
appelle appliquerOperation()
operation vaut 0
nouvelleSaisie vaut 1
fin procédure
procédure toucheEffacer()
affichage vaut "0"
accumulateur vaut 0
operation vaut 0
nouvelleSaisie vaut 1
modeExp vaut 0
expSaisi vaut 0
fin procédure
procédure toucheUnaire(quoi)
erreur vaut 0
val vaut valeurAffichee()
si quoi = 1 alors
val vaut val / 100
sinon si quoi = 2 alors
// l'inverse de zéro n'existe pas
si val = 0 alors
affichage vaut "erreur"
erreur vaut 1
sinon
val vaut 1 / val
fin si
sinon si quoi = 3 alors
// la racine d'un négatif non plus
si val < 0 alors
affichage vaut "erreur"
erreur vaut 1
sinon
val vaut racine(val)
fin si
sinon
val vaut val * val
fin si
si erreur = 0 alors
appelle afficherNombre(val)
fin si
nouvelleSaisie vaut 1
fin procédure
procédure appuyerTouche(code2)
si code2 >= 0 et code2 <= 9 alors
appelle taperChiffre(code2)
sinon si code2 = 10 alors
// virgule : une seule par nombre
si nouvelleSaisie = 1 alors
affichage vaut "0,"
nouvelleSaisie vaut 0
sinon si non contient(affichage, ",") alors
affichage vaut affichage + ","
fin si
sinon si code2 = 11 alors
// changement de signe
si copier(affichage, 1, 1) = "-" alors
affichage vaut copier(affichage, 2, longueur(affichage) - 1)
sinon si affichage <> "0" alors
affichage vaut "-" + affichage
fin si
sinon si code2 = 12 alors
appelle toucheOperation(1)
sinon si code2 = 13 alors
appelle toucheOperation(2)
sinon si code2 = 14 alors
appelle toucheOperation(3)
sinon si code2 = 15 alors
appelle toucheOperation(4)
sinon si code2 = 16 alors
appelle toucheEgal()
sinon si code2 = 17 alors
appelle toucheEffacer()
sinon si code2 = 18 alors
appelle toucheUnaire(1)
sinon si code2 = 19 alors
appelle toucheUnaire(2)
sinon si code2 = 20 alors
appelle toucheUnaire(3)
sinon si code2 = 21 alors
appelle toucheUnaire(4)
sinon si code2 = 22 alors
// notation scientifique : les chiffres suivants forment l'exposant
modeExp vaut 1
expSaisi vaut 0
sinon si code2 = 23 alors
memoire vaut memoire + valeurAffichee()
nouvelleSaisie vaut 1
sinon si code2 = 24 alors
memoire vaut memoire - valeurAffichee()
nouvelleSaisie vaut 1
sinon si code2 = 25 alors
appelle afficherNombre(memoire)
nouvelleSaisie vaut 1
fin si
fin procédure
@ Dessin
procédure touche(g, col, rang, etiquette, fond, txt, taillePolice)
cx vaut toucheX(col)
cy vaut toucheY(rang)
contour(g, #0E5B8A, 2)
rectangle_arrondi(g, cx, cy, L_TOUCHE, H_TOUCHE, 7, fond)
contour(g, #0)
label(g, cx + L_TOUCHE / 2 - longueur(etiquette) * taillePolice / 4, cy + H_TOUCHE / 2 + taillePolice / 3, etiquette, txt, taillePolice)
fin procédure
procédure dessinerTout()
effacer(ecran)
rectangle(ecran, 0, 0, 300, 440, #F0F0F0)
contour(ecran, #0E5B8A, 3)
rectangle_arrondi(ecran, 4, 4, 292, 432, 14, #1E8BCD)
contour(ecran, #0)
label(ecran, 116.66, 24, "CoddyRun", #FFFFFF, 14)
// ----- écran -----
contour(ecran, #14405E, 3)
rectangle_arrondi(ecran, 14, 34, 272, 48, 4, #FFFFFF)
contour(ecran, #0)
si modeExp = 1 alors
etiq vaut affichage + " E " + convertir_texte(expSaisi)
sinon
etiq vaut affichage
fin si
// le nombre est collé à droite, comme sur une vraie calculatrice
label(ecran, 278 - longueur(etiq) * 13, 70, etiq, #3A3A3A, 24)
si memoire <> 0 alors
label(ecran, 22, 54, "M", #8A8A8A, 12)
fin si
// ----- rangée du haut -----
appelle touche(ecran, 0, 0, SYM_POURCENT, #1565A0, #FFFFFF, 17)
appelle touche(ecran, 1, 0, "M+", #1565A0, #FFFFFF, 15)
appelle touche(ecran, 2, 0, "M-", #1565A0, #FFFFFF, 15)
appelle touche(ecran, 3, 0, "MR", #1565A0, #FFFFFF, 15)
appelle touche(ecran, 4, 0, "C", #A8D420, #2A3A0A, 18)
// ----- colonne de gauche : les fonctions -----
appelle touche(ecran, 0, 1, "1/x", #1565A0, #FFFFFF, 15)
appelle touche(ecran, 0, 2, SYM_RACINE + "x", #1565A0, #FFFFFF, 16)
appelle touche(ecran, 0, 3, "x" + SYM_CARRE, #1565A0, #FFFFFF, 16)
appelle touche(ecran, 0, 4, "EE", #1565A0, #FFFFFF, 15)
// ----- les chiffres -----
appelle touche(ecran, 1, 1, "7", #FFFFFF, #2A2A2A, 19)
appelle touche(ecran, 2, 1, "8", #FFFFFF, #2A2A2A, 19)
appelle touche(ecran, 3, 1, "9", #FFFFFF, #2A2A2A, 19)
appelle touche(ecran, 1, 2, "4", #FFFFFF, #2A2A2A, 19)
appelle touche(ecran, 2, 2, "5", #FFFFFF, #2A2A2A, 19)
appelle touche(ecran, 3, 2, "6", #FFFFFF, #2A2A2A, 19)
appelle touche(ecran, 1, 3, "1", #FFFFFF, #2A2A2A, 19)
appelle touche(ecran, 2, 3, "2", #FFFFFF, #2A2A2A, 19)
appelle touche(ecran, 3, 3, "3", #FFFFFF, #2A2A2A, 19)
appelle touche(ecran, 1, 4, "0", #FFFFFF, #2A2A2A, 19)
appelle touche(ecran, 2, 4, ",", #FFFFFF, #2A2A2A, 19)
appelle touche(ecran, 3, 4, SYM_PLUSMOINS, #FFFFFF, #2A2A2A, 19)
// ----- colonne de droite : les opérations -----
appelle touche(ecran, 4, 1, SYM_DIVISE, #1565A0, #FFFFFF, 20)
appelle touche(ecran, 4, 2, SYM_FOIS, #1565A0, #FFFFFF, 20)
appelle touche(ecran, 4, 3, SYM_MOINS, #1565A0, #FFFFFF, 22)
appelle touche(ecran, 4, 4, "+", #1565A0, #FFFFFF, 21)
// ----- la barre égale -----
contour(ecran, #0E5B8A, 2)
rectangle_arrondi(ecran, 12, 356, 276, 52, 8, #5FBDEF)
contour(ecran, #0)
label(ecran, 138, 392, "=", #14405E, 30)
affiche ecran
fin procédure
@ Programme principal
// Correspondance entre la position d'une touche et son code interne.
// Rangée 0 : % M+ M- MR C, puis les quatre rangées du pavé.
fonction codeDe(col, rang)
si rang = 0 alors
si col = 0 alors
retourne 18
fin si
si col = 1 alors
retourne 23
fin si
si col = 2 alors
retourne 24
fin si
si col = 3 alors
retourne 25
fin si
retourne 17
fin si
si col = 0 alors
si rang = 1 alors
retourne 19
fin si
si rang = 2 alors
retourne 20
fin si
si rang = 3 alors
retourne 21
fin si
retourne 22
fin si
si col = 4 alors
si rang = 1 alors
retourne 15
fin si
si rang = 2 alors
retourne 14
fin si
si rang = 3 alors
retourne 13
fin si
retourne 12
fin si
// les chiffres : 7 8 9 / 4 5 6 / 1 2 3 / 0 , (-)
si rang = 4 alors
si col = 1 alors
retourne 0
fin si
si col = 2 alors
retourne 10
fin si
retourne 11
fin si
retourne (3 - rang) * 3 + col
fin fonction
appelle dessinerTout()
tant que enJeu
interagir ecran, ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "-", "*", "/", "=", "c", "p"] dans action, ptX, ptY
si non enJeu alors
arrête
fin si
si action = 0 alors
// la barre égale d'abord, elle déborde de la grille
si clique(ptX, ptY, 12, 356, 276, 52) alors
appelle appuyerTouche(16)
sinon
pour i de 0 à 4
pour j de 0 à 4
si clique(ptX, ptY, toucheX(i), toucheY(j), L_TOUCHE, H_TOUCHE) alors
appelle appuyerTouche(codeDe(i, j))
fin si
fin pour
fin pour
fin si
sinon si action <= 10 alors
appelle appuyerTouche(action - 1)
sinon si action = 11 alors
appelle appuyerTouche(12)
sinon si action = 12 alors
appelle appuyerTouche(13)
sinon si action = 13 alors
appelle appuyerTouche(14)
sinon si action = 14 alors
appelle appuyerTouche(15)
sinon si action = 15 alors
appelle appuyerTouche(16)
sinon si action = 16 alors
appelle appuyerTouche(17)
sinon
enJeu vaut faux
arrête
fin si
appelle dessinerTout()
fin tant que
affiche "Calculatrice fermée"