Blog

Page d’exemple

Projets

Entrainement au calcul mental en Python

Ce script génère des additions et multiplications aléatoires et permet de s’entraîner sur le calcul mental.

Projet NSI 1 : Le calcul mental :

Ce projet consiste à créer un programme en python faisant travailler le calcul mental. Nous sommes en 1ère spécialité NSI au lycée Louis Pasteur à l’année 2019/2020.

Introduction : Python :

Python est un langage de programmation interprété. C’est à dire un programme qui exécute les programmes écrits avec un langage informatique. Python est un langage épuré car il possède moins de construction syntaxique que les autres langages. Il est disponible sur tablettes, ordinateurs, ou encore calculatrice.

But et présentation du programme :

Ce programme de calcul mental permet de se perfectionner et de s’entrainer au calcul via différents niveaux adaptés à tout le monde. Il est pratique car il permet d’avoir une correction et un score et de ne pas se préoccuper à trouver des calculs. Ce programme est destiné à tous les niveaux (plus particulièrement aux élèves de seconde qui doivent savoir maîtriser ces notions.).

Ce programme est constitué de 5 niveaux regroupant le calcul d’additions, de soustractions et de multiplication. Chaque niveau est constitué de 20 questions et d’une correction. Ce programme permet aussi à un élève de seconde de s’initier au langage python en l’exécutant et d’essayer de le comprendre grâce à la petite présentation du programme ci-dessous.

Décortication du programme :

Tout d’abord la console nous demande de choisir un niveau dans le menu proposé.

# La fonction menu !
def menu():
    print("Choisis un niveau")
    print("1. Addition niveau 1") 
    print("2. Addition niveau 2")
    print("3. Multiplication niveau 1")
    print("4. Multiplication niveau 2")
    print("5. Final avec toutes les opérations posssibles")
    choix = 0
    while choix==0:
        choix=int(input())
    if choix==1:
        additionniveau1()
    elif choix==2: 
        additionniveau2()
    elif choix==3:
        multiplicationniveau1()
    elif choix==4:
        multiplicationniveau2()
    elif choix==5:
        final()
    elif choix==9:
        print("Au revoir !")
        exit
    else: 
        menu() 
    if choix!=9:
        menu() 

menu()

On peut voir ci-dessus la fonction menu. Grace à « print » un menu va s’afficher. Puis avec la fonction « int(input » l’utilisateur va choisir un niveau grâce à 5 chiffres correspondant aux 5 niveaux. Et avec les conditions « elif et if » notre programme va se reporter au fonction prédéfinies précedemment.

Voici une des fonctions définies :

# Une des 5 fonctions définis !
    print("Niveau1 : Addition avec 1 chiffre")
    nb=1
    score = 0
    while nb<=20:
        aleat1 = random.randint(1, 9)
        aleat2 = random.randint(1, 9)
        print("Combien fait", aleat1, "+",aleat2)
        reponse = int(input("réponse = "))
        nb = nb + 1
        result = (aleat1 + aleat2)
        if reponse==result :
            score = score + 1
        elif reponse!=result :
            score = score + 0
        print("Voici la correction:", result)
    print("Ton score est:", score, "/20")
    if score>=16 :
        print("Bravo tu es experimenté et tu peux passer au niveau 2")
    if score<10 :
        print("C'est pas grave, retente ta chance")
    if score<16 and score>=10:
        print("Tu as un bon niveau mais je te conseille de reessayer. Avant révise un peu.") 

Grace à la fonction random des chiffres et des nombres vont être tirés aléatoirement permettant de générer des calculs aléatoirement.

Ces chiffres et nombres sont 2 variables (aleat1 et aleat2) tirés aléatoirement selon un intervalle de chiffres et nombres selon les niveaux respectifs. Cela va être appliqué au 4 premier niveaux.

Avec « if » qui nous permet d’exécuter le code mais avec des conditions. Si la réponse est juste le +1 va être ajouté au score sinon pas de changement du score. Ce qui fera un résultat final sur 20 grâce à la fonction « while » ; while nous permet de réaliser cette boucle indéfiniment tant que la variable « nb » n’est pas inférieur à 20. Cette boucle va donc se répéter pendant 20 questions.. Aussi à la fin de chaque calcul une correction est proposée encore grâce à « if ». Si le score est supérieur à 16 la compétence est validée, si c’est entre 10 et 15 tu maîtrises moyennement les compétences. Si inférieur à 10 il vaudrait mieux réviser.

# Le script d'une autre fonction !
    print("Niveau5: Final")
    nb=1
    score = 0
    while nb<=20:
        aleat1 = random.randint(1, 15)
        aleat2 = random.randint(1, 15)
        listes = [(aleat1 + aleat2), (aleat1 * aleat2), (aleat1 - aleat2)]
        aleat3 = listes[random.randint(0, 2)]
        if aleat3==(aleat1 + aleat2) :
            print("Combien fait", aleat1, "+", aleat2)
        elif aleat3==(aleat1 * aleat2) :
            print("Combien fait", aleat1, "x", aleat2)
        elif aleat3==(aleat1 - aleat2) :
            print("Combien fait", aleat1, "-", aleat2)
        reponse = int(input("réponse = "))
        nb = nb + 1 
        result = aleat3
        if reponse==result :
            score = score + 1
        elif reponse!=result :
            score = score + 0
        print("Voici la correction:", result)
    print("Ton score est:", score, "/20")
    if score>=16 :
        print("Bravo tu es experimenté et tu maitrise toutes les compétences nécessaires")
    if score<10 :
        print("C'est pas grave, retente ta chance tu vas y arriver. Avant révise un peu.")
    if score<16 and score>=10:
        print("Tu as un bon niveau mais je te conseille de réessayer")

Pour la 5ème fonction nous avons créé une 3ème variable (aleat3) nous permettant de tirer aléatoirement dans une liste prédéfinie (composé des 3 opérations), et grâce encore une fois à la condition « if » pour avoir une opération aléatoire et toujours des chiffres et nombres aléatoires.

Si tu veux t’améliorer en calcul mental clique sur le lien ci-dessous :

Projets

Convertisseur d’unité en python

Plus besoin de convertir des unités de tête ou avec un tableau. Ce programme vous fait le travail à votre place.

Ce projet est un programme réalisé avec python dans le but de convertir un nombre avec une unité de départ dans une unité finale. Il permet de convertir des volumes, des masses, des longueurs et des aires. Ce programme a été développé à l’aide d’omega et est téléchargeable sur la calculatrice Numworks grâce aux liens hypertextes en bas de cet article.

Explication de notre programme

• Tout d’abord nous avons dû assimilés les unités avec les puissances de 10 qui correspondaient.

expo0 = [10**-3, 10**-2, 10**-1, 10**0, 10**1, 10**2, 10**3, 10**-3, 10**0, 10**3, 10**6, 10**9]
unit0 = ["mL", "cL", "dL", "L", "daL", "hL", "kL", "cm3", "dm3", "m3", "dam3", "hm3", "km3"]
 
expo1 =[10**-3, 10**-2, 10**-1, 10**0, 10**1, 10**2, 10**3, 10**5, 10**6]
unit1 =["mg", "cg", "dg", "g", "dag", "hg", "kg", "q", "t"]
 
expo2 = [10**-9,10**-6,10**-3,10**-2,10**-1,10**0,10**1,10**2,10**3]
unit2 = ["nm","micrometre","mm","cm","dm","m","dam","hm","km",]
 
expo3 = [10**-6, 10**-4, 10**-2, 10**0, 10**2, 10**4, 10**6]
unit3 = ["mm2", "cm2", "dm2", "m2", "dam2", "hm2", "km2"]

• On a également créer une petite fonction utile.

Une fonction utile

def clear(nb):
    print("\n"*nb)

Cette fonction permet de sauter le nombre de ligne que l’on veut en écrivant ce nombre entre les parenthèses.

Exemple

clear(2)

• Ensuite, nous avons créé les fonctions permettant de convertir les unités.

Fonction volume, masse, longueur et aire

def volume():
    clear(6)
    print("Vous avez choisi les volumes.")
    clear(2)
    nbr = float(input("Quel nombre voulez vous\nconvertir : "))
    clear(1)
    print("liste des unites : \n0 = mL\t1 = cL\t 2 = dL\n3 = L \t4 = daL\t5 = hL\n6 = kL\t7 = cm3\t8 = dm3\n9 = m3\t10 = dam3  11 = hm3\n12 = km3")
    clear(1)
    unit_d0 = int(input("Quel est l'unite de depart\nde votre nombre : "))
    clear(0)
    unit_a0 = int(input("Quel est l'unite final\nde votre nombre : "))
    convert0 = nbr * expo0[unit_d0] / expo0[unit_a0]
    clear(1)
    print("Le resultat est :\n%.3e"%convert0, unit0[unit_a0])
    clear(0)
    go_menu = float(input("Entrez un nombre pour\nretourner au menu : "))
    if go_menu == 1:
        return menu()
    else:
        return menu()

Explication de la fonction volume ci-dessus

Cette fonction nous demande dans un premier temps, quel nombre nous voulons convertir.

Et dans un second temps, l’unité de départ et l’unité finale du nombre.

Cette fonction nous affiche ensuite le résultat et nous demande d’écrire un nombre au hasard pour retourner au menu (que l’on verra plus tard dans cet article).

def masse():
    clear(6)
    print("Vous avez choisi les masses.")
    clear(2)
    nbr = float(input("Quel nombre voulez vous\nconvertir : "))
    clear(1)
    print("liste des unites : \n0 = mg\t1 = cg\t2 = dg\n3 = g     4 = dag   5 = hg\n6 = kg\t7 = q\t 8 = t")
    clear(1)
    unit_d1 = int(input("Quel est l'unite de depart\nde votre nombre : "))
    clear(1)
    unit_a1 = int(input("Quel est l'unite final\nde votre nombre : "))
    convert1 = nbr * expo1[unit_d1] / expo1[unit_a1]
    clear(1)
    print("Le resultat est :\n%.3e"%convert1, unit1[unit_a1])
    clear(0)
    go_menu = float(input("Entrez un nombre pour\nretourner au menu : "))
    if go_menu == 1:
        return menu()
    else:
        return menu()

La fonction masse ci-dessus

Cette fonction est la même que la fonction volume, mais elle ne convertit pas des volumes mais des masses.

def longueur():
    clear(6)
    print("Vous avez choisi les longueurs.")
    clear(2)
    nbr = float(input("Quel nombre voulez vous\nconvertir : "))
    clear(1)
    print("liste des unites : \n0 = nm\t1 = micrometre\n2 = mm\t3 = cm\t4 = dm\n5 = m     6 = dam   7 = hm\n8 = km")
    clear(1)
    unit_d2 = int(input("Quel est l'unite de depart\nde votre nombre : "))
    clear(0)
    unit_a2 = int(input("Quel est l'unite final\nde votre nombre : "))
    convert2 = nbr * expo2[unit_d2] / expo2[unit_a2]
    clear(1)
    print("Le resultat est :\n%.3e"%convert2, unit2[unit_a2])
    clear(0)
    go_menu = float(input("Entrez un nombre pour\nretourner au menu : "))
    if go_menu == 1:
        return menu()
    else:
        return menu()

La fonction longueur ci-dessus

Cette fonction est la même que la fonction volume et la fonction masse, mais elle ne convertit ni des volumes ni des masses, mais des longueurs.

def aire():
    clear(6)
    print("Vous avez choisi l'aire.")
    clear(2)
    nbr = float(input("Quel nombre voulez vous\nconvertir : "))
    clear(1)
    print("liste des unites : \n0 = mm2\t1 = cm2\t2 = dm2\n3 = m2     4 = dam2   5 = hm2\n6 = km2")
    clear(1)
    unit_d3 = int(input("Quel est l'unite de depart\nde votre nombre : "))
    clear(1)
    unit_a3 = int(input("Quel est l'unite final\nde votre nombre : "))
    convert3 = nbr * expo3[unit_d3] / expo3[unit_a3]
    clear(1)
    print("Le resultat est :\n%.3e"%convert3, unit3[unit_a3])
    clear(0)
    go_menu = float(input("Entrez un nombre pour\nretourner au menu : "))
    if go_menu == 1:
        return menu()
    else:
        return menu()

La fonction aire ci-dessus

Cette fonction est la même que la fonction volume, la fonction masse et la fonction longueur, mais elle ne convertit ni des volumes ni des masses ni des longueurs, mais des aires.

• Et pour finir nous avons créé une fonction menu.

def menu():
    clear(3)
    print("        _______________")
    print("       |               |")
    print("       | CONVERTISSEUR |")
    print("       |    D'UNITE !  |")
    print("       |_______________|")
    print("\n1 - Le volume")
    print("2 - La masse")
    print("3 - La longueur")
    print("4 - L'aire\n")
    choix = int(input("Indiquer votre choix : " ))
 
    if choix == 1:
        volume()
 
    elif choix == 2:
        masse()
 
    elif choix == 3:
        longueur()
 
    elif choix == 4:
        aire()
 
    else:
        return menu()

Explication de la fonction menu ci-dessus

Cette fonction nous propose 4 choix qui sont le volume, la masse, la longueur et l’aire. Ces 4 choix sont respectivement associés aux chiffres 1, 2, 3 et 4 donc si on rentre le chiffre 1, le programme va exécuter la fonction volume. Et si on rentre un nombre différent de 1, 2, 3 et 4 la fonction exécutera encore le menu.

Conclusion

Plus besoin de convertir mentalement ou avec un tableau, ce programme vous fait le travail à votre place ! Vous pouvez le télécharger les liens ci-dessous.

Le programme

ServeurRemarquesLiens hypertextes
Workshop de NumWorksPermet un téléchargement rapide sur la calculatriceconvertisseur d’unité

Projets

Une Histoire de plus ou moins

Lancez vous dans le jeu du plus ou moins, et tenter de battre l’ordinateur en devinant le nombre entre 0 et 1000 auquel il pense en moins de 10 coups ! Ou alors faites lui deviner votre nombre, saura t’il le trouver en moins de 10 coups et quelle stratégie adoptera t’il ?

Lancez vous dans le jeu du plus ou moins et tentez de battre l’ordinateur en devinant le nombre, entre 0 et 1000, auquel il pense en moins de 10 coups ! 
Ou alors, faites lui deviner votre nombre, saura t’il le trouver en moins de 10 coups et quelle stratégie adoptera t’il ?

Ce projet est un programme réalisé sur python recréant le célèbre jeu du plus ou moins. Il vous permettra une fois téléchargé sur votre calculatrice Numworks ou à l’aide d’un IDE de trouver ou de faire deviner un nombre entre 0 et 1000 à l’ordinateur. Ce programme a été developpé sur Pycharm et peut être téléchargeable sur la calculatrice Numworks via les liens hypertextes en bas de l’article.

La Naissance du projet

Dès l’annonce du projet nous voulions partir sur un jeu et surtout travailler sur l’interaction entre l’homme et la machine.

C’est alors que le jeu du plus ou moins nous est apparu comme une idée ni trop simple ni trop compliquée à coder avec une interaction importante.

Le projet était comme un mini défi puisque nous devions incrémenter une sorte de mini “intelligence artificielle”, car en effet dans ce jeu il existe une stratégie qui garantit la victoire.

Les différents modes de jeu

  • UN PREMIER MODE DE JEU

Dans ce mode de jeu, l’ordinateur doit trouver un nombre auquel l’utilisateur pense.

La stratégie consiste à diviser par deux le nombre de possibilités allant de 0 à 999, il suffit donc de proposer 500 comme premier choix, 250 ou 750 en deuxième choix et ainsi de suite… Grâce à cette méthode, l’ordinateur a la certitude de trouver le nombre en moins de dix coups.

Le but étant d’intégrer la stratégie à l’ordinateur comme une sorte de mini « intelligence artificielle” pour que l’ordinateur l’adopte et soit donc sûr de gagner à tous les coups.

victoire = False
min = 0
max = 1000
 
def recherche(min, max):
   scoreordi = 0
   scorejoueur = 0
   global victoire
   while not victoire:
       print("Ton chiffre est il plus grand que",int((min + max) / 2),"?")
       reponse = input()
       if reponse == "+":
           recherche(int((min + max) / 2), max)
       elif reponse == "-":
           recherche(min, int((min + max) / 2))
       elif reponse == "=":
           print("J'ai donc trouvé ton chiffre qui est",int((min + max) / 2))
           victoire = True
           print("Partie terminee")
recherche(min,max)

Voici le rendu du 1er mode de jeu :

  • UN DEUXIEME MODE DE JEU

Le deuxième mode de jeu fut bien plus simple à coder que l’autre car il suffisait de faire un script qui génère un nombre aléatoirement et le faire deviner à l’utilisateur à l’aide de phrases tels que “c’est plus !” ou “c’est moins !” .Nous avons intégré des boucles “if” et “while” en réponse au nombre entré par le joueur.

choix = randint(0, 999)
    nb = int(input())
    if nb < 0:
        print("Votre réponse n'est pas valide")
        sleep(3)
        questionordi()
    elif nb > 999:
        print("Votre réponse n'est pas valide")
        sleep(3)
        questionordi()
    cpt = 0
    scoreordi = 0
    scorejoueur = 0
    while cpt < 9:
        if nb > choix:
            print("C'est moins !")
            nb = int(input())
            if nb < 0:
                print("Votre réponse n'est pas valide")
                sleep(3)
                questionordi()
            elif nb > 999:
                print("Votre réponse n'est pas valide")
                sleep(3)
                questionordi()
            cpt += 1
        elif nb < choix:
            print("C'est plus !")
            nb = int(input())
            if nb < 0:
                print("Votre réponse n'est pas valide")
                sleep(3)
                questionordi()
            elif nb > 999:
                print("Votre réponse n'est pas valide")
                sleep(3)
                questionordi()
            cpt += 1
        else:
            print("Tu as trouve")
            cpt = 10
            scorejoueur = scorejoueur + 1
            print("Score ordinateur :", scoreordi, "\nScore joueur  :", scorejoueur)

Voici le rendu du 2ème mode de jeu :

Une ergonomie pensée pour la calculatrice

Un des autres défis de ce projet fut de traduire notre script pour qu’il puisse coller à l’interface limitée de la Numworks, en effet dans la calculatrice on ne peut pas se permettre de faire une phrase trop longue ou encore de mettre trop de texte. Nous avons alors utilisé des IDE Python tels que Numworks ou Omega pour corriger les bugs d’affichage et mettre en forme notre jeu textuel.

La création d’un menu nous a permis de créer un semblant d’interface graphique afin d’ajouter un peu d’esthétique à notre code.

Voici un aperçu du menu :

Conclusion

Comme vous le savez, le langage python nécessite comme tous les langages une extrême rigueur sans quoi le script est immédiatement obsolète.

C’est pourquoi nous avons dû braver certains problèmes qui empiétaient sur la justesse du code et donc du jeu.

Notre obstacle majeur étant que la boucle « while » dans la définition recherche (Voir le mode de jeu 1), était interminable ! Aussi mais pas des moindre nous avons eu aussi de nombreux soucis d’indentation et de syntaxe.

Après avoir résolu ces problèmes et optimiser notre jeu, nous avions l’impression qu’une couche graphique aiderait à rendre le jeu plus vivant.

Malheureusement, nos faibles connaissances pour les modules tels que turtlekandinsky et tkinter ont fait que notre tentative d’amélioration a échoué. Dès lors, nous avons abandonné l’idée d’offrir une interface graphique au joueur pour uniquement nous concentrer sur le script et le menu, qui servirait en remplacement.

Voici un lien vers nos essais graphiques

En somme, ce projet nous aura permis d’étendre nos connaissances en python ainsi que de réaliser notre premier “jeu” interactif.

Vous retrouverez les liens de notre script dans le tableau ci-dessous et pourrez le télécharger.

Télécharger et tester

ServeurWorkshop de NumWorkstiplanet.orgnsi.xyz
RemarquePermet un téléchargement rapide sur la calculatriceTéléchargement .pyTéléchargement .zip
Liens hypertexteslienNumWorks > Physique > Lien(Bouton en dessous)
Projets

Un Pac-Man sur ta Numworks, en python

Rond comme un ballon, et plus jaune qu’un citron, c’est lui Pac-Man ! Pac-Man débarque sur ta NumWorks ! Aide le à manger toutes les pac-gommes en évitant les fantômes et accumule le plus grand score.

Bon jeu !

URL courte de cet article : nsi.xyz/pacman

Pac-Man débarque sur ta NumWorks !

Aide le à manger toutes les pac-gommes en évitant les fantômes et accumule le plus grand score. Pour cela, tu peux :

  • Manger des pac-gommes (10)
  • Manger des super pac-gommes (50)
  • Manger les fantômes (200, 400, 800, puis 1600)

Si tu manges tout les fantômes a chaque super pac-gommes, tu obtiendras même un bonus de 12000 points !

Bon jeu !

Pac-Man, un sacré projet…

Comme toujours, sur nsi.xyz, on aime raconter l’histoire derrière nos projets.

Celle là commence dans une cuisine. Je commençais à faire à manger quand le patron  m’a envoyé un message concernant un bug sur un de ses projets « un jeu en une soirée » : Treasure

L’idée me plaisait, j’avais envie de faire pareil. Mais quel jeu choisir ?

🤓  Je vais tenter de faire un jeu en une nuit aussi vous m’avez motivé. Une idée ?
🧐 Pacman, tout autre jeu serait trop facile pour toi 😅

Pac-Man, ca paraissait infaisable… Des IA différentes pour chaque fantômes, des collisions, des tableaux et encore des tableaux, tout ça dans 32Ko max !

On est parti !

Première étape : Comment stocker la carte ?

Déjà, posons nous la question suivante : C’est quoi la carte dans Pac-Man ?

La carte, c’est soit :

  • Les chemins : On peut se balader dessus, les fantômes aussi.
  • Les murs : Comme on peut le penser, c’est l’inverse des chemins, on ne peut pas les traverser.

Du coup, on est sauvé ! Le tableau contiendra uniquement des 1 (pour les murs) ou des 0 (pour les chemins). Ainsi, on passe d’un tableau 2D de Booléen à un tableau 1D d’entier.
L’astuce est simple mais efficace : Une ligne de 1 et de 0 peut être convertie en entier grâce au fait que l’ordinateur code les entier en binaire.
En plus de réduire la complexité en espace, ça réduit aussi celle en temps, ce qui est pratique quand on parle d’un jeu tel que Pac-Man sur une calculatrice.

Deuxième étape : Construire la carte

Je commence déjà par choisir une taille pour les cases : 10px.
Sachant que la NumWorks dispose d’un écran de 222 px de haut, je sais que ma carte fera 22 cases de haut.Retour ligne automatique
A l’aide d’un logiciel professionnel et d’une image sur Internet, je crée une image blanche de 18x22px (Pourquoi 18 ? Je ne sais pas) que je commence à colorier de façon à obtenir ceci :

Et cette carte se traduit par le tableau suivant :

bits = 18  # Le nombre de bits pour chaque entiers, ce sera utile plus tard
terrain = (262143,131841,187245,187245,131073,186285,135969,252783,249903,251823,1152,251823,249903,251823,131841,187245,147465,219051,135969,195453,131073,262143)

Encore une fois, on utilise des tuple pour gagner en mémoire.

Maintenant, il ne reste plus qu’a rendre la carte à l’écran.
Et pour ca, on utilise une belle fonction :

def render():
    global terrain
    for l in range(len(terrain)):
        for c in range(bits):
            fill_rect(c*10+140,l*10+1,10,10,colors[0])
            if terrain[l]>>(bits-1-c) & 1:
                for d in ((1,0),(0,1),(-1,0),(0,-1)):
                    if 0 <= l + d[0] <= len(terrain) - 1 and 0 <= c + d[1] <= bits - 1 and not terrain[l + d[0]]>>(bits-1-(c+d[1])) & 1:
                        fill_rect(c*10+140+9*(d[1]==1),l*10+1+9*(d[0]==1),1+9*(d[1]==0),1+9*(d[0]==0),colors[1])

Pour faire simple, cette fonction lit les entier comme s’ils était des tableaux de 1 et de 0. Pour chaque case, elle dessine un carré noir. Si la case est un 1, elle regarde dans les 4 direction possibles, si un 0 s’y trouve, alors elle dessine un mur de ce côté.

En rajoutant une petite fonction pour du pré-rendu que je ne détaillerai pas, on obtiens déjà ceci :

Troisième étape : Ajouter de « la classe » au jeu

Outre l’aspect douteux de ce jeu de mot, il est temps de créer une classe pour Pac-Man et ses amis.
Ainsi née la classe Entity qui contiendra, à elle seule, toutes les méthodes pour le jeu. En effet, si on ne considère pas l’entrée des directions, les fantômes et Pac-Man se déplacent de la même manière sur la carte.

Pour faire court, cette classe contient 4 méthodes :

  • Le constructeur : initialise tout les attributs de l’entité.
  • espace : C’est la méthode qui teste les collision, grâce à elle, les fantômes et Pac-Man ne tournent que sur les intersections sans déborder sur les murs. Et évidemment, ils ne traversent pas non plus les murs.
  • move : C’est la méthode qui fait se déplacer les entités, qui réactualise les pac-gommes et super pac-gommes (j’y viendrai plus tard) et qui gère les collisions Pac-Man / Fantômes et Pac-Man / pac-gommes.
  • ia : Détermine la direction des fantômes.

Attardons-nous sur la méthode ia :

def ia(self,x,y):
    if self.f:
        while True:
            d = randint(0,3)
            dx, dy = ((-0.1,0),(0,-0.1),(0,0.1),(0.1,0))[d]
            if d != (3,2,1,0)[self.d] and self.espace(dx,dy):
                self.d = d
                break
    else:
        distances = [9999 for _ in range(4)]
        for i in range(4):
            if i != (3,2,1,0)[self.d]:
                dx, dy = ((-0.1,0),(0,-0.1),(0,0.1),(0.1,0))[i]
                if self.espace(dx,dy):
                    distances[i] = sqrt((self.y + dy - y)**2 + (self.x + dx - x)**2)
        self.d = distances.index(min(distances))

On voit qu’elle comporte deux parties, c’est un des éléments clés de Pac-Man : quand les fantômes sont dans l’état effrayé, ils choisissent une direction au hasard, sinon, ils choisissent la direction qui leur permet d’avoir la plus courte distance euclidienne à un point. Rajoutons que les fantômes n’ont pas le droit de faire demi-tour.

Mais une question se pose : Quel est donc ce point que visent les fantômes ?

Quatrième étape : Les fantômes débarquent !

Dans Pac-Man, il y a quatre fantômes. Mais il n’y a pas que leur couleur qui change, leur comportement aussi !

Petit listing exhaustif :

Blinky poursuit Pac-Man, ainsi le point qu’il cherche à atteindre et le point au centre de Pac-Man.

Pinky est la plus intelligente, ainsi le point qu’elle cherche à atteindre est deux cases devant Pac-Man dans la direction qu’il regarde.

Inky est un peu plus farceur, pour savoir ou il vise, il faut prendre en compte la position de Blinky et de Pac-Man. Posons v le vecteur Blinky-Point deux cases devant Pac-Man dans la direction qu’il regarde, Inky visera le point situé à 2v, ce qui le rend imprévisible.

Clyde quant à lui est un froussard, il agit comme Blinky quand à lui, est à 4 « mètres » de Pac-Man, mais vise un angle de la carte quand il est proche de Pac-Man.

Cinquième étape : Déplacer Pac-Man

Les fantômes maintenant capables de changer de direction, il n’en n’est rien pour Pac-Man…Retour ligne automatique
Comment se déplace Pac-Man ? Pac-Man se déplace jusqu’au bout d’un chemin avant de s’arrêter. Si on lui donne une direction, il la prendra dès qui le pourra sauf si la direction en question est la direction opposée à celle qu’il emprunte déjà.

Du coup, avec nos méthodes et un peu d’astuce, c’est tout simple !

for i in range(4):
    if keydown(i):
        if i == (3,2,1,0)[pacman.d]:
            pacman.d = i
        pacman.nd = i
if pacman.espace():
    pacman.d = pacman.nd

Sixième étape : Gestion des pac-gommes

Vous l’aurez peut-être remarqué mais le jeu est relativement fluide et rapide.Retour ligne automatique
Tout ça repose sur une grosse optimisation sur les pac-gommes, sans cette optimisation, le jeu tourne à 4 IPS.

Une question importante se pose : Comment réussir à afficher et rafraichir les pac-gommes ?

Une première approche innocente serait de stocker les pac-gommes sous forme de tableau de 0, 1 et 2 et le parcourir en affichant ou non les précieuses gommes. Sauf que là, bonjour le temps pour chaque image…

Une deuxième approche est de créer deux listes d’entier et d’utiliser les opérateurs binaires et les soustractions pour stocker les pac-gommes.Retour ligne automatique
Enfin, et c’est la l’énorme gain de temps. Pour chaque entités, après un mouvement, on regarde dans les deux listes si une (super) pac-gomme se trouve sur la case précédente, que ce soit un mur ou non, et on dessine une pac-gomme si besoin. Et c’est comme ça qu’on atteint une fluidité de jeu.

En plus, au lieu d’un parcours de liste, on a juste a implémenter les cinq lignes suivantes :

px, py = int(self.x - 5.5*dx), int(self.y - 5.5*dy)
if pacgommes[py]>>(bits-1-px) & 1:
    fill_rect(px*10+144,py*10+5,2,2,(250, 207, 173))
if superpacgommes[py]>>(bits-1-px) & 1:
    fill_rect(px*10+143,py*10+4,4,4,(250, 207, 173))

Septième étape : Gestion du score et des états des fantômes

Pour le score, on a juste à implémenter les règles citées en début d’article.

Pour la gestion des états des fantômes, c’est un peu plus compliqué qu’une simple variable.
Il faut rajouter un attribut afin que lorsqu’on mange un fantôme, il ne soit plus effrayé sans pour autant que les autres ne le soient plus.
Enfin, il faut rajouter une clock qui nous permettra de rendre leur état normal au fantômes après un certain temps en le rendant blanc juste avant pour alerter le joueur.

Conclusion

Evidemment, je ne me suis pas attardé sur tous les détails car se serait beaucoup trop long. Mais ce sont les éléments principaux pour un Pac-Man.
Je n’ai pas rajouté les changement de phases entre Chase et Scatter, de peur d’impacter les performances ou de dépasser la place disponible en mémoire.
Le Pac-Man fini rend bien :

Code jouable disponible ici :

Projets

Méli mélo de formule de Physique-Chimie

Ce projet a été réalisé par des élèves en spécialité NSI du Lycée Louis Pasteur. Ils sont également les auteurs de ce compte rendu. Pour en savoir plus : Les projets en spécialité NSI

Présentation du programme

Ce programme propose trois aides en physique-chimie : 
1 – Convertir un nombre d’entités en mole
2 – Donner la composition finale d’une réaction 
3 – Registre des significations des lettres et symboles avec leur unité

aperçu du menu
def menu():
   
    print("\n--------MENU PRINCIPAL--------\n")
    print("1 - Convertir un nombre \n d'entites en mole")
    print("2 - Donner la composition \nfinale d'une reaction")
    print("3 - Registre des significatons \ndes lettres et symboles avec \n leur unite")
    choix=int(input("Choix =\t"))
    print()
    if choix==1:
        f1()
    elif choix==2:
        f2()
    elif choix==3:
        f3()
    else:
        print("Choix non valide\n")
        menu()
 
def f1():
    n = int(input("Donner le nombre d'entites a\n convertir:\t "))
    na = 6.02214076 * 10 ** 23
    r = n / na
    print("\n La quantite de matiere\n correspondante est\n %.3e"%r, "moles" )
    input ()
    menu ()
   
def compo_finale(a,b,c,d,nx,ny):
    x=min(nx/a,ny/b)
    return nx-a*x,ny-b*x,c*x,d*x
 
def f2():
    A = int(input("Veuillez renseigner\n le coefficient A:\t"))
    B = int(input("\nVeuillez renseigner\n le coefficient B:\t"))
    C = int(input("\nVeuillez renseigner\n le coefficient C:\t"))
    D = int(input("\nVeuillez renseigner\n le coefficient D:\t"))
    n_x = int(input("\nVeuillez renseigner\n la quantite de matiere\n de A:\t"))
    n_y = int(input("\nVeuillez renseigner\n la quantite de matiere\n de B:\t"))
 
    nfA,nfB,nfC,nfD = compo_finale(A,B,C,D,n_x,n_y)
    print("Il reste %.3e"%nfA, "\nmoles de A\n")
    print("Il reste %.3e"%nfB, "\nmoles de B\n")
    print("Il reste %.3e"%nfC, "\nmoles de C\n")
    print("Il reste %.3e"%nfD, "\nmoles de D\n")
    input()
    menu()
 
def f3():
    print ("m : masse de l'échantillon\n ou masse d'un corps (g)")
    print ("\nM : masse molaire de\n l'echantillon (g.mol-1)")
    print ("\nn : quantite de matiere (mol)")
    print ("\nV : volume d un corps\n (L ou m3)")
    print ("\nrho : masse volumique de la\n solution (g.L-1 ou kg.m-3)")
    print ("\nd : densite (sans unite)")
    print ("\nn : quantite de matiere (mol)")
    print ("\nCM: concentration molaire\n (mol.L-1)")
    print ("\nU : tension (V, volts)")
    print ("\nI : intensite du courant\n (A, amperes)")
    print ("\nR : resistance (Omega, ohms)")
    print ("\nT : temperature en kelvin (K)")
    input()
    menu ()
   
menu()

Les deux premiers sous-programmes calculent automatiquement vos résultats avec les données que vous aurez préalablement rentrées et le dernier sera juste là en tant qu’aide ou rappel.

Menu de sélection

aperçu du menu
def menu():
   
    print("\n--------MENU PRINCIPAL--------\n")
    print("1 - Convertir un nombre \n d'entites en mole")
    print("2 - Donner la composition \nfinale d'une reaction")
    print("3 - Registre des significatons \ndes lettres et symboles avec \n leur unite")
    choix=int(input("Choix =\t"))
    print()
    if choix==1:
        f1()
    elif choix==2:
        f2()
    elif choix==3:
        f3()
    else:
        print("Choix non valide\n")
        menu()

Le choix de l’aide se fait par un menu où il suffit de rentrer le nombre désiré (en l’occurrence 1, 2 ou 3). Si un autre nombre que ceux proposés est rentré, “Choix non valide” s’affichera et vous serez automatiquement redirigé vers le menu.

Sous programme 1 : Convertir un nombre d’entités en mole

aperçu choix 1
def f1():
    n = int(input("Donner le nombre d'entites a\n convertir:\t "))
    na = 6.02214076 * 10 ** 23
    r = n / na
    print("\n La quantite de matiere\n correspondante est\n %.3e"%r, "moles" )
    input ()
    menu ()

Ce programme sert comme son nom l’indique à obtenir une quantité d’atome en mole. Pour ce faire on demande simplement à l’utilisateur d’entrer un nombre d’atome que le programme divise par le nombre d’Avogadro.

Sous programme 2 : Donner la composition finale d’une réaction

aperçu choix 2 (1/2)
aperçu choix 2 (2/2)
def compo_finale(a,b,c,d,nx,ny):
    x=min(nx/a,ny/b)
    return nx-a*x,ny-b*x,c*x,d*x
 
def f2():
    A = int(input("Veuillez renseigner\n le coefficient A:\t"))
    B = int(input("\nVeuillez renseigner\n le coefficient B:\t"))
    C = int(input("\nVeuillez renseigner\n le coefficient C:\t"))
    D = int(input("\nVeuillez renseigner\n le coefficient D:\t"))
    n_x = int(input("\nVeuillez renseigner\n la quantite de matiere\n de A:\t"))
    n_y = int(input("\nVeuillez renseigner\n la quantite de matiere\n de B:\t"))
 
    nfA,nfB,nfC,nfD = compo_finale(A,B,C,D,n_x,n_y)
    print("Il reste %.3e"%nfA, "\nmoles de A\n")
    print("Il reste %.3e"%nfB, "\nmoles de B\n")
    print("Il reste %.3e"%nfC, "\nmoles de C\n")
    print("Il reste %.3e"%nfD, "\nmoles de D\n")
    input()
    menu()

Ce sous programme en renseignant les coefficients directeurs de A, B, C et D ainsi que la quantité de matière de A et B permet de calculer la composition finale d’une réaction.

Sous programme 3 : Registre des significations des lettres et symboles avec leur unité

aperçu choix 3
def f3():
    print ("m : masse de l'échantillon\n ou masse d'un corps (g)")
    print ("\nM : masse molaire de\n l'echantillon (g.mol-1)")
    print ("\nn : quantite de matiere (mol)")
    print ("\nV : volume d un corps\n (L ou m3)")
    print ("\nrho : masse volumique de la\n solution (g.L-1 ou kg.m-3)")
    print ("\nd : densite (sans unite)")
    print ("\nn : quantite de matiere (mol)")
    print ("\nCM: concentration molaire\n (mol.L-1)")
    print ("\nU : tension (V, volts)")
    print ("\nI : intensite du courant\n (A, amperes)")
    print ("\nR : resistance (Omega, ohms)")
    print ("\nT : temperature en kelvin (K)")
    input()
    menu ()
   
menu()

Le choix 3 est présent en tant qu’aide afin de savoir à quoi correspond chaque lettre ou symbole ainsi que l’unité qui l’accompagne.

Bonus

%.3e »%

Ce morceau de programme permet de présenter le résultat sous forme d’écriture scientifique avec trois chiffres après la virgule.

Télécharger le programme

Lien vers le script sur le Workshop Numworks : https://workshop.numworks.com/python/p3r50nne/pc1g

Projets

Une brève navigation dans l’espace sur python

Naviguez au cœur du système solaire, et découvrez les caractéristiques de chaque planètes qui le composent, soit, la période de révolution, la distance au soleil, la masse, le rayon et enfin les satellites connus (leur nombre) …

Ce projet est un programme réalisé sur python permettant de naviguer dans l’espace, et plus précisément dans notre système solaire. Il permet de découvrir les caractéristiques des planètes qui le compose, soit, la période de révolution, la distance au soleil, la masse, le rayon et enfin les satellites connus (nombre). Ce programme a été developpé sur omega et peut être téléchargeable sur la calculatrice Numworks via les liens hypertextes en bas de l’article.

Difficultés rencontrées…

À la genèse de notre projet, nous fûmes légèrement idéaliste quant à nos capacités, et à celles de la calculatrice ; nous voulions créer une animation, tel un court-métrage, avec l’histoire du big bang se déroulant sous nos yeux ébahis, puis la galaxie, et enfin atterrir dans notre système solaire, qui aurait été animé… Après un dur retour à la réalité, nous nous sommes accordées pour simplifier notre concept originel. Malgré avoir réalisé une deuxième couche graphique composée d’un trou noir ; Saggitarius A*, au centre de notre galaxie, et du système solaire, nous n’avons pu l’insérer dans le code initial.

Comment tout a commencé…

Notre programme a été conçu en deux grandes phases :

  • la couche graphique
  • l’interaction

La couche graphique

Premièrement, il a fallu tracer des cercles pour retrouver la forme des planètes, et insérer des dégradés afin de s’approcher au plus des couleurs initiales, en adoptant les modules mathkandinsky et random.Retour ligne automatique
Cette image a été le pilier de la création du fond graphique :

Pour ce faire, du à nos faibles connaissances en python, nous sommes allées nous renseigner auprès du célèbre Philippe Moutou.

def cercle(x0,y0,r,c,e):# fonction pour tracer contour du cercle
 for i in range(2*e):
   xd=x0-int((r-i*0.5)/sqrt(2))
   xf=x0+int((r-i*0.5)/sqrt(2))
   for x in range(xd,xf+1):
     x1=x
     y1=y0+int(sqrt((r-i*0.5)**2-(x-x0)**2))
     set_pixel(x,y1,c)
     for j in range(3):
       x2=x0+y1-y0
       y2=y0+x0-x1
       set_pixel(x2,y2,c)
       x1,y1=x2,y2
 
def cercle_plein(x0,y0,r,c1,e,c2): #remplir le cercle
 cercle(x0,y0,r,c1,e)
 cercle(x0,y0,r-e,c2,r-e)
 
def cercle_grade(x0,y0,R,c1,e,c2):#faire un dégradé de couleur
 for i in range(R):
   r=c1[0]+i*(c2[0]-c1[0])//R
   g=c1[1]+i*(c2[1]-c1[1])//R
   b=c1[2]+i*(c2[2]-c1[2])//R
   cercle(x0,y0,i,color(r,g,b),1)

Grâce à son génie, nous n’avons eu qu’à changer couleurs, rayons ou encore coordonnées dans les diverses fonctions, et créer des listes pour regrouper les différents globes, soit neuf au total en comptant l’astre qui nous fournit en énergie. Pour trouver les couleurs appropriées, nous nous sommes servies de code couleur html, afin de concevoir le plus précisément possible les textures.

Voici un exemple d’appel de fonction, qui a été fait pour chaque planète, et mis dans une liste pour simplifier le code :

cExt=[251,136,7]
cInt= [106,73,32]
cercle_grade(197,95,8,cExt,10,cInt)

Ensuite nous sommes passées à la conception du fond étoilé avec toujours l’aide de notre cher Moutou :

def degrade(c1,c2,k):
 dr=c2[0]-c1[0]
 dg=c2[1]-c1[1]
 db=c2[2]-c1[2]
 return color(c1[0]+int(k*dr),c1[1]+int(k*dg),c1[2]+int(k*db))
 
def tirage(n):
 for i in range(n):
   x=randint(0,320)
   y=randint(0,222)
   c=couleur(x,y)
   set_pixel(x,y,c)
   set_pixel(x+1,y,c)
   set_pixel(x,y+1,c)
   set_pixel(x+1,y+1,c)
 
def couleur(x,y):
 d=sqrt((x-160)**2+(y-111)**2)/32.5
 return degrade(c[int(d)],c[(int(d)+1)%6],d-int(d))

Il nous a suffit de changer les couleurs pour faire un magnifique dégradé galactique, et effectuer un tirage non exhaustif afin de révéler des points blancs.

c=[[235,128,0],[13,89,175],[13,89,175],[44,122,211],[207,230,230],[207,230,230]]
tirage(250)

Pour afficher les anneaux blancs qui représentent l’orbite de chaque planète, rien de plus simple, il suffit d’appeler la fonction traçant le contour d’un cercle.

Etant donné qu’il y a 8 planètes on se sert de la variable for in range :

c_blanc=[119,135,135]
r_orb = [22,32,42,52,62,76,92,109]
for i in range(8):
   cercle(160,111,r_orb[i],c_blanc,1)

Bien évidemment cet appel de fonction doit se faire après celui du fond étoilé, mais avant celui des planètes, pour que tout se superpose parfaitement.

Voici le résultat escompté après de maints efforts :

L’interactivité :

Méconnus du grand public, les modules time et ion ont été le support de cette interaction, utilisée pour naviguer entre les diverses planètes, grâce aux flèches du keyboard, numérotées de 0 à 3. En effet, grâce au getkey, disponible sur omega, qui est la capacité de la calculatrice à détecter si une touche est pressée, le déplacement devient envisageable.

Après plusieurs essais désastreux pour cette tâche plus complexe, nous avons chercher de l’aide auprès d’une source externe ; un grand mage.

Nous avons alors pu avoir accès à un fragment d’un de ses sortilèges que nous avons dû comprendre de nous même pour la suite de notre programme.

On définit tout d’abord dans une liste toutes les caractéristiques des planètes étudiées :

systeme = [ ("Soleil",'centre du sytème solaire','dis soleil: 0','masse: 1,989 × 10^30 kg','rayon: 696340 km', 'satellites connus: 0'),
           ("Venus",'periode de revo: 225 jours','dis soleil: 104 millions km','masse: 4,867 × 10^24 kg','rayon: 6051.8 km', 'satellites connus: 0'),
           #etc pour toutes les planètes
           ]
 
coord = [(160,111,16), (185,95,8)#etc...]
couleur1 = [[255,255,0], [190,183,150]#etc...]
couleur2 = [[235,128,0], [121,104,83]#etc...]

Ensuite on crée une fonction qui permet de tracer un rond blanc à la place de l’astre choisi lorsque degrade n’est pas égal à 1 (égal à un de base), sinon les astres restent tel quel.

def solar_systeme_dessine(n, degrade=1):
 # Affiche un corps du sytème solaire, numéro du corps dans systeme[], degradé
 p = 2 + 9 * (n != 0)
 if degrade == 1:
   cercle_grade(coord[n][0], coord[n][1], coord[n][2], couleur1[n], p, couleur2[n])
 else:
   cercle_grade(coord[n][0], coord[n][1], coord[n][2], [255,255,255], p, [255,255,255])

Avec l’ajout d’un code pour définir les touches et leur mouvement, ainsi qu’un autre pour afficher le texte voulu, on peut désormais naviguer entre les différents astres et voir leurs caractéristiques !

Conclusion

Pour pouvoir profiter du système solaire, il vous faudra donc télécharger le code via le lien en bas de page, et manipuler les flèches pour vous déportez sur les diverses planètes. Pour afficher les informations liées à chaque globe, vous manipulerez les flèches du haut et du bas. 
Bon exode planétaire !

La prochaine fois que quelqu’un se plaint que vous avez fait une erreur, dites-lui que c’est peut-être une bonne chose. Parce que sans imperfections, ni toi ni moi n’existerions.
Stephen Hawking

Télécharger et tester

Serveur Workshop de NumWorks tiplanet.org nsi.xyz 
RemarquesPermet un téléchargement rapide sur la calculatriceTéléchargement .pyTéléchargement .zip
Liens hypertexteslienNumWorks > Physique > Lien
Projets

Un site internet pour tester à la volée des…

Ici nous allons vous montrer un site internet pour essayer les codes HTML ; CSS ; javascript.

Introduction au projet

On ne voulait utiliser un site fait maison pour être sûr de pas se faire attaquer par le DNS du service informatique, qui peut arbitrairement décider de bloquer tel ou tel site web.

On a alors posé un cahier des charges :

  • Un site permettant de charger du HTML, du CSS et du JS.
  • Intuitif.
  • Un retour console pour le JS car c’est mieux que d’aller dans la console du navigateur.

Une fois fait, on s’est mis a coder, on était large, on avait 2 jours pour proposer au prof un outil clé en main.

Interface

L’idée de l’interface est simple :
<emb751|center>
En rouge : le site retour.
En bleu : les zones d’édition.
En noir : le bouton pour envoyer tout ce beau code

L’architecture est un système de div, très pratique pour la mise en page.
Afin de ne pas interférer avec le code éventuel des élèves, on donne des ID aléatoirement générés pour les parties vitales du site (inputs, outputs).

Le JavaScript

C’est la partie la plus importante du site.

Pour le bon fonctionnement du site, il nous faut 3 fonctions :

  • Une fonction de récupération de console.
  • Une fonction d’envoi du code.
  • Une fonction traitant le CSS à envoyer.

Récupération console

On réécrit la fonction console.log et on associe cette fonction à la fonction window.onerror.

<code class="javascript">Retour ligne automatique
console.log = function () Retour ligne automatique
// On recupère le message passé en argumentRetour ligne automatique
var message = [].join.call(arguments, " ") ;

// On crée un nouvel élément <div> qu'on ajoute dans le codeRetour ligne automatique
var div = document.createElement("div") ;Retour ligne automatique
div.appendChild(document.createTextNode(message)) ;Retour ligne automatique
document.getElementById("vfRDiMPLLlGMBuKV").appendChild(div) ;Retour ligne automatique
 ;

// Redéfinition de la fonction d'erreurRetour ligne automatique
window.onerror = console.log ;Retour ligne automatique
</code>

Fonction de traitement du CSS

On commence par convertir le CSS en une seule ligne.
Ensuite on split la chaine obtenue avec le charactère «  », ça nous permet d’avoir un Array contenant des strings commençant toujours par un objet à modifier en CSS ou une string vide.

Comme notre fenêtre visible et modifiable par les élèves porte l’ID « main », on ajoute « #main  » a chaque objet ou on remplace « body » par « #main » afin de n’affecter que la div main.

<code class="javascript">Retour ligne automatique
function convertCSS(code) Retour ligne automatique
code = code.replace("\n", "") ;Retour ligne automatique
code = code.replace("\r", "") ;Retour ligne automatique
var newCode = code.split("") ;Retour ligne automatique
for (var i = newCode.length ; i >= 0 ; i—) Retour ligne automatique
if (newCode[i] !== undefined && newCode[i] !== "") Retour ligne automatique
newCode[i] = newCode[i].replace(/^\s+|\s+$/g, "") ;Retour ligne automatique
if (newCode[i].startsWith("body")) Retour ligne automatique
newCode[i] = "#main " + newCode[i].substring(4) ;Retour ligne automatique
Retour ligne automatique
if (!newCode[i].startsWith("#main")) Retour ligne automatique
newCode[i] = "#main " + newCode[i] ;Retour ligne automatique
Retour ligne automatique
newCode[i] += "" ;Retour ligne automatique
Retour ligne automatique
Retour ligne automatique
return newCode.join("") ;Retour ligne automatique
Retour ligne automatique
</code>

Fonction d’envoi du code

On commence par clear la console.
Puis on envoie un retour console avec un id précis pour changer son style. Ce retour permet de nous assurer que le code a été envoyé.

On actualise les balises du site qui assurent le bon fonctionnement de la fenêtre main en prenant bien soin de traiter le CSS.

Problème principal lors de la réalisation de cette fonction :
Pour pouvoir modifier le JS de la fenêtre, il est indispensable de supprimer la balise < script > qui contient l’ancien JS. On ne peut pas juste réécrire le JS, sinon la cache ne s’actualise pas.

<code class="javascript">Retour ligne automatique
// Fonction d'envoi du codeRetour ligne automatique
var sendCode = function() Retour ligne automatique
document.getElementById("vfRDiMPLLlGMBuKV").innerHTML = "<p>Retour console</p>" ;Retour ligne automatique
// On crée un nouvel élément <div> qu'on ajoute dans le codeRetour ligne automatique
var div = document.createElement("div") ;Retour ligne automatique
div.id = "change" ;Retour ligne automatique
div.appendChild(document.createTextNode("Code envoyé !")) ;Retour ligne automatique
document.getElementById("vfRDiMPLLlGMBuKV").appendChild(div) ;Retour ligne automatique
// Changement HTMLRetour ligne automatique
document.getElementById("main").innerHTML = document.getElementById("html").value ;Retour ligne automatique
// Changement JSRetour ligne automatique
document.getElementById("toAdd").remove() ;Retour ligne automatique
var script = document.createElement("script") ;Retour ligne automatique
script.id = "toAdd" ;Retour ligne automatique
document.body.appendChild(script) ;Retour ligne automatique
document.getElementById("toAdd").innerHTML = document.getElementById("js").value ;Retour ligne automatique
// Changement CSS Retour ligne automatique
document.getElementById("maincss").innerHTML = convertCSS(document.getElementById("css").value) ;Retour ligne automatique
if(document.getElementById("html").value.toString().indexOf("<body onload=") !== -1)Retour ligne automatique
window[Retour ligne automatique
document.getElementById("html").value.substring(Retour ligne automatique
document.getElementById("html").value.toString().indexOf("\""Retour ligne automatique
,document.getElementById("html").value.toString().indexOf("<body onload="))+1Retour ligne automatique
,document.getElementById("html").value.toString().indexOf("("Retour ligne automatique
,document.getElementById("html").value.toString().indexOf("<body onload=")))]() ;Retour ligne automatique
Retour ligne automatique
</code>

Conclusion

Le site fut fini dans les temps et opérationnel !
https://workspace.nsi.xyz/

Projets

Un Sokoban pour la NumWorks

Le Sokoban est un jeu de puzzle inventé au Japon en 1982. Le principe est simple : vous êtes un gardien d’entrepôt et vous devez amener les caisses aux bons emplacement. Pour cela, vous pouvez uniquement pousser les caisses, et une seule à la fois.*

Une partie des informations de cette page sont extraites de la page Wikipédia Sokoban.
Si vous souhaitez creuser le sujet, n’hésitez pas à la consulter.

L’objectif du jeu est de résoudre les niveaux en un nombre minimum de déplacements. Par ailleurs, il existe des milliers de niveaux, pour la majorité créés par la communauté. En fonction de la taille et de la complexité de la grille, ainsi que de l’exigence de l’utilisateur pour réduire son nombre de coups, tous les niveaux de difficultés sont imaginables. Ces éléments donnent une grande durabilité au jeu.

En raison de son apparition rapide dans le monde du jeu vidéo, de sa simplicité apparente et de son intérêt toujours renouvelé, le jeu a connu un grand succès et a été développé sous de nombreuses versions et plateformes. A mon tour de le porter sur la calculatrice NumWorks !

Fonctionnalités

  • Aide (règles, touches, signification des couleurs) affichée au lancement et accessible à tout moment.
  • Ajustement de l’affichage à la taille de la grille.
  • Possibilité d’annuler les mouvements précédents.
  • Déplacement rapide.
  • Détection de la victoire.
  • Ajout et choix de niveaux facile (voir la section correspondante).

Lancer le jeu

Le moteur de jeu et le contenu (les niveaux) sont stockés dans des scripts séparés :

Pour jouer, il faut télécharger ces scripts et exécuter sokoban.py. Il vous est demandé de préciser la cartouche (liste de niveaux) à utiliser ainsi que le niveau auquel vous souhaitez commencer. Il n’est pas nécessaire de remplir ces champs, le jeu commencera par défaut au niveau 1 de la cartouche soko.

Ajouter des niveaux

Si vous venez à bout des 50 niveaux inclus dans la cartouche de base, vous pouvez en télécharger une autre sur le Workshop. Ils sont nommés soko1soko2, … Pour les utiliser, il suffit de rentrer le nom de la cartouche au lancement du jeu.

Une présentation détaillée de ce projet à été publiée sur tiplanet.org

Tutoriels

Lancer une machine virtuelle sur son ordinateur

Dans le cadre des cours de spécialité NSI, vous pouvez être amené à utiliser une machine virtuelle sur votre propre ordinateur. En informatique, une machine virtuelle (VM en anglais) est une illusion d’un appareil informatique créée par un logiciel d’émulation.

Une machine virtuelle, c’est quoi ?

D’après wikipédia

En informatique, une machine virtuelle (VM en anglais) est une illusion d’un appareil informatique créée par un logiciel d’émulation.

Le logiciel d’émulation simule la présence de ressources matérielles et logicielles telles que la mémoire, le processeur, le disque dur, voire le système d’exploitation et les pilotes, permettant d’exécuter des programmes dans les mêmes conditions que celles de la machine simulée

Une machine virtuelle, ça sert à quoi ?

D’après wikipédia

Un des intérêts des machines virtuelles est de pouvoir s’abstraire des caractéristiques de la machine physique utilisée (matérielles et logicielles — notamment système d’exploitation), permettant une forte portabilité des logiciels et la gestion de systèmes hérités étant parfois conçus pour des machines ou des environnements logiciels anciens et plus disponibles.

Les machines virtuelles sont également utilisées pour isoler des applications pour des raisons de sécurité, pour augmenter la robustesse d’un serveur en limitant l’impact des erreurs système ou pour émuler plusieurs machines sur une seule machine physique (virtualisation).

Les inconvénients des machines virtuelles sont d’une part des performances brutes sensiblement inférieures à une exécution sur le matériel en natif (ce qui peut rendre malaisé le test de jeux 3D), d’autre part de consommer une petite partie de la mémoire réelle pour leur propre fonctionnement. Leurs avantages sont de permettre des tests de variantes d’installation sur des machines simulées possédant des tailles de RAM, de mémoire graphique, et des nombres de processeurs très divers.

Une machine virtuelle en spé NSI

Le programme de la spé NSI comporte une partie qui traite des système d’exploitation, de leurs fonctionnalités et de l’utilisation du mode console d’un OS.

Pour des raisons de sécurité, sur les ordinateurs du lycée, est bloqué :

  •  le mode console 
  • la possibilité d’installer un nouvel OS 
  •  l’accès administrateur

Manipuler une machine virtuelle permet de disposer d’une machine sur laquelle on peut installer un système libre (Ubuntu sera choisit pour sa simplicité), et sur ce système d’exploitation vous serez administrateur (vous pourrez donc tout casser par exemple, ou installer un virus (si vous y arrivez) sur votre machine virtuelle sans pour autant contaminer votre système d’exploitation natif.

Mon ordinateur peut-il faire tourner une machine virtuelle ?

Le fonctionnement (ou le non fonctionnement) d’une VM dépend des éléments suivants :

  • processeur : Si votre processeur est très vieux ou très peu puissant, il ne pourra pas faire tourner une machine virtuelle.
  • Chipset : Certains chipset peuvent bloquer mais en général il s’agit plus d’un réglage à faire dans le BIOS
  • BIOS : Il est parfois nécessaire d’accéder au BIOS et d’y modifier un paramètre.
  • Système d’exploitation

Mon processeur est-il capable de faire tourner une machine virtuelle ?

L’article sur le site du fabricant de processeur intel est particulièrement bien écrit : 
Processeur Intel

Si vous n’arrivez pas à faire tourner une machine virtuelle, dans 90% des cas la solution sera de modifier un paramètre du BIOS de votre carte mère.

Modifier le BIOS pour faire tourner une machine virtuelle

D’après wikipédia

Le BIOS, de l’anglais Basic Input Output System (en français : « système élémentaire d’entrée/sortie ») est un ensemble de fonctions, contenu dans la mémoire morte (ROM) de la carte mère d’un ordinateur, lui permettant d’effectuer des opérations de base, lors de sa mise sous tension. Par exemple l’identification des périphériques d’entrée/sortie connectés et la lecture d’un secteur sur un disque, un CD ou une partie d’une clé USB.

Par extension, le terme est souvent utilisé pour décrire l’ensemble du micrologiciel de la carte mère.

C’est en quelque sorte le centre de contrôle de la carte mère. Sur les cartes récentes il est remplacé par sa version moderne l’UEFI.

Si au lancement de la machine virtuelle, vous avez ce message d’erreur :

Alors voici les grandes lignes de ce qu’il va falloir faire :

  1. Trouver le moyen d’accéder au BIOS de son ordinateur
  2. Trouver le bon paramètre, et le modifier
  3. Sauvegarder le nouveau paramétrage du BIOS
  4. Redémarrer la machine physique

1. Accéder au BIOS

Pour accéder au BIOS, la procédure change selon la marque, l’année de votre ordinateur, son installation…

Si ce tutoriel marche :
How to enable virtualisation vt-x/amd-v on windows 10 (in bios) suivez le !

Paramètres Windows > Mise à jour et sécurité > Récupération > Démarrage avancéRetour ligne automatique
puis : Retour ligne automatique
Dépannage > Options avancées > Changer les paramètres du microprogramme UEFI

Si cette méthode ne marche pas, il faudra spammer au redémarrage les touches permettant d’accéder au BIOS, souvent la touche « Suppr », « Del », « F2″…

BIOS – Accéder au setup du Bios

2. Trouver le bon paramètre

Ne modifiez que ce que vous comprenez.

La paramètre à modifier peut se cacher vous divers noms. 
Les deux captures d’écrans réalisées par Metais R. et Fernando L. pourront vous aider dans cette recherche.

3. Sauvegarder le nouveau paramétrage du BIOS

Vous devez sauvegarder ce nouveau réglage avant de redémarrer le PC.

4. Redémarrer la machine physique

Sur Windows 10 > Démarrer le gestionnaire de tâche et vérifier que la virtualisation est activé.

Autres débogage

Si cela ne marche toujours pas, pas de panique. Essayez les stratégie ci-dessous :

1. Désactiver Hyper-V dans les fonctionnalités de Windows

Désactiver = la case doit être décochée !

2. Modifier les paramètres de la machine virtuelle elle même

Procédure à venir …

Projets

Un Tetris en python pour la NumWorks

Tout le monde sait qu’une calculatrice programmable sert à jouer à des jeux. Or quand on parle de jeux, un des premiers à nous venir en tête est Tetris, alors pourquoi pas un Tetris pour NumWorks ?

Ainsi, après un démineur, un snake, on vous propose cette fois ci le jeu mythique de la Gameboy adapté en flat design et codé en python pour la NumWorks.

Donne moi 32 ko, je te ferai un Tetris !

Jusqu’à la version 13.2 d’Epsilon, l’OS officiel de la NumWorks, faire un jeu en python sur la couche graphique de la NumWorks était impossible et les scripts commençaient à planter dès qu’ils pesaient 3-4 ko.

Avec un tas python heap de 32 ko, on peut enfin commencer à s’amuser et monter des projets dont le code source pèse près de 8ko.

Le récit de la création d’un jeu en image

Tout commença le 19 avril 2020 dans une nuit confinée.

🧐 Bon on vient de finir nos trois projets en python, on fait quoi maintenant ?
🤓 Oh on peut acheter des contrefaçon de Gameboy sur Aliexpress pour 10€ ! Et il y a 400 jeux dedans.
🧐 La nuit porte conseil, on en parle demain, enfin dans quelques heures !

Le lendemain :

🧐 Bon on fait un Tetris. Je viens de lire l’article sur Wikipédia, c’est passionnant. Par contre par un mot à Arthur, il va nous piquer notre idée sinon. Et cette fois, on ne stocke pas coordonnées des cases occupées dans des matrices, et on va utiliser la fonction get_pixel() de la NumWorks pour déterminer si une case est occupée ou non.

et c’est ainsi qu’un premier Tétrominos apparaît à l’écran.

🤓 J’ai peut être fini la collision
🧐 Hein ?! Mais j’ai pas commencé moi…
🧐 Bon je partage l’écran. Qu’est ce qu’on a dit déjà ? 120 pixels pour le menu, 120 pixels pour le score et 42 pixels pour le jeu en lui même c’est bien ça ?


🧐 Bon je viens de finir la maquette d’une ébauche de menu, reste à le coder !
🤓 et moi je viens de finir les collisions …
🧐 Pour les couleurs ça sera délicat et subtil. On va s’écarter du code couleur original.

🧐 Et du coup on va faire un rappel dans le menu
🤓 On fixe les points d’ancrage dans les pièces, et ainsi elles peuvent tourner

Rendu final souhaité (et obtenu)

🤓 Astuce : Si tu joues sur Omega, alors l’interface du jeu n’est plus orange mais rouge, elle s’adapte au fork de Epsilon.

🧐 D’ailleurs faudra que je relance l’équipe de développement de Omega, ils m’ont promis un tas python de 120 ko et j’ai l’impression que ce projet n’avance pas !
🧐 Bon ils sont encore sur répondeur, ils ont du bloquer mon numéro !
🤓 On fait une pause, j’ai envie de jouer un peu :

🧐 Bon je vais spoiler Critor de tiplanet.org mais toujours aucune info à Arthur !
🤓 Score codé, avec des fonctions polynôme et les points marqués dépendent du niveau du jeu …
🧐 Niveau max : 99, Score max : 999 999
🤓 Vitesse du jeux codé, avec une fonction logarithme népérien car un polynôme n’était pas adapté …

🧐 Bon maintenant s’agit de faire un gros score, histoire d’être certain que Critor ne nous batte pas !

Commencé un dimanche, fini le mercredi suivant, c’était presque trop facile !

🧐 Je reviens, je vais conseiller à Critor de commencer level 42, ça plantera son score !

Meilleurs scores

🧐 Il a commencé sa partie directement au niveau 42, du coup son score est à peine acceptable !🤓 En plus, il a triché ! Il a utilisé une vision prédictive triple et la grille d’aide !

Bien évidemment, il a nié avoir triché 🙄

Je ne les ai même pas utilisés, c’était pour mettre à l’écran le maximum d’éléments visuels, car j’étais parti pour l’utiliser également comme photo d’illustration d’article

Xavier Andréani, alias Critor du tiplanet.org

Mais nous ne sommes pas dupes non plus !

Réagir ou commenter ce jeu

N’hésitez à réagir à cet article sur le forum tiplanet.org associé :
Tetris en Python pour NumWorks 13.2.0+

Vous pouvez également réagir à l’annonce de ce Tetris posté sur twitter :