Skip to the content.

Jeu du Backjack

Ce jeu de Blackjack est un travail de groupe réalisé pour l’université dans le carde d’un projet de fin de semestre en INF101. Le but était de créer un jeu de Blackjack fonctionnel et se rapprochant le plus possible d’un jeu de Blackjack réel.

Lors de la création du programme nous avons ajouté progressivements certaines fonctionnalités que nous allons détailler ici. La structure choisie a été de créer un fichier blackjack.py pour stocker toutes les fonctions de jeu et un autre main.py pour les exécuter dans l’ordre.

Table des matières

Déroulement de base du jeu

Le jeu de Blackjack est un jeu assez simple en soi, donc sa réalisation est plutôt simple à traduire en code. En simplifiant les règles du jeu officiel, nous en avons tiré un déroulement de jeu à peu près similaire à ceci :

Les différentes parties distinctes du jeu sont exécutées avec les fonctions suivantes :

Structure des données de jeu

L’enjeu majeur de ce programme était de savoir comment stocker les données de jeu et pouvoir y accéder facilement avant, durant et après la partie et pouvoir les modifier le plus facilement possible. Pour cela nous avons décidé de nous tourner vers les dictionnaires. Ne pouvant pas utiliser les classes et les objets, les dictionnaires semblaient être la meilleur alternative.

Nous avons donc décidé de rassembler les données en un seul dictionnaire : GDict où sont stockées toutes les données liées au jeu en lui-même, comme la pioche ou les stratégies de jeu ; ainsi que toutes les informations liées aux joueurs et au croupier, comme le score actuel, ne nombre de victoires, la mise, etc.

Le dictionnaire prend la forme suivante :

GDict = {
    'pioche': [],
    'stratlist': ['alea', 'risk', 'safe', 'intel', 'croupNormal', 'croupFacile', 'croupDiff'],
    'stratmiselist': ['miseAlea', 'miseFaible', 'miseForte'],
    'joueurs': {
        0: {
            'nom': '',
            'type': 0,
            'strat': '',
            'stratmise': '',
            'score': 0,
            'wallet': 100,
            'mise': 0,
            'ingame': True,
            'blackjack': False,
            'burst': False
        },
    },
    'croupier': {
        'score': 0,
        'wallet': 0,
        'ingame': True,
        'blackjack': False,
        'burst': False
    },
    'victoires': {}
}

Les informations liées au joueur comme le score ne sont pas stockées dans un dictionnaire pour chaque, mais dans le dictionnaire personnel du joueur. Cela rallonge quelque peu l’écriture du code mais offre une bien plus grande flexibilité dans l’ajout futur de nouvelles informations.

Les données joueurs sont :

À noter que le dictionnaire victoires n’est pas dans le dictionnaire du joueur : cela permet de potentiellement exporter le dictionnaire dans un fichier et pouvoir ré afficher le compte de victoires au nouveau lancement du programme.

Pour appeler une donnée dans une fonction particulière, seule la variable GDict est nécessaire dans les paramètres. Une donnée s’appelle comme suit : GDict['joueurs'][indexDuJoueur][cléDeLaDonnée]. Les propriétés du dictionnaire permettent donc d’accéder facilement à toutes les données et d’être accédé via une boucle for, par exemple :

for j in GDict['joueurs']:
    GDict['joueurs'][j]['scores'] = 0

Filtrage des inputs

Lors du déroulement de la partie, le jeu interagit beaucoup avec l’utilisateur pour demander, soit le nombre de joueurs, soit la mise des joueurs, etc. Il est donc nécessaire de filtrer les données entrées par l’utilisateur afin de ne pas déclencher une erreur dans le programme.

Pour ce qu’il sagit des entrées de texte, la méthode est assez simple, il suffit de faire une boucle while qui tourne tant que la réponse de l’utilisateur ne convient pas, comme par exemple :

while True:
    strat = input(s+" (o/n) : ")
    if strat != 'o' and strat != 'n':
        continue
    else:
        break

Pour les entrées de valeurs entières, comme la mise ou le nombre de joueur, trier devient plus complexe. En effet, la méthode simple comme ci-dessus ne convient pas car on ne peut pas vérifier facilement si une chaine de caractère est un entier correct ou non. Aussi, lorsque la fonction int(input()) reçoit une valeur incorrecte, elle renvoie une erreur au lieu de simplement renvoyer None, ce qui a pour inconvénient de stopper le programme.

Pour pallier à cela, nous avons utilisé une méthode que nous n’avons pas vu en cours : les erreurs et exceptions. Cela utilise en plus les instructions try et except :

while True:
    try:
        nbjoueurs = int(input('Nombre de joueurs : '))
    except:
        print("Entrez une valeur correcte")
        continue
    if nbjoueurs <= 0:
        print("Le nombre de joueurs doit être supérieur à 0")
        continue
    else:
        break

Ces deux méthodes assez similaires font en sorte qu’aucune erreur ne soit déclenchée directement par l’utilisateur, ce qui est important notamment lors de la phase de testage du programme.

Les fonctions de jeu

Le fonctionnement du jeu repose sur différentes fonctions créées dans le programme blackjack.py. Mise à part les fonctions de déroulement de jeu, elles servent à tout ce qui est gestion du jeu et calcul de différentes variables et données.

Stratégies de pioche

Les stratégies de pioches sont utilisées pour les joueurs ordinateur ou pour le croupier. Ce sont en fait des fonctions qui déterminent si le joueur doit continuer à piocher ou non, basé sur certains critères.

Stratégies de choix de la mise

Le fonctionnement des mises demandé ne correspond pas du tout au fonctionnement des mises du Blackjack classique, faisant jouer les joueurs contre eux et non contre le croupier. C’est pourquoi nous avons décidé de revoir le système avec les règles suivantes :

De même que les stratégie de pioche, les stratégies de mises peuvent être choisies au moment de l’inscription du joueur ordinateur dans le dictionnaire. Elles déterminenent donc combien d’OtterCoins le joueur va miser en fonction de différents critères.

Tournoi automatique et comparaison des stratégies

Nous allons à présent étudier différentes possibilités de jeux, afin de voir quelle(s) stratégie(s) de mises et/ou de pioches sont les meilleurs pour gagner face au croupier. Pour procéder à cela, nous avons créé une nouvelle branche du jeu (se trouvant ici). Le programme a été complètement simplifié en enlevant tous les affichages console et les interractions avec l’utilisateur, et en enlevant le code concernant les joueurs humains.

Afin de tester toutes les stratégies, le programme principal créé un joueur ordinateur par stratégie et effectue un nombre n de parties affin de comparer le nombre de victoires et les gains pour chaques stratégies.

On utilise ensuite le module matplotlib pour tracer des graphiques avec les valeurs obtenues. On notera le nombre de victoires sous forme d’un histograme et les gains sous forme d’un graphique évoluant à chaque partie effectuée. On effectue 10 000 parties d’affilées pour avoir un résultat se rapprochant le plus possible de la probabilité de réussite de la stratégie.

Graphique des gains Histogramme des Victoires

On remarque que la stratégie de jeu la plus efficace est finalement croupFacile, similaire à celle du croupier, avec un score d’arrêt légèrement plus faible. Cependant, dans certains autres tests, c’est la stratégie croupNormal qui l’emportait de peu. C’est donc une de ces stratégies qu’il faudrait choisir, car en plus de cela, le taux de victoire est supérieur à 50%.

Au contraire, la stratégie risk qui consiste à continuer à piocher huit fois sur 10 est la pire, car c’est celle qui fait que le joueur dépasse le plus souvent.

On remarque aussi, que qu’importe la stratégie, le gain est toujours négatif et donc le casino s’en sort toujours avec un gain positif.

Interface graphique du jeu

Lien du jeu

La partie interface graphique du jeu étant optionnelle, nous avons décidé de ne pas nous attarder sur python qui n’est pas du tout un langage adapté pour cela. Nous avons eu donc l’idée de se baser sur le fonctionnement des sites web et de coder le jeu en html, css et JavaScript. Ce dernier étant le langage principal du fonctionnement du jeu.

La création d’un programme en JavaScript est assez simple et similaire à Python, mais nous avons rencontré tout de même certaines difficultés lors de la programmation.

Capture d'écran du jeu