A laptop with the Python download webpage open on Chrome.
Agence web » Actualités du digital » Développer un simulateur de lancer de dés

Développer un simulateur de lancer de dés

Alors, c'est une soirée RPG sur table, et tout le monde a son sac de dés, et vous sortez… votre ordinateur portable ? Eh bien, c'est le moment idéal pour montrer ce simulateur de lancer de dés que vous avez construit en Python. Ce projet pour débutant devrait vous apprendre les bases des lancers de dés et de la randomisation.

Mise en place de notre projet

Cela va être une configuration assez simple. J'ai déjà décrit comment nous avons configuré Visual Studio pour le codage avec Python, nous l'utiliserons donc pour notre configuration de base. Nous allons garder cela aussi simple que possible, nous allons donc commencer par nos importations :

import tkinter as tk
from tkinter import ttk
import random

Nous avons déjà utilisé Tkinter lorsque nous avons créé notre simple outil de suivi des dépenses ; dans ce cas, c'est la solution la plus légère. La bibliothèque nous permet de créer une interface graphique simple, moderne et élégante. La bibliothèque aléatoire nous offre la fonctionnalité permettant de randomiser les nombres entre deux valeurs, ce qui est l'essence même d'un lancer de dé. Rendons les choses un peu plus jolies.

Considérations de conception avec nos faces de dés

Nous allons simuler un jeu de dés RPG. Pour une touche stylistique, j'ai rendu les dés à quatre faces (d4) et les dés à six faces (d6) un peu fantaisistes pour démontrer la gestion de l'art ASCII avec Tkinter.

def __init__(self, root):
        self.root = root
        self.root.title("Dice Simulator")
        self.root.geometry("400x500")
        
        
        self.d4_faces = {
            1: " ╱▲╲n ╱ 1 ╲n╱ ╲n",
            2: " ╱▲╲n ╱ 2 ╲n╱ ╲n",
            3: " ╱▲╲n ╱ 3 ╲n╱ ╲n",
            4: " ╱▲╲n ╱ 4 ╲n╱ ╲n"
        }
        
        self.d6_faces = {
            1: "┌─────────┐n│ │n│ ● │n│ │n└─────────┘",
            2: "┌─────────┐n│ ● │n│ │n│ ● │n└─────────┘",
            3: "┌─────────┐n│ ● │n│ ● │n│ ● │n└─────────┘",
            4: "┌─────────┐n│ ● ● │n│ │n│ ● ● │n└─────────┘",
            5: "┌─────────┐n│ ● ● │n│ ● │n│ ● ● │n└─────────┘",
            6: "┌─────────┐n│ ● ● │n│ ● ● │n│ ● ● │n└─────────┘"
        }

J'ai opté pour cela parce que je pensais qu'une interface graphique serait beaucoup plus attrayante. Lorsque nous avons créé notre application de quiz, nous nous en sommes tenus au terminal, mais j'aimerais avoir un peu de style dans cette application. Ne vous inquiétez pas trop pour ce morceau de code. Tout ce qu'il fait, c'est afficher notre d6 avec un visage comme un vrai d6, et pareil pour un d4. C'est également le début de notre interface graphique, avec le titre de l'application « Dice Simulator » affiché en haut de la fenêtre. Voyons comment nous allons faire notre contribution.

Nous voulons un endroit où l'utilisateur puisse saisir le nombre et le type de dés qu'il souhaite lancer. Pour garder les choses simples, nous maximiserons les dés à cinq, donc rien de plus que cela, nous ne gérerons pas. Notre interface utilisateur aura donc un sélecteur de dé (pour le type de dé) et un certain nombre d'entrées de dés si nous en lançons plusieurs.

Je souhaite également implémenter un système d'historique pour nos lancers, je vais donc le mettre en bas et le mettre à jour à chaque fois que nous lancerons un nouveau jeu de dés. Notre extrait de code devrait ressembler à ceci :

        
        self.main_frame = ttk.Frame(self.root, padding="10")
        self.main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))

        
        ttk.Label(self.main_frame, text="Number of Dice:").grid(row=0, column=0, pady=5)
        self.num_dice = ttk.Spinbox(self.main_frame, from_=1, to=5, width=5)
        self.num_dice.set(1)
        self.num_dice.grid(row=0, column=1, pady=5)

        
        ttk.Label(self.main_frame, text="Dice Type:").grid(row=1, column=0, pady=5)
        self.dice_type = ttk.Combobox(self.main_frame, values=("d4", "d6", "d8", "d12", "d20"), width=5)
        self.dice_type.set("d6")
        self.dice_type.grid(row=1, column=1, pady=5)

        
        self.roll_button = ttk.Button(self.main_frame, text="Roll Dice!", command=self.roll_dice)
        self.roll_button.grid(row=2, column=0, columnspan=2, pady=10)

        
        self.result_text = tk.Text(self.main_frame, height=15, width=40, font=('Courier', 10))
        self.result_text.grid(row=3, column=0, columnspan=2, pady=10)

        
        ttk.Label(self.main_frame, text="Roll History:").grid(row=4, column=0, columnspan=2, pady=5)
        self.history_text = tk.Text(self.main_frame, height=5, width=40)
        self.history_text.grid(row=5, column=0, columnspan=2, pady=5)

        self.roll_history = ()
        
        self.main_frame = ttk.Frame(self.root, padding="10")
        self.main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))

        
        ttk.Label(self.main_frame, text="Number of Dice:").grid(row=0, column=0, pady=5)
        self.num_dice = ttk.Spinbox(self.main_frame, from_=1, to=5, width=5)
        self.num_dice.set(1)
        self.num_dice.grid(row=0, column=1, pady=5)

        
        ttk.Label(self.main_frame, text="Dice Type:").grid(row=1, column=0, pady=5)
        self.dice_type = ttk.Combobox(self.main_frame, values=("d4", "d6", "d8", "d12", "d20"), width=5)
        self.dice_type.set("d6")
        self.dice_type.grid(row=1, column=1, pady=5)

        
        self.roll_button = ttk.Button(self.main_frame, text="Roll Dice!", command=self.roll_dice)
        self.roll_button.grid(row=2, column=0, columnspan=2, pady=10)

        
        self.result_text = tk.Text(self.main_frame, height=15, width=40, font=('Courier', 10))
        self.result_text.grid(row=3, column=0, columnspan=2, pady=10)

        
        ttk.Label(self.main_frame, text="Roll History:").grid(row=4, column=0, columnspan=2, pady=5)
        self.history_text = tk.Text(self.main_frame, height=5, width=40)
        self.history_text.grid(row=5, column=0, columnspan=2, pady=5)

        self.roll_history = ()

Cela nous donne une configuration d'interface utilisateur de base pour notre application de lancer de dés. Passons à la simulation des rouleaux.

Lancer des dés via un ordinateur

Si vous avez déjà joué à un jeu vidéo RPG, vous avez déjà expérimenté des lancers de dés simulés. Les dés façonnent la façon dont les jeux de rôle sur table jouent, leurs flux et reflux et ce qui arrive aux personnages. Un jet de dé est un nombre aléatoire produit entre deux valeurs, minimum et maximum. En Python, nous pouvons utiliser la bibliothèque aléatoire pour simuler ces lancers. Voici notre code :

    def roll_single_die(self, sides):
        """Simulate rolling a single die with given number of sides."""
        return random.randint(1, sides)

    def get_dice_face(self, value, dice_type):
        """Get ASCII art representation of a die face."""
        if dice_type == 4:
            return self.d4_faces.get(value, str(value))
        elif dice_type == 6:
            return self.d6_faces.get(value, str(value))
        return str(value)

    def roll_dice(self):
        """Handle the dice rolling action and update the display."""
        try:
            num_dice = int(self.num_dice.get())
            dice_type = int(self.dice_type.get()(1:))
            
            
            self.result_text.delete(1.0, tk.END)
            
            
            rolls = (self.roll_single_die(dice_type) for _ in range(num_dice))
            total = sum(rolls)
            
            
            if dice_type in (4, 6):
                for roll in rolls:
                    self.result_text.insert(tk.END, self.get_dice_face(roll, dice_type) + "n")
            else:
                roll_str = ", ".join(str(roll) for roll in rolls)
                self.result_text.insert(tk.END, f"Rolls: {roll_str}n")
            
            self.result_text.insert(tk.END, f"nTotal: {total}")
            
            
            roll_record = f"{num_dice}d{dice_type}: {rolls} = {total}"
            self.roll_history.append(roll_record)
            if len(self.roll_history) > 5:
                self.roll_history.pop(0)
            
            
            self.history_text.delete(1.0, tk.END)
            for record in self.roll_history:
                self.history_text.insert(tk.END, record + "n")

        except ValueError:
            self.result_text.delete(1.0, tk.END)
            self.result_text.insert(tk.END, "Please enter valid numbers")

Cela nous fournit le code de base pour simuler nos lancers de dés. Pour faire fonctionner le programme, il suffit d'appeler notre fonction principale :

if __name__ == "__main__":
    root = tk.Tk()
    app = DiceSimulator(root)
    root.mainloop()

Et ça devrait le faire. Nous avons maintenant un simulateur de lancer de dés !

Suggestions de mises à niveau et de mises à jour

Lorsque vous exécutez l'application, vous devriez voir quelque chose comme ceci :

L'application présente quelques limitations que j'ai intentionnellement laissées de côté pour vous offrir quelque chose avec lequel étendre l'application. Il n'y a pas de support pour les d10 ou les d100 (qui peuvent être simulés en lançant 2d10 ou en lançant 1d100). Vous pouvez les ajouter vous-même si vous souhaitez développer l'application. De plus, vous pouvez étendre cela à un rouleau de dés en réseau et rendre l'interface utilisateur un peu plus jolie avec un peu de skinning. Comme d'habitude, tout le code de cette application est disponible sur mon GitHub. Tout commentaire sur le code ou mon approche est toujours le bienvenu.

★★★★★