Author: 1ère spé NSI 2021- 2022

Projets

Le jeu Plateforme sur la NumWorks en python

Le but du jeu est simple, se déplacer de plateformes en plateformes en essayant d’atteindre la plateforme finale située a la fin du niveau.

Ce jeu est uniquement jouable sur numworks car nous avons utilisé des fonctions uniquement disponible sur numworks.

Pour réaliser notre projet sur Numworks , nous avons eu besoin de plusieurs modules . Nous avons eu en premier temps besoin du module kandinsky qui nous a permis de réaliser les graphismes du jeu. Ensuite nous avons utilisé le module random pour permettre la génération aléatoire des placements des plateformes et de leur taille . Nous avons aussi utilisé les modules ion et time pour définir les touches qui vont nous permettre de jouer et pour définir le temps d’affichage des cinématiques lors de la mort et la victoire.

Le jeu :

Lorsque l’on lance le jeu sur numworks, des plateformes se génèrent aléatoirement et il faut utiliser les flèches pour sauter de plateformes en plateformes jusqu’à atteindre la dernière plateforme d’un niveau.

L’image si dessous correspond a la fin du niveau, avant de sauter sur la plateforme verte, dernière plateforme du niveau.

Les animations :

Une fois sauté sur la plateforme verte, une rideau va descendre et afficher le texte suivant :

Le code ci dessous correspond a l’animation de la victoire. Un rideau vert va s’abaisser. Nous avons créé un rectangle d’un pixel de hauteur et de 32O pixels de large (largeur de l’écran de la calculatrice). Ce rectangle va se répéter 222 fois (hauteur de l’écran de la calculatrice) avec un écart de 0,01 seconde entre chaque rectangle pour faire un effet d’animation.

Mais attention ! Si vous tombez avant la plateformes verte, dans les piques situés en bas de l’écran, un rideau gris apparaitra et une animation aura lieu a :

Le code ci dessous correspond a l’animation lorsque l’on meurt. C’est le même principe que pour l’animation de la victoire mais ici on a codé la tête de mort en plus. Elle se créée avec le module kandinsky en créant des carrés et rectangles. Nous avons également placé une pause de 0,3 seconde entre chaque carré ou rectangle pour accentuer l’animation.

Pour se deplacer de plateformes en plateformes nous avons décidé de créer un personnage. Cette création s’est faite en plusieurs étapes

Les personnages :

personnage statique :

Ce dessin est celui qui a été fait avant de réaliser le personnage sur kandinsky . Nous avons mis en évidence un des rectangles composant le dessin , je l’ai mis en coordonnées 1 et 3 sur le tableau présent sur le croquis pour déterminer les coordonnées à mettre dans le script . Sur la feuille , un carreau représente un carré de 1 par 1 . Le rectangle dessiné à gauche est fait de 2 carrés côte à côte donc le rectangle aura une longueur de 2 pour une hauteur de 1 . Donc si je veux que ce rectangle soit noir , en kandinsky cela donnera :

personnage en mouvement :

Ainsi de même pour le personnage qui cours nous avons mis un autre rectangle en évidence qui sera formé à partir de :

personnage qui saute :

Enfin pour le personnage qui saute , la même règle s’applique et le premier rectangle composant le personnage est fait grâce à : 

Les bases du jeu :

Maintenant la question que vous vous posez surement est: « Comment le niveau se génère aléatoirement ? ».

D’abord, voici le code permettant de réaliser une telle action :

Dans ce code, on peut d’abord remarquer que nous avons décidé de nommer la fonction de génération « randomlevel ». Cette fonction prend en compte 3 listes : « x », « y » et « l ». A titre d’exemple, la première plateforme du jeu aura comme coordonné en x la première variable de la liste « x », aura comme coordonné en y la première variable de la liste « y » et aura comme longueur la première variable de la liste « l ». La première boucle « for » permet de faire répéter la génération aléatoire 15 fois pour obtenir 15 plateformes vu que levell = 15. La première ligne dans cette boucle permet d’insérer la longueur aléatoire se comprenant entre 10 et 80 pixels dans « l ». Ensuite, on a fait en sorte que la première plateforme apparait toujours à une hauteur comprise entre limitup (31) et limitdown (191) et qu’elle apparaisse à une distance de 100 pixels du bord. Pour ne pas rentrer trop dans les détails, on peut dire que le reste du code permet de générer les plateformes a des distances raisonnables les unes des autres pour que les sauts ne soient pas trop long donc impossibles.

Enfin vous vous demandez peut être comment le jeu fonctionne en général ? Ce passage montre bien comment il fonctionne:

Ici on remarque d’abord le « while game == 0: » . Cela permet de faire répéter le programme ci dessus indéfiniment tant que le joueur n’a pas gagné ou n’est pas mort. En effet « break » nous permet de sortir de cette boucle quand le joueur gagne ou perd. Les mouvements pour avancer et reculer sont coder grâce à la logique « if » qui permet à la troisième ligne et à la huitième ligne de réaliser une action quand une touche spécifique de cette dernière est pressée. Dans notre jeu le personnage n’avance pas vraiment. En fait ce sont les plateformes qui bougent mais on a l’impression que c’est le personnage. Cette illusion est utilisée dans presque tout les jeux de plateforme en 2D connus. Ensuite nous avons créer un système de gravité qui fait que le personnage tombe et retombe après un saut. Ce système a été nommé gravityleft et gravityright. Ces deux lignes récupèrent la couleur au pied du personnage. Si la couleur est la couleur d’une plateforme, le personnage ne tombe pas. Si la couleur est la couleur du vide, le personnage tombe. Si la couleur est couleur des piques, le personnage meurt. Si la couleur est la couleur de l’arrivée, le joueur gagne.

Nous pensons que vous avez compris l’idée globale du code maintenant et qu’il est très peu utile de s’intéresser à tous les petits détails. C’est pour cela que c’est à vous de teste le jeux maintenant. Bonne cession !

Conclusion :

Nous espérons que ce jeu vous aura plus et qu’il vous aura donné du fil à retordre !! Nous avons cependant un bug qui ne peut se résoudre car le bug vient de numwork. 

Liens vers le jeu :

https://my.numworks.com/python/charlie18-coquel/jeu_de_platforme

Image mise en avant de notre projet Projets

Un jeu terrifiant revisité en python

Un projet basé sur le jeu de billes de Squid Game

Jeu des billes Squid Game

Présentation

Notre projet repose sur les consignes et conseils que nos professeurs de spécialité NSI nous ont donnés. Nous avons fait le choix du jeu des billes dans Squid Game puisque nous avons adoré cette série et que c’est un jeu qui nous semblait intéressant à développer en python.

Règles du Jeu

Pour cela nous allons tout d’abord faire une brève explication des règles du jeu : Les joueurs doivent deviner combien l’autre joueur à de billes dans la main, si le nombre est pair ou impair. Ils misent un nombre de billes de leur choix. S’il gagne, il remporte une partie des billes de l’adversaire, alors que s’il perd il doit lui donner une partie des siennes, que la personne a misé. Le premier qui n’a plus de billes a perdu la partie.

Extrait de l’épisode

Petite représentation du jeu dans la série

Explication des lignes de code

L’importation du module random

from random import randint

Le module random est un module qui regroupe des fonctions permettant de simuler le hasard. Si nous avons fait le choix de ce module c’est qu’il est indispensable dans notre jeu car l’ordinateur doit faire diffèrent choix. Grâce à ce module il est fait donc au hasard.

Définition du nombre de bille de l’ordinateur et du joueur

nb_bille = [10, 10]

Création d’un tuple dans le but de définir les nombres de billes du joueur et de l’ordinateur

Le choix du jeu et de la mise de l’ordinateur

def choix_mise_ordi():  # Definie la mise de l'ordinateur
    print("A l'ordinateur de miser\nIl a miser")
    return randint(1, nb_bille[0])


def choix_jeu_ordi(): # Definie le choix du jeu de l'ordinateur
     print("A L'ordinateur de choisir\nIl a fait ses jeu")
     choix_jeu_comp = randint(1, nb_bille[0])
     if choix_jeu_comp % 2 == 0:
        nb_comp = "pair"
     else:
        nb_comp = "impair"

Ici nous pouvons voir deux fonctions qui définissent la mise et le jeu de l’ordinateur qui se repose sur le module random.

Le choix du jeu et de la mise du joueur

def choix_mise_joueur(): # Definie le choix de la mise du joueur
    choix_mise = int(input("A vous de miser\nCombien voulez vous miser : "),nb_bille[1])
    return choix_mise


def choix_jeu_joueur():
    choix_jeu = int(input("A vous de jouer\nCombien de bille voulez vous jouez : "),nb_bille[1])
    return choix_jeu

Contrairement au script du dessus ici on va demander au joueur de rentrer sa mise et son jeu donc le module random n’est pas nécessaire.

Déduction du joueur et de l’ordinateur

ef deduction_joueur(): # Definie si le joueur pense que l'ordinateur a choisi un nombre pair ou impair
     choix_deduction = int(input("--- Selon vous l'ordinateur a choisi un nombre paire ou impaire ---\n""Tapez 0 si vous pensez que c'est un nombre pair et tapez 1 si vous penser que c'est un nombre impair\n""Votre choix : "))
     if choix_deduction  % 2 == 0:
        print("Vous avez tapé {0}, tu penses donc que l'ordinateur a choisi un nombre de bille pair".format(choix_deduction))
        nb_gamer = "paire"
     else:
        print("{0} est Impair, donc tu penses qu'il a un nombre de bille impair".format(choix_deduction))
        nb_gamer = "impair"
        return nb_gamer


def deduction_ordi(): # Definie si l'ordinateur pense que le joueur a choisi un nombre pair ou impair
     choix_deduction = randint(1, nb_bille[0])
     if choix_deduction % 2 == 0:
        nb_comp = "pair"
     else:
        nb_comp = "impair"
        return nb_comp

Ces fonctions nous permettent de définir les déductions du joueur et de l’ordinateur en fonction du jeu qu’ont fait ses derniers.

Résultat des jeux et incrémentation des points

def resultat_joueur():
    deduction_gamer = deduction_joueur()
    choix_mise_gamer = choix_mise_joueur()
    choix_jeu_computer = choix_jeu_ordi()
    
    if   deduction_gamer == choix_jeu_computer:# incrementation des billes de l'ordinateur vers le joueur
            print("Vous avez gagné, vous avez",nb_bille[1],"billes")
            nb_bille[1] += choix_mise_gamer
            nb_bille[0] -= choix_mise_gamer
    else:                                    # incrementation des billes du joueur vers l'ordinateur
        print("Vous avez perdu, il vous reste",nb_bille[1],"billes")
        nb_bille[1] -= choix_mise_gamer
        nb_bille[0] += choix_mise_gamer


def resultat_ordi():
    deduction_comp = deduction_ordi()
    choix_mise_comp = choix_mise_ordi()
    choix_jeu_gamer = choix_jeu_joueur()
     
    if   deduction_comp == choix_jeu_gamer: # incrementation des billes de l'ordinateur vers le joueur
            print("Vous avez perdu, il vous reste",nb_bille[1],"billes")
            nb_bille[0] += choix_jeu_gamer
            nb_bille[1] -= choix_jeu_gamer
    else:                                    # incrementation des billes du joueur vers l'ordinateur
        print("Vous avez gagné, vous avez",nb_bille[1],"billes")
        nb_bille[0] -= choix_mise_comp
        nb_bille[1] += choix_mise_comp   

Ces fonctions sont les fonctions finales de notre jeu, elles reprennent toutes les fonctions précédentes. De plus il y a l’incrémentation des points.

Les erreurs qu’on a pu faire

  • Un mauvais choix de jeu dans un premier temps car nous voulons faire à la base le 1, 2, 3 soleil de Squid Game
  • Une interface graphique Tkinter impossible à notre niveau et pas forcément utile pour notre jeu

Les changements qu’on a dû réaliser

  • Changement de jeu pour un plus réalisable
  • abandonner idée de l’interface avec Tkinter
  • Se donner des rôles avec son binôme

Nos astuces

Notre première astuce est celle de regarder des vidéos sur YouTube dans le but de s’améliorer en python puisque nous ne sommes pas très fort.

La seconde est celle de rechercher quelques informations sur internet

Conclusion

Ce projet nous a permis d’apprendre beaucoup de choses dans des domaines différents, que l’on ne savait pas au préalable donc un grand merci a nos professeurs.

Projets

Une partie de Blackjack en Python

Les jeux d’argent ont beau être peu recommandables, il n’empêche qu’ils restent assez divertissants ; et afin de pouvoir y participer depuis chez soi, sans la moindre répercussion sur son compte en banque, je vous propose une partie de Blackjack grâce à un script en Python ! Vous pouvez miser de la fausse monnaie à votre guise ou simplement jouer pour le plaisir. Serez-vous capable de battre le croupier à plat de couture ?

Un dilemme vite résolu

Ma première idée pour ce projet était entièrement différente ; et, à vrai dire, j’avais véritablement l’intention d’opter pour elle. Seulement, l’intitulé de ce devoir était « Une programmation fonctionnelle en Python ». Mon plan initial s’est avéré très peu adapté à cette problématique ; par conséquent, j’ai préféré me rabattre sur mon second choix : le jeu du Blackjack.

De toute manière, mon idée de base était un tantinet trop ambitieuse pour le type de projet qui était à réaliser : je ne regrette pas ma décision de la changer.

Quelques recherches avant de débuter

Je ne pouvais guère me lancer dans l’écriture de mon script avant d’être certain de connaître les règles du Blackjack. Quelques recherches en ligne m’ont permis rapidement de déterminer les points importants à intégrer :

Les tours :

Le joueur commence. Il débute son tour en tirant deux cartes dont les points constituent son score de base. Ensuite, il a le choix de piocher ou non une nouvelle carte. S’il décide de le faire, les points de la carte sont ajoutés à son score ; sinon, il termine son tour. Son but est d’obtenir le score le plus élevé possible sans jamais dépasser vingt-et-un. Si c’est le cas, son tour s’arrête directement.

Ensuite, c’est au croupier de jouer. Dans un véritable casino, ses règles diffèrent légèrement de celles du joueur ; mais par souci de simplicité, j’ai préféré lui donner les mêmes. Son but est d’obtenir un score supérieur à celui du joueur, ou, au moins, de faire égalité.

Lorsque les deux tours touchent à leur fin, on compte les points. Celui qui en possède le plus sans dépasser vingt-et-un est déclaré vainqueur. Il est possible de faire égalité.

Les points :

Chaque carte possède son propre nombre de points :
– de deux à neuf : autant de points que le nombre affiché sur la carte.
– de dix à roi : 10 points.
– As : 1 ou 11 points (au choix du joueur).

Les mises :

Le joueur mise en début de partie une somme ne pouvant dépasser un certain montant. Ce dernier différant de casino en casino, je l’ai réglé à cent-cinquante euros.

Dans un véritable casino, le joueur a la possibilité de doubler sa mise , ou bien d’abandonner et d’en perdre la moitié, en pleine partie ; toutefois, j’ai pris la liberté de ne pas intégrer cette fonctionnalité afin de ne pas compliquer le jeu.

Si le joueur gagne, il récupère le double de sa mise ; en revanche, s’il perd, il ne la recouvre pas. En cas d’égalité, rien ne se passe.

J’ai consigné toutes ces règles dans mon script, affichées au gré du joueur.

Les premiers tests

Je n’ai pas voulu plonger tête première dans l’écriture de mon code sans avant tout faire quelques essais.

Je n’ai intégré que trois cartes au départ : l’as, le deux et le trois, respectivement à un, deux et trois points.

paquet = ("as","deux","trois")
points = (1, 2, 3)
score_joueur = 0

En créant deux n-uplets et en faisant correspondre le nom des cartes avec leur nombre de points, je pouvais aisément créer un système de pioche grâce au module random et donner le nom et les points de la carte tirée.

carte = randint(0,2) # piochage d'une carte au hasard
print("Votre première carte est un", paquet[carte])
score_joueur += points[carte] # points de la carte ajoutés au score du joueur

carte = randint(0,2)
print("Votre seconde carte est un", paquet[carte])
score_joueur += points[carte]

print("Votre score de base est de", score_joueur)

Lorsque la variable « carte » est égale à 0, par exemple, elle prend le premier item du n-uplet « paquet » et « points » qui correspondent respectivement à « as » et « 1 ». En revanche, si, pour la seconde carte, la variable « carte » vaut 2, elle prend le troisième item des deux n-uplets qui est « trois » et « 3 ». Une autre variable « score_joueur » récupère les points gagnés afin de constituer le score.

Dans cette situation, le script afficherait :

J’ai ainsi codé le début du tour du joueur.

Afin de respecter l’intitulé du projet (« Une programmation fonctionnelle en Python »), j’ai placé cette partie de code dans une fonction que j’ai nommée « base() ». J’ai également rendu la variable « score_joueur » globale de sorte qu’elle soit utilisable dans toutes les fonctions.

paquet = ("as","deux","trois")
points = (1, 2, 3)
score_joueur = [0]

def base():
    carte = randint(0,2) # piochage d'une carte au hasard
    print("Votre première carte est un", paquet[carte])
    score_joueur[0] += points[carte] # points de la carte ajoutés au score du joueur
    carte = randint(0,2)
    print("Votre seconde carte est un", paquet[carte])
    score_joueur[0] += points[carte]
    print("Votre score de base est de", score_joueur[0])
    
base()

Et, à partir de cette base, j’ai codé la partie « joueur » du jeu.

La partie « joueur »

Puisque le système qui met en place le score de base était déjà intégré, je me suis ensuite attelé au codage du reste du tour.

Selon les règles du Blackjack, le joueur décide s’il souhaite piocher une nouvelle carte ou non tant que son score est inférieur à vingt-et-un. Subséquemment, j’ai repris le code de la fonction « base() » dans une nouvelle fonction nommée « choix_joueur() » et ajouté une condition pour qu’il soit exécuté :

def choix_joueur():
    while score_joueur[0] < 21: # tant que le score du joueur est strictement inférieur à 21, il peut continuer de piocher
        ch = input("[Voulez-vous piocher ?] " )
        if ch == "o": # si le joueur continue de piocher
            carte = randint(0,2) # piochage d'une carte au hasard
            print("Vous piochez un", paquet[carte])
            score_joueur[0] += points[carte] # points de la carte ajoutés au score du joueur
            print("Votre score est de", score_joueur[0], "\n")
        elif ch == "n": # si le joueur cesse de piocher
            print("Vous décidez de vous arrêter.")
            break

Ce script peut, par exemple, afficher :

Afin que cette fonction se lance, je l’ai appelée à la fin de « base() » :

def base():
    carte = randint(0,2) # piochage d'une carte au hasard
    print("Votre première carte est un", paquet[carte])
    score_joueur[0] += points[carte] # points de la carte ajoutés au score du joueur
    carte = randint(0,2)
    print("Votre seconde carte est un", paquet[carte])
    score_joueur[0] += points[carte]
    print("Votre score de base est de", score_joueur[0])
    score_joueur() # suite du tour

Si le joueur dépasse le score de vingt-et-un, il perd automatiquement. J’ai, de ce fait, défini une fonction « defaite() » qui est appelée si le joueur va trop loin :

def choix_joueur():
    while score_joueur[0] < 21: # tant que le score du joueur est strictement inférieur à 21, il peut continuer de piocher
        # [...]
    if score_joueur[0] > 21:
    	defaite()

def defaite(): # lorsque le joueur perd
    print("Vous avez perdu...")

En revanche, si le joueur tombe pile sur vingt-et-un, il ne gagne pas automatiquement puisque le croupier pourrait faire égalité ; à la place, le jeu passe directement au tour du croupier et ne laisse pas le choix de tirer ou non une nouvelle carte. Étant donné que cesser de piocher et atteindre le score de vingt-et-un ont les mêmes conséquences, j’ai regroupé ces deux conditions en une seule :

    if score_joueur[0] > 21:
    	defaite()
    else:
        choix_ordi()

(La fonction « choix_ordi() » sera détaillée dans la prochaine partie : elle correspond au tour du croupier.)

Avec le codage du tour du joueur terminé, je pouvais désormais m’affairer à celui du croupier.

La partie « croupier »

Une fois la partie « joueur » créée, il ne suffisait que de recopier son code et de lui retirer son interactivité afin de programmer la partie « croupier ».

Ainsi, j’ai définie la fonction « choix_ordi » (montrée dans la partie précédente) et ajouté une nouvelle variable globale que j’ai nommée « score_ordi ». Le croupier continue de piocher tant qu’il n’a pas dépassé le score du joueur.

paquet = ("as","deux","trois")
points = (1, 2, 3)
score_joueur = [0]
score_ordi = [0]

def base():
	#[...]

def choix_joueur():
	#[...]

def choix_ordi():
    carte = randint(0,2) # piochage d'une carte au hasard
    print("La première carte du croupier est", paquet[carte])
    score_ordi[0] += points[carte] # points de la carte ajoutés au score du croupier
    carte = randint(0,2)
    print("La seconde carte du croupier est", paquet[carte])
    score_ordi[0] += points[carte]
    print("Le score de base du croupier est de", score_ordi[0], "\n")
    while score_ordi[0] < score_joueur[0]: # le croupier ne cessera pas de piocher tant que son score est inférieur à celui du joueur
        carte = randint(0,2)
        print("Le croupier pioche", paquet[carte])
        score_ordi[0] += points[carte]
        print("Le score du croupier est de", score_ordi[0], "\n")
    if score_ordi[0] > 21: # si le score du croupier dépasse 21, le joueur gagne automatiquement
      	reussite()
    else:
        print("Le croupier décide de s'arrêter.")
        defaite()

def defaite(): # lorsque le joueur perd
    print("Vous avez perdu...")

def reussite(): # lorsque le joueur gagne
  	print("Vous avez gagné !")

J’ai également créé la fonction « reussite() » qui est appelée lorsque le joueur gagne la partie.

La partie « croupier » m’a amené à réfléchir à l’intelligence artificielle de mon ordi. Oui, il est logique qu’il cesse de piocher lorsque son score est supérieur à celui du joueur et qu’il ne le fasse pas avant ; mais s’il tombe pile sur son score ? Devrait-il continuer et peut-être dépasser vingt-et-un où devrait-il s’arrêter ? En prenant en compte le système de mise d’argent, je me suis rendu à l’évidence qu’il valait mieux que, à un certain stage, si les deux scores sont identiques, le croupier ne tente pas sa chance.

J’ai donc complété la boucle while de la fonction afin qu’elle corresponde à mes attentes et est défini une nouvelle fonction : « egalite() ».

def choix_ordi():
    # [...]
    while score_ordi[0] <= score_joueur[0]:
        if score_ordi[0] == score_joueur[0]:
            if score_joueur[0] >= 15:
                break # si le score du croupier est égal à celui du joueur et est supérieur ou égal à 15, il cesse de piocher automatiquement
       # [...]
    if score_ordi[0] > 21:
    	reussite()
    else:
      	print("Le croupier décide de s'arrêter.")
      	if score_ordi[0] > score_joueur[0]:
      		defaite()
      	else:
      		egalite()

def egalite():
  	print("Vous avez fait égalité.")

Désormais, si le croupier fait un score identique à celui du joueur, il arrête de piocher s’il est au minimum à quinze ; sinon, il continue. Mon résonnement est simple : lorsque j’implémenterai le reste des cartes (partie suivante), il y aura plus de chances de dépasser vingt-et-un en piochant une carte à partir de quinze que non. Le croupier ne préfère pas tenter le diable.

Par ailleurs, un problème assez flagrant est visible à l’affichage de ce code, dans la console : tout le texte qui décrit le tour du croupier est imprimé en une fois, sans laisser le temps au joueur de lire.

(Texte imprimé en un coup.)

Le rythme d’affichage sera réglé plus tard, dans la partie « Les finitions ».

Le reste des cartes

Une fois la structure du jeu quasiment terminée (ne manquant que le système de mises et de banque qui sera traité dans la prochaine partie), je me suis décidé à ajouter le reste des cartes.

paquet = ("as","deux","trois","quatre","cinq","six","sept","huit","neuf","dix","valet","dame","roi")
points = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10)

Bien entendu, je ne me suis pas soucié de la couleur de chacune étant donné que seule la valeur importe dans le jeu du Blackjack.

D’autre part, j’ai changé le système de pioche en écrivant :

carte = randint(0,12)

Une fois le paquet entier codé, j’ai constaté un problème avec la carte « dame ». Lorsque cette dernière était piochée, il était affiché :

« Vous piochez un dame ». Quand bien même cette erreur est anodine, j’ai préféré la régler directement. De ce fait, j’ai modifié le n-uplet contenant le nom des cartes en ajoutant le bon article :

paquet = ("un as","un deux","un trois","un quatre","un cinq","un six","un sept","un huit","un neuf","un dix","un valet","une dame","un roi")

Ensuite, j’ai retiré les mots qui compromettaient cette nouvelle organisation :

print("Vous piochez", paquet[carte]) # au lieu de "print("Vous piochez un", paquet[carte])"

Le cas de l’as

Selon les règles du Blackjack, lorsqu’un as est tiré, le joueur peut choisir entre un et onze points. Par souci de fidélité au vrai jeu, j’ai décidé d’intégrer cette fonction. Cela signifiait deux choses : je devais donner la possibilité au joueur de prendre la décision et je devais programmer une intelligence artificielle qui choisirais la meilleure tactique.

Pour la première problématique, j’ai implémenté une condition qui vérifie si un as est tiré ou non. Si c’est le cas, un choix est donné au joueur :

def base():
    carte = randint(0,12)
    print("Votre première carte est", paquet[carte])
    if carte == 0: # si la carte est un as (choix entre 1 et 11 points)
        As = int(input("Préférez-vous qu'elle vaille 1 ou 11 points ? "))
        if As == 1:
            carte = 0
            print()
        elif As == 11:
            carte = 13
            print()
    score_joueur[0] += points[carte]
    carte = randint(0,12)
    print("Votre seconde carte est", paquet[carte])
    if carte == 0:
        As = int(input("Préférez-vous qu'elle vaille 1 ou 11 points ? "))
        if As == 1:
            carte = 0
            print()
        elif As == 11:
            carte = 13
            print()
    score_joueur[0] += points[carte]
    print("Votre score de base est de", score_joueur[0], "\n")
    choix_joueur()

Ici, si la variable « carte » prend la valeur 0, elle correspond au premier item du n-uplet « paquet » qui se trouve être as. Dans ce cas, le script donne le choix au joueur. S’il opte pour un point, on donne à la variable « carte » la valeur 0 ; en revanche, s’il opte pour onze points, on lui donne la valeur 13, soit le douzième item du n-uplet « points ».

Cela nous donne :

On applique ce processus à la fonction « choix_joueur() » :

def choix_joueur():
    while score_joueur[0] < 21:
        ch = input("[Voulez-vous piocher ?] " )
        if ch == "o":
            carte = randint(0,12)
            print("Vous piochez", paquet[carte])
            if carte == 0: # si la carte est un as (choix entre 1 et 11 points)
                As = int(input("Préférez-vous qu'il vaille 1 ou 11 points ? "))
                if As == 1:
                    carte = 0
                    print()
                elif As == 11:
                    carte = 13
                    print()
            score_joueur[0] += points[carte]
            print("Votre score est de", score_joueur[0], "\n")
        elif ch == "n":
            print("Vous décidez de vous arrêter.")
            break
    if score_joueur[0] > 21:
        defaite()
    else:
        choix_ordi()

Dès lors que la partie « joueur » est complétée, je pouvais m’atteler au processus de décision de l’ordi en commençant avec les deux cartes piochées au début de son tour.

Que la première carte piochée vaille un ou onze points, cela n’importe guère. Par conséquent, j’ai décidé de laisser le hasard faire les choses :

def choix_ordi():
    carte = randint(0,12)
    print("La première carte du croupier est", paquet[carte])
    if carte == 0: # si la carte du croupier est un as
        As = randint(1,2) # le croupier choisi au hasard entre 1 et 11 points
        if As == 1:
            print("Le croupier préfère que la carte vaille 1 point.")
            carte = 0
        else:
            print("Le croupier préfère que la carte vaille 11 points.")
            carte = 13        
    score_ordi[0] += points[carte]

Par contre, pour la deuxième carte, le processus est légèrement plus complexe.

Tout d’abord, si la première carte était un as à onze points, il est impératif que le croupier opte pour un point pour sa deuxième carte afin de ne pas dépasser vingt-et-un. Ce cas de figure, quand bien même plutôt rare, reste tout de même important à prendre en compte.

Sinon, il faut vérifier si ajouter onze au score du croupier le fait dépasser celui du joueur. Si c’est le cas, le deuxième as devrait correspondre automatiquement à onze points.

Si aucun de ces deux conditions n’est vraie, le croupier choisit au hasard.

carte = randint(0,12)
    print("La seconde carte du croupier est", paquet[carte])
    if carte == 0:
        if score_ordi[0] + 11 > 21: # si ajouter 11 points au score actuel du croupier le fait dépasser 21, l'as vaut 1 point
            print("Le croupier préfère que la carte vaille 1 point.")
            carte = 0
        elif score_ordi[0] + 11 >= score_joueur[0]: # si ajouter 11 points au score actuel du croupier le fait atteindre le score du jouer, l'as vaut 11 points 
            print("Le croupier préfère que la carte vaille 11 points.")
            carte = 13
        else:
            As = randint(1,2) # sinon, le croupier choisi au hasard entre 1 et 11 points
            if As == 1:
                print("Le croupier préfère que la carte vaille 1 point.")
                carte = 0
            else:
                print("Le croupier préfère que la carte vaille 11 points.")
                carte = 13
    score_ordi[0] += points[carte]

La même logique est appliquée pour le reste du tour.

Maintenant que toutes les cartes sont programmées, le projet ne semble plus très loin de sa fin. Encore quelques efforts !

Le système de mises et de banque

Un jeu d’argent ne serait rien sans l’argent lui-même.

La « banque » correspond à la quantité d’argent détenu par le joueur. Dans le code, elle est représentée par une variable globale :

banque = [300]

Par défaut, elle contient trois-cents euros (ce montant sera expliqué plus tard).

J’ajoute au système de banque la possibilité de miser en début de partie grâce à la fonction « miser() » :

mise = [0]

def miser():
    euro = int(input("Combien d'euros souhaitez-vous miser ? "))
    mise[0] = euro
    print()
    base()

La fonction globale « mise » sert à récupérer le montant versé par le joueur pour ensuite, lorsque la partie touche à sa fin, modifier la banque.

Dans la partie « Quelques recherches avant de débuter », j’ai expliqué que les casinos mettent en place un montant maximum pour les mises. J’ai élevé le mien à cent-cinquante euros. Une condition doit être implémentée dans la fonction afin de respecter ce choix.

def miser():
    while True:
    	euro = int(input("Combien d'euros souhaitez-vous miser ? (150 maximum) "))
    	if euro > 150: # si la mise est supérieure à 150
        	print("Vous devez miser en-dessous de 150 €.\n")
    	else:
        	break
    mise[0] = euro
    print()
    base()

Outre le montant de cent-cinquante euros, la mise du joueur ne peut pas dépasser le contenu de sa banque. Par exemple, si la banque du joueur contient cent euros, il ne peut pas en miser cent-cinquante.

def miser():
    while True:
    	euro = int(input("Combien d'euros souhaitez-vous miser ? (150 maximum) "))
    	if euro > 150: # si la mise est supérieure à 150
        	print("Vous devez miser en-dessous de 150 €.\n")
        elif euro > banque[0]: # si la mise est supérieure au contenu de la banque
        	print("Vous ne pouvez pas miser davantage que vous possédez (Votre banque contient", banque[0], "€)\n")
    	else:
        	break
    mise[0] = euro
    print()
    base()

Enfin, une mise négative ou nulle ne peut être acceptée : elle doit valoir au minimum un euro.

def miser():
    while True:
    	euro = int(input("Combien d'euros souhaitez-vous miser ? (150 maximum) "))
    	if euro > 150: # si la mise est supérieure à 150
        	print("Vous devez miser en-dessous de 150 €.\n")
        elif euro > banque[0]: # si la mise est supérieure au contenu de la banque
        	print("Vous ne pouvez pas miser davantage que vous possédez (Votre banque contient", banque[0], "€)\n")
    	elif euro <= 0: # si la mise vaut 0 ou moins
        	print("Vous devez miser davantage afin de pouvoir participer.\n")
        else:
        	break
    mise[0] = euro
    print()
    base()

La fonction est affichée de cette manière dans la console :

Désormais, il ne reste qu’à programmer les conséquences qui viennent modifier la banque lors d’une réussite ou défaite.

Lors d’une défaite, le joueur perd simplement la mise.

def defaite():
    print("Vous avez perdu...")
    banque[0] -= mise[0] # on soustrait à la banque la mise
    print("Votre banque contient", banque[0], "€") # affichage du contenu de la banque
	nouvelle_partie()

def nouvelle_partie():
    rejouer = input("Désirez-vous refaire une partie ? (\"o\" ou \"n\") ")
    if rejouer == "o": # si le joueur veut refaire une partie, son score ainsi que celui du croupier sont réinitialisés
        score_joueur[0] = 0
        score_ordi[0] = 0
        print()
        miser()
    elif rejouer == "n":
        fin()

def fin(): # lorsque le joueur ne veut pas refaire une partie
    print()
    print("À la prochaine !")

Entre autre, j’ai défini deux autres fonctions : « nouvelle_partie() » qui propose au joueur de rejouer et réinitialise les scores, et « fin() » si le joueur veut finir la partie.

Le processus est similaire pour la fonction « reussite() » :

def reussite():
  	print("Vous avez gagné !")
	banque[0] += 2 * mise[0] # on ajoute à la banque le double de la mise
    print("Votre banque contient", banque[0], "€")
    nouvelle_partie()

Une fois ces fonctionnalités programmées, un problème m’a sauté aux yeux : à quoi sert ce système de banque et de mise si, au final, cela n’a pas de conséquences ? Afin de donner un but précis au jeu, j’ai programmé la possibilité de perdre la partie si le contenu de la banque descend à zéro ou moins, ou de la gagner si le contenu atteint les mille euros.

def defaite():
    print("Vous avez perdu...")
    banque[0] -= mise[0]
    print("Votre banque contient", banque[0], "€")
    if banque[0] <= 0: # si la banque est vide, le joueur perd la partie
        print("Vous ne possédez plus assez d'argent pour pouvoir participer.")
        print("Vous êtes complétement ruiné !")
        rejouer = input("Désirez-vous rejouer ? (\"o\" ou \"n\") ")
        if rejouer == "o": # réinitialisation des paramètres
            banque[0] = 300
            score_joueur[0] = 0
            score_ordi[0] = 0
            print()
            miser()
        elif rejouer == "n":
            fin()
    else:
        nouvelle_partie()

Cette partie de code affiche :

def reussite():
  	print("Vous avez gagné !")
	banque[0] += 2 * mise[0]
    print("Votre banque contient", banque[0], "€")
    nouvelle_partie()
	if banque[0] >= 1000: # si le contenu de la banque atteint les 1000 €, le joueur gagne la partie
    	print("Votre banque contient", banque[0], "€ : vous avez atteint les 1000 € !\n")
    	print("Vous gagnez la partie !")
    	fin()
    else:
      	nouvelle_partie()
      

Implémenter ces fonctionnalités m’a également fait prend conscience d’une chose : peut-être que le joueur n’aimerait pas mettre de l’argent en jeu et désirerait simplement faire une partie pour le plaisir. De ce fait, je lui ai donné la possibilité de choisir entre deux modes : le mode « libre », sans mises, ou le mode « casino ».

mode = ["libre"]

mode[0] = input("Quel mode de jeu voulez-vous : libre ou casino ? ")

Ce morceau de code sera intégré à la fonction « menu() » dont je parlerai dans la prochaine partie.

Les modifications causées par le choix du mode sont assez nombreuses ; il est conseillé d’aller vérifier le code lui même donné à la fin de l’article.

Les finitions

Je touchait presque la fin de mon projet, seulement quelques bricoles restaient à régler.

Premièrement, il fallait intégrer les règles du Blackjack au début afin d’informer le joueur. Elles sont affichées grâce à la fonction « menu() », la première à être appelée dans le code.

def menu(): # première chose affichée
    print("Bienvenue au jeu du Blackjack !")
    regles = input("Souhaitez-vous lire les règles ? (\"o\" ou \"n\") ")
    if regles == "o": # affichage des règles
        # [...]
    print()
    mode[0] = input("Quel mode de jeu voulez-vous : libre ou casino ? ")
    if mode[0] == "libre":
        base()
    elif mode[0] == "casino": # contenu de la banque donné pour la première mise, inutile après la première partie
        print()
        print("Votre banque contient", banque[0], "€")
        miser()

Cela nous donne :

(L’entièreté des règles est affichée dans le script donné à la fin de cet article.)

Un autre problème à régler était le rythme du jeu : le texte était affiché en une seule fois, rendant l’expérience de jeu bien laborieuse. Grâce au module time et à sa fonction « sleep() », j’ai pu rendre l’affichage plus lent, imitant presque le chargement d’un vrai jeu vidéo !

Le dernière point le plus complexe à régler était l’espacement entre certaines lignes : afin que l’affichage soit cohérent, les sauts à la ligne doivent conserver la même logique. Je vous épargne toutes les modifications faites, hormis une que je trouve particulièrement pratique :

print()
print("------------------------------------\n")
sleep(1)

Cette barre de séparation aide vraiment à discerner les différentes parties du jeu à l’affichage, ce qui permet au joueur de mieux se repérer dans la partie.

Pour terminer, j’ai quelque peu modifié les choix qui sont présentés au fil d’une partie afin que le joueur ne puisse pas entrer n’importe quoi, grâce à une boucle while :

while True: # choix du mode
	mode[0] = input("Quel mode de jeu voulez-vous : libre ou casino ? ")
    if mode[0] != "libre" and mode[0] != "casino":
    	print("Désolé, mais ce n'est pas un choix proposé.\n")
        sleep(2)
    else:
        break

Et enfin, après quelques ajouts esthétiques, le script est enfin achevé !

Conclusion

Malgré la taille du projet et mon niveau peu haut en matière d’écriture de script, coder ce jeu a été plutôt plaisant, et chaque problème rencontré m’a paru comme une énigme à résoudre. Oui, quelquefois, j’ai été frustré par les bugs qui semblaient impossibles à régler ; mais à force de patience et persévérance, je suis parvenu à un script satisfaisant à mon goût ainsi qu’un jeu qui fonctionne !

Le script à télécharger

Projets

Générateur leet speak en python

ParL32 v0U2 l3 1337 5p3aK ? C3 pr0j37 357 un 9ÉNÉrA73ur 3n py7h0N d3 1337 5p3ak…

Présentation

Ce projet a été réalisé par Lena G. en classe de première G5 dans le cadre de leur enseignement de spécialité NSI (numérique et sciences de l’informatique), au lycée Louis Pasteur à Avignon.
Avec comme matériel un ordinateur équipé du logiciel Thonny.

Le leet speak

Le leet speak et un langage qui remplace les caractères d’un mot ou d’une phrase par un caractère voisin visuellement, il est créé à la fin des années 80 par des programmeurs informatiques. Il existe plusieurs niveaux de codage :

  • Codage simple Leet Speak = LeeT 5Pe4k
  • Codage simple Leet Speak = |_337 $|>34|<

Description du programme

Les listes

J’ai d’abord créé 3 listes avec tous les caractères utilisables, la première correspond au langage naturel que va entrer l’utilisateur, la seconde sera la traduction du caractère dans un langage simple à traduire et la troisième dans un langage complique à déduire.

liste_1 = ("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", " ","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","é","è","à","'",".")
liste_2 = ("4", "8", "C", "D", "e", "F", "9", "H", "1", "j", "k", "L", "m", "N", "0", "P", "Q", "R", "5", "T", "u", "V", "W", "X", "Y", "2", " ", "4", "8", "C", "D", "e", "F", "9", "H", "1", "j", "k", "L", "m", "N", "0", "P", "Q", "R", "5", "T", "u", "V", "W", "X", "Y", "2","é","è","À","'",".")
liste_3 = ("4", "8", "(", "|)", "3", "|=", "9", "}{", "1", "_|", "|<", "|_", "|\/|", "N", "0", "|>", "().", ".-", "$", "7", "|_|", "\/", "\|/", "><", "`/", "2", " ", "4", "8", "(", "|)", "3", "|=", "9", "}{", "1", "_|", "|<", "|_", "|\/|", "N", "0", "|>", "().", ".-", "$", "7", "|_|", "\/", "\|/", "><", "`/", "2","⋷","ē","ἀ","ノ","•")

Les fonctions de traduction

J’ai créé 2 fonction quasi-identique, elle consiste toutes deux à prendre chaque caractère (que l’utilisateur aura entre) qui se trouve dans « liste 1 » et en parcourent une des 2 autres listes, ressortir le caractère correspondent dans « liste 2 » pour la première fonction « code_1(mot) » et « liste 3 » pour la deuxième fonction « code_2(mot) ». Soit une boucle ou tant que le caractère de « liste 1 » n’a pas atteint le caractère correspondant dans l’autre liste, on continue à parcourir la liste en question. Une fois le caractère atteint, il remplace le caractère de la première liste.

def code_1(mot):
    mot_traduit = ""
    for i in mot:
        k = 0
        while liste_1[k] != i:
            k += 1
        mot_traduit += liste_2[k] 
    return mot_traduit

def code_2(mot):
    mot_traduit = ""
    for i in mot:
        k = 0
        while liste_1[k] != i:
            k += 1
        mot_traduit += liste_3[k] 
    return mot_traduit

Fonction menu

La fonction « menu » laisse l’utilisateur choisir s’il souhaite changer ce qu’il veut entrer, en langage simple ou compliquer en entrant soit 1 pour simple soit 2 pour compliquer. S’il choisit 1, l’utilisateur entrera ses caractères et il se lancera la fonction « code_1(mot) ». S’il choisit 2, l’utilisateur entrera ses caractères et il se lancera la fonction « code_2(mot) ». S’il ne choisit un autre chiffre que 1 ou 2, il s’affichera « Choix non-valide » est relancera le menu.

def menu():
    print("Langage simple:\t 1")
    print("Langage compliqué:\t 2")
    choix = int(input("Choisissez le langage de départ:\t"))
    if choix == 1:
        mot_origine = input("Veuillez rentre le mot d'origine :")
        print(code_1(mot_origine))
        print("\n")
        menu()
    elif choix == 2:
        mot_origine = input("Veuillez rentre le mot d'origine :")
        print(code_2(mot_origine))
        print("\n")
        menu()
    else :
        print("Choix non-valide\n")
        menu()

Conclusion

J’espère que mon programme vous sera utile.
Vous pouvez le récupérer si vous voulez l’améliorer.