ساخت بازی Cosmic Egg Catcher با پایتون

پروژه‌های بازی‌سازی پایتون

آموزش ۸ دقیقه مطالعه
فهرست مطالب
این مطلب از سایت tool.hamidvalad.ir گرفته شده است

معرفی

Cosmic Egg Catcher یک بازی جذاب و رنگارنگ است که در آن بازیکن باید تخم‌مرغ‌های کیهانی در حال سقوط را با استفاده از یک جمع‌کننده کنترل شده توسط کلیدهای کیبورد، جمع‌آوری کند. این پروژه از کتابخانه tkinter برای ایجاد رابط گرافیکی استفاده می‌کند و دارای ویژگی‌های پیشرفته‌ای مانند سیستم کامبو، افکت‌های ذره‌ای، انیمیشن‌های پویا و تم‌های رنگی متنوع است.

نمای اجرای بازی Cosmic Egg Catcher در پنجره tkinter: تخم‌مرغ‌های رنگی در حال سقوط در آسمان آبی، سبد قرمز روی زمین چمن و نمایش امتیاز ۰ و ۳ جان در بالای صفحه

نصب و پیش‌نیازها

برای اجرای این پروژه نیاز به پایتون نسخه 3.6 یا بالاتر دارید. کتابخانه‌های مورد نیاز به صورت پیش‌فرض در پایتون موجود هستند:

  • tkinter - برای رابط گرافیکی
  • itertools - برای چرخه رنگ‌ها
  • random - برای ایجاد اعداد تصادفی
  • math - برای محاسبات ریاضی
  • time - برای مدیریت زمان

معماری پروژه

کلاس اصلی بازی CosmicEggCatcher شامل بخش‌های زیر است:

  • مدیریت پنجره و کانواس
  • سیستم تم‌های رنگی پویا
  • مدیریت وضعیت بازی (امتیاز، جان‌ها، کامبو)
  • سیستم فیزیک و تشخیص برخورد
  • انیمیشن‌ها و افکت‌های بصری
  • کنترل‌های بازیکن

کدنویسی پروژه

کد کامل پروژه

Python

from itertools import cycle
from random import randrange, choice, uniform
import tkinter as tk
from tkinter import messagebox
import math
import time

class CosmicEggCatcher:
    def __init__(self):
        # Game setup variables
        self.canvas_width = 900
        self.canvas_height = 600
        
        # Enhanced Color themes with gradients
        self.themes = {
            "Aurora Sky": {
                "sky": "#667eea",
                "ground": "#2E8B57",
                "sun": "#FFD700",
                "text": "#FFFFFF",
                "catcher": "#FF6B6B",
                "cloud": "#FFFFFF",
                "particle": ["#FF6B6B", "#4ECDC4", "#45B7D1"]
            },
            "Sunset Dream": {
                "sky": "#ff7e5f",
                "ground": "#8B4513",
                "sun": "#FF4500",
                "text": "#FFFFFF",
                "catcher": "#FF8C00",
                "cloud": "#FFA07A",
                "particle": ["#FF8C00", "#FF6347", "#FFD700"]
            },
            "Midnight Magic": {
                "sky": "#0f0c29",
                "ground": "#34495E",
                "sun": "#F1C40F",
                "text": "#ECF0F1",
                "catcher": "#9B59B6",
                "cloud": "#BDC3C7",
                "particle": ["#9B59B6", "#3498DB", "#1ABC9C"]
            },
            "Forest Whisper": {
                "sky": "#74b9ff",
                "ground": "#00b894",
                "sun": "#FFEAA7",
                "text": "#2D3436",
                "catcher": "#00b894",
                "cloud": "#DFE6E9",
                "particle": ["#00b894", "#55EFC4", "#81ECEC"]
            }
        }
        self.current_theme = "Aurora Sky"
        
        # Enhanced egg colors
        self.egg_colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7', '#DDA0DD', '#98D8C8', '#F7DC6F']
        self.color_cycle = cycle(self.egg_colors)
        
        # Game design variables
        self.egg_width = 50
        self.egg_height = 60
        self.egg_score = 10
        self.egg_speed = 500
        self.egg_interval = 3500
        self.difficulty_factor = 0.95
        
        # Catcher setup
        self.catcher_width = 120
        self.catcher_height = 80
        
        # Game state
        self.score = 0
        self.lives_remaining = 3
        self.eggs = []
        self.particles = []
        self.combo = 0
        self.last_catch_time = 0
        
        # Animation variables
        self.catcher_glow = 0
        self.sun_pulse = 0
        self.cloud_offset = 0
        
        self.setup_gui()
        self.setup_game()
        
    def setup_gui(self):
        # Initialize the main window
        self.win = tk.Tk()
        self.win.title("✨ Cosmic Egg Catcher ✨")
        self.win.configure(bg='#0f0c29')
        self.win.resizable(False, False)
        
        # Center the window
        screen_width = self.win.winfo_screenwidth()
        screen_height = self.win.winfo_screenheight()
        x = (screen_width - self.canvas_width) // 2
        y = (screen_height - self.canvas_height) // 2 - 50
        self.win.geometry(f"{self.canvas_width}x{self.canvas_height}+{x}+{y}")
        
        # Create canvas with current theme
        theme = self.themes[self.current_theme]
        self.c = tk.Canvas(self.win, width=self.canvas_width, height=self.canvas_height, 
                          background=theme["sky"], highlightthickness=0)
        self.c.pack()
        
        # Enhanced control panel
        self.setup_control_panel()
        
    def draw_background(self):
        theme = self.themes[self.current_theme]
        
        # Clear only background elements, keep game objects
        self.c.delete("bg")
        
        # Ground
        self.c.create_rectangle(-5, self.canvas_height - 100, self.canvas_width + 5, 
                               self.canvas_height + 5, fill=theme["ground"], width=0, tags="bg")
        
        # Sun with simple animation
        sun_size = 40 + math.sin(self.sun_pulse) * 5
        self.c.create_oval(50 - sun_size, 50 - sun_size, 50 + sun_size, 50 + sun_size,
                         fill=theme["sun"], outline="", tags="bg")
        
        # Clouds
        self.draw_animated_clouds(theme["cloud"])
        
        # Add grass details
        for i in range(0, self.canvas_width, 15):
            height = randrange(5, 12)
            self.c.create_rectangle(i, self.canvas_height - 100, i + 8, 
                                  self.canvas_height - 100 - height, 
                                  fill="#228B22", outline="", tags="bg")
    
    def draw_animated_clouds(self, color):
        cloud_positions = [
            (150 + self.cloud_offset, 80),
            (400 + self.cloud_offset * 0.7, 120),
            (650 + self.cloud_offset * 0.5, 70)
        ]
        
        for x, y in cloud_positions:
            self.draw_cloud(x % (self.canvas_width + 200) - 100, y, color)
    
    def draw_cloud(self, x, y, color):
        # Simple cloud with multiple circles
        circles = [
            (x, y, 20), (x + 15, y - 8, 16), (x + 30, y, 20),
            (x + 12, y + 8, 14), (x + 25, y + 4, 16)
        ]
        
        for cx, cy, radius in circles:
            self.c.create_oval(cx - radius, cy - radius, cx + radius, cy + radius,
                             fill=color, outline="", tags="bg")
    
    def setup_control_panel(self):
        control_frame = tk.Frame(self.win, bg='#0f0c29', bd=0)
        control_frame.pack(pady=10)
        
        # Theme selector
        tk.Label(control_frame, text="🎨 Theme:", fg='white', bg='#0f0c29', 
                font=('Arial', 11, 'bold')).pack(side=tk.LEFT, padx=5)
        
        self.theme_var = tk.StringVar(value=self.current_theme)
        theme_menu = tk.OptionMenu(control_frame, self.theme_var, *self.themes.keys(), command=self.change_theme)
        theme_menu.config(bg='#667eea', fg='white', font=('Arial', 10, 'bold'),
                         relief='flat', bd=0, padx=10, pady=5)
        theme_menu.pack(side=tk.LEFT, padx=5)
        
        # Restart button
        restart_btn = tk.Button(control_frame, text="🔄 Restart", command=self.reset_game,
                               bg='#FF6B6B', fg='white', font=('Arial', 11, 'bold'),
                               relief='flat', bd=0, padx=15, pady=6)
        restart_btn.pack(side=tk.LEFT, padx=10)
        
        # Combo display
        self.combo_label = tk.Label(control_frame, text="Combo: 0x", fg='#FFD700', bg='#0f0c29',
                                  font=('Arial', 11, 'bold'))
        self.combo_label.pack(side=tk.LEFT, padx=10)
    
    def change_theme(self, theme_name):
        self.current_theme = theme_name
        theme = self.themes[theme_name]
        self.c.config(bg=theme["sky"])
        self.draw_background()
        if hasattr(self, 'catcher'):
            self.c.itemconfig(self.catcher, outline=theme["catcher"])
        if hasattr(self, 'score_text'):
            self.c.itemconfig(self.score_text, fill=theme["text"])
            self.c.itemconfig(self.lives_text, fill=theme["text"])
    
    def setup_game(self):
        theme = self.themes[self.current_theme]
        
        # Draw background first
        self.draw_background()
        
        # Create catcher
        catcher_start_x = self.canvas_width / 2 - self.catcher_width / 2
        catcher_start_y = self.canvas_height - self.catcher_height - 80
        catcher_start_x2 = catcher_start_x + self.catcher_width
        catcher_start_y2 = catcher_start_y + self.catcher_height
        
        self.catcher = self.c.create_arc(catcher_start_x, catcher_start_y, 
                                        catcher_start_x2, catcher_start_y2, 
                                        start=200, extent=140, style='arc', 
                                        outline=theme["catcher"], width=6, tags="game")
        
        # Score and lives display
        self.score_text = self.c.create_text(20, 20, anchor='nw', 
                                           font=('Arial', 18, 'bold'), 
                                           fill=theme["text"],
                                           text='🌟 Score: 0', tags="game")
        
        self.lives_text = self.c.create_text(self.canvas_width - 20, 20, anchor='ne', 
                                           font=('Arial', 18, 'bold'), 
                                           fill=theme["text"],
                                           text='💖 Lives: 3', tags="game")
        
        # Game title
        self.c.create_text(self.canvas_width // 2, 30, anchor='n', 
                         font=('Arial', 20, 'bold'), 
                         fill=theme["text"],
                         text='✨ COSMIC EGG CATCHER ✨', tags="game")
        
        # Instructions
        self.c.create_text(self.canvas_width // 2, self.canvas_height - 30, anchor='n', 
                         font=('Arial', 12), 
                         fill=theme["text"],
                         text='Use ← → or A D keys to move • Catch the falling eggs!', tags="game")
        
        # Bind controls
        self.win.bind('<Left>', self.move_left)
        self.win.bind('<Right>', self.move_right)
        self.win.bind('<a>', self.move_left)
        self.win.bind('<d>', self.move_right)
        self.c.focus_set()
        
        # Start game loops
        self.start_game_loops()
    
    def start_game_loops(self):
        self.win.after(1000, self.create_eggs)
        self.win.after(1000, self.move_eggs)
        self.win.after(1000, self.catch_check)
        self.win.after(50, self.update_particles)
        self.win.after(50, self.update_animations)
    
    def create_eggs(self):
        if self.lives_remaining > 0:  # Only create eggs if game is active
            x = randrange(20, self.canvas_width - self.egg_width - 20)
            y = 60
            
            # Create egg with simple design
            egg_color = next(self.color_cycle)
            new_egg = self.c.create_oval(x, y, x + self.egg_width, y + self.egg_height, 
                                        fill=egg_color, width=0, tags="egg")
            
            # Add simple shine
            shine = self.c.create_oval(x + 10, y + 10, x + 20, y + 20, fill='white', width=0, tags="egg")
            
            self.eggs.append({"egg": new_egg, "shine": shine})
            self.win.after(self.egg_interval, self.create_eggs)
    
    def move_eggs(self):
        if self.lives_remaining > 0:  # Only move eggs if game is active
            for egg_data in self.eggs[:]:
                egg = egg_data["egg"]
                shine = egg_data["shine"]
                
                self.c.move(egg, 0, 8)
                self.c.move(shine, 0, 8)
                
                egg_coords = self.c.coords(egg)
                if egg_coords and egg_coords[3] > self.canvas_height:
                    self.egg_dropped(egg_data)
            
            self.win.after(self.egg_speed, self.move_eggs)
    
    def egg_dropped(self, egg_data):
        if egg_data in self.eggs:  # Check if egg still exists
            self.eggs.remove(egg_data)
            self.c.delete(egg_data["egg"])
            self.c.delete(egg_data["shine"])
            self.lose_a_life()
            self.combo = 0
            self.combo_label.config(text=f"Combo: {self.combo}x")
    
    def lose_a_life(self):
        self.lives_remaining -= 1
        self.c.itemconfig(self.lives_text, text=f'💖 Lives: {self.lives_remaining}')
        
        if self.lives_remaining <= 0:
            self.win.after(500, self.game_over)
        else:
            # Visual feedback
            original_bg = self.themes[self.current_theme]["sky"]
            self.c.config(bg='#FF6B6B')
            self.win.after(100, lambda: self.c.config(bg=original_bg))
    
    def game_over(self):
        # Create explosion effect for remaining eggs
        for egg_data in self.eggs[:]:
            self.create_explosion(egg_data)
            self.eggs.remove(egg_data)
        
        # Show game over dialog
        self.show_game_over_dialog()
    
    def show_game_over_dialog(self):
        response = messagebox.askyesno(
            '🎮 GAME OVER! ✨', 
            f'🌟 Final Score: {self.score}\n🔥 Max Combo: {self.combo}x\n\nDo you want to play again?'
        )
        if response:
            self.reset_game()
        else:
            self.win.quit()
    
    def create_explosion(self, egg_data, particle_count=6):
        egg_coords = self.c.coords(egg_data["egg"])
        if not egg_coords:
            return
            
        egg_x, egg_y, egg_x2, egg_y2 = egg_coords
        center_x = (egg_x + egg_x2) / 2
        center_y = (egg_y + egg_y2) / 2
        
        theme = self.themes[self.current_theme]
        
        for _ in range(particle_count):
            angle = randrange(0, 360)
            speed = uniform(2, 6)
            size = randrange(3, 6)
            color = choice(theme["particle"])
            life = randrange(20, 30)
            
            particle = {
                "x": center_x, "y": center_y,
                "dx": math.cos(math.radians(angle)) * speed,
                "dy": math.sin(math.radians(angle)) * speed,
                "size": size,
                "color": color,
                "life": life,
                "max_life": life
            }
            self.particles.append(particle)
        
        # Remove egg
        self.c.delete(egg_data["egg"])
        self.c.delete(egg_data["shine"])
    
    def update_particles(self):
        particles_to_remove = []
        
        for particle in self.particles:
            particle["x"] += particle["dx"]
            particle["y"] += particle["dy"]
            particle["life"] -= 1
            
            if particle["life"] <= 0:
                particles_to_remove.append(particle)
                continue
            
            # Draw particle
            x, y = particle["x"], particle["y"]
            size = particle["size"]
            self.c.create_oval(x, y, x + size, y + size, 
                              fill=particle["color"], outline="", tags="particle")
        
        # Remove dead particles
        for particle in particles_to_remove:
            self.particles.remove(particle)
        
        self.c.delete("particle")
        self.win.after(30, self.update_particles)
    
    def update_animations(self):
        # Update sun pulse
        self.sun_pulse += 0.1
        
        # Update cloud movement
        self.cloud_offset += 0.5
        if self.cloud_offset > self.canvas_width + 200:
            self.cloud_offset = 0
        
        # Redraw background for animations
        self.draw_background()
        
        # Bring game objects to front
        self.c.tag_raise("game")
        self.c.tag_raise("egg")
        self.c.tag_raise("particle")
        
        self.win.after(50, self.update_animations)
    
    def catch_check(self):
        if self.lives_remaining > 0:  # Only check catches if game is active
            catcher_coords = self.c.coords(self.catcher)
            if not catcher_coords:
                self.win.after(50, self.catch_check)
                return
                
            catcher_x, catcher_y, catcher_x2, catcher_y2 = catcher_coords
            current_time = time.time()
            
            for egg_data in self.eggs[:]:
                egg = egg_data["egg"]
                egg_coords = self.c.coords(egg)
                
                if not egg_coords:
                    continue
                    
                egg_x, egg_y, egg_x2, egg_y2 = egg_coords
                
                # Simple collision detection
                if (catcher_x < egg_x and egg_x2 < catcher_x2 and 
                    catcher_y2 - egg_y2 < 50):
                    
                    # Remove egg from list and canvas
                    if egg_data in self.eggs:
                        self.eggs.remove(egg_data)
                        self.c.delete(egg_data["egg"])
                        self.c.delete(egg_data["shine"])
                    
                    # Combo system
                    if current_time - self.last_catch_time < 2.0:
                        self.combo += 1
                    else:
                        self.combo = 1
                    
                    self.last_catch_time = current_time
                    self.combo_label.config(text=f"Combo: {self.combo}x")
                    
                    # Score with combo multiplier
                    points = self.egg_score * self.combo
                    self.create_explosion(egg_data, 8)
                    self.increase_score(points)
                    
                    # Visual feedback
                    theme = self.themes[self.current_theme]
                    original_color = theme["catcher"]
                    self.c.itemconfig(self.catcher, outline="#00FF00")
                    self.win.after(100, lambda: self.c.itemconfig(self.catcher, outline=original_color))
        
        self.win.after(50, self.catch_check)
    
    def increase_score(self, points):
        self.score += points
        # Increase difficulty gradually
        self.egg_speed = max(200, int(self.egg_speed * self.difficulty_factor))
        self.egg_interval = max(1500, int(self.egg_interval * self.difficulty_factor))
        self.c.itemconfig(self.score_text, text=f'🌟 Score: {self.score}')
    
    def move_left(self, event):
        if hasattr(self, 'catcher'):
            catcher_coords = self.c.coords(self.catcher)
            if catcher_coords:
                x1, y1, x2, y2 = catcher_coords
                if x1 > 30:
                    self.c.move(self.catcher, -25, 0)
    
    def move_right(self, event):
        if hasattr(self, 'catcher'):
            catcher_coords = self.c.coords(self.catcher)
            if catcher_coords:
                x1, y1, x2, y2 = catcher_coords
                if x2 < self.canvas_width - 30:
                    self.c.move(self.catcher, 25, 0)
    
    def reset_game(self):
        # Clear all game objects
        self.c.delete("egg")
        self.c.delete("particle")
        
        self.eggs = []
        self.particles = []
        
        # Reset game state
        self.score = 0
        self.lives_remaining = 3
        self.combo = 0
        self.egg_speed = 500
        self.egg_interval = 3500
        
        # Update displays
        self.c.itemconfig(self.score_text, text='🌟 Score: 0')
        self.c.itemconfig(self.lives_text, text='💖 Lives: 3')
        self.combo_label.config(text="Combo: 0x")
        
        # Restart game loops
        self.start_game_loops()
    
    def run(self):
        self.win.mainloop()

# Start the game
if __name__ == "__main__":
    game = CosmicEggCatcher()
    game.run()

کلاس اصلی و متغیرهای بازی

کلاس CosmicEggCatcher شامل تمامی متغیرهای مورد نیاز برای مدیریت بازی است:

Python
class CosmicEggCatcher:
    def __init__(self):
        self.canvas_width = 900
        self.canvas_height = 600
        self.egg_width = 50
        self.egg_height = 60
        self.score = 0
        self.lives_remaining = 3
        self.eggs = []
        self.particles = []
        self.combo = 0

سیستم تم‌های رنگی

این بازی از چندین تم رنگی پشتیبانی می‌کند که به صورت داینامیک قابل تغییر هستند:

Python
self.themes = {
    "Aurora Sky": {
        "sky": "#667eea",
        "ground": "#2E8B57",
        "sun": "#FFD700",
        "text": "#FFFFFF",
        "catcher": "#FF6B6B",
        "cloud": "#FFFFFF",
        "particle": ["#FF6B6B", "#4ECDC4", "#45B7D1"]
    },
    "Sunset Dream": {
        "sky": "#ff7e5f",
        "ground": "#8B4513",
        "sun": "#FF4500",
        "text": "#FFFFFF",
        "catcher": "#FF8C00",
        "cloud": "#FFA07A",
        "particle": ["#FF8C00", "#FF6347", "#FFD700"]
    }
}

ایجاد تخم‌مرغ‌ها

تخم‌مرغ‌ها به صورت تصادفی در موقعیت‌های مختلف ایجاد می‌شوند:

Python
def create_eggs(self):
    if self.lives_remaining > 0:
        x = randrange(20, self.canvas_width - self.egg_width - 20)
        y = 60
        egg_color = next(self.color_cycle)
        new_egg = self.c.create_oval(x, y, x + self.egg_width, y + self.egg_height, 
                                    fill=egg_color, width=0, tags="egg")
        shine = self.c.create_oval(x + 10, y + 10, x + 20, y + 20, 
                                 fill='white', width=0, tags="egg")
        self.eggs.append({"egg": new_egg, "shine": shine})
        self.win.after(self.egg_interval, self.create_eggs)

سیستم کامبو و امتیازدهی

بازیکن با گرفتن تخم‌مرغ‌ها در زمان کوتاه، کامبو می‌گیرد و امتیاز بیشتری دریافت می‌کند:

Python
def catch_check(self):
    catcher_coords = self.c.coords(self.catcher)
    current_time = time.time()
    
    for egg_data in self.eggs[:]:
        egg_coords = self.c.coords(egg_data["egg"])
        
        if (catcher_x < egg_x and egg_x2 < catcher_x2 and 
            catcher_y2 - egg_y2 < 50):
            
            if current_time - self.last_catch_time < 2.0:
                self.combo += 1
            else:
                self.combo = 1
            
            self.last_catch_time = current_time
            points = self.egg_score * self.combo
            self.increase_score(points)

انیمیشن‌ها و افکت‌های بصری

افکت‌های ذره‌ای

هنگام گرفتن تخم‌مرغ یا پایان بازی، افکت‌های ذره‌ای زیبا نمایش داده می‌شود:

Python
def create_explosion(self, egg_data, particle_count=6):
    egg_coords = self.c.coords(egg_data["egg"])
    center_x = (egg_coords[0] + egg_coords[2]) / 2
    center_y = (egg_coords[1] + egg_coords[3]) / 2
    theme = self.themes[self.current_theme]
    
    for _ in range(particle_count):
        angle = randrange(0, 360)
        speed = uniform(2, 6)
        size = randrange(3, 6)
        color = choice(theme["particle"])
        life = randrange(20, 30)
        
        particle = {
            "x": center_x, "y": center_y,
            "dx": math.cos(math.radians(angle)) * speed,
            "dy": math.sin(math.radians(angle)) * speed,
            "size": size,
            "color": color,
            "life": life,
            "max_life": life
        }
        self.particles.append(particle)

انیمیشن‌های محیطی

خورشید پالس می‌زند و ابرها به آرامی در حرکت هستند:

Python
def update_animations(self):
    self.sun_pulse += 0.1
    self.cloud_offset += 0.5
    if self.cloud_offset > self.canvas_width + 200:
        self.cloud_offset = 0
    self.draw_background()
    self.c.tag_raise("game")
    self.c.tag_raise("egg")
    self.c.tag_raise("particle")
    self.win.after(50, self.update_animations)

کنترل‌های بازی

بازیکن می‌تواند از دو روش برای کنترل جمع‌کننده استفاده کند:

  • کلیدهای جهت‌دار چپ و راست (← →)
  • کلیدهای A و D
Python
def move_left(self, event):
    if hasattr(self, 'catcher'):
        catcher_coords = self.c.coords(self.catcher)
        if catcher_coords:
            x1, y1, x2, y2 = catcher_coords
            if x1 > 30:
                self.c.move(self.catcher, -25, 0)

def move_right(self, event):
    if hasattr(self, 'catcher'):
        catcher_coords = self.c.coords(self.catcher)
        if catcher_coords:
            x1, y1, x2, y2 = catcher_coords
            if x2 < self.canvas_width - 30:
                self.c.move(self.catcher, 25, 0)

نحوه اجرا

برای اجرای بازی کافی است فایل پایتون را اجرا کنید:

Python
python cosmic_egg_catcher.py

یا از بخش اصلی برنامه در انتهای فایل استفاده کنید:

Python
if __name__ == "__main__":
    game = CosmicEggCatcher()
    game.run()

توسعه و بهبود

ایده‌هایی برای توسعه بیشتر بازی:

  • افزودن قدرت‌های ویژه (Power-ups)
  • ایجاد مراحل مختلف با سختی progressive
  • ذخیره امتیازهای بالا (High Score)
  • افزودن صدا و موسیقی متن
  • ایجاد تخم‌مرغ‌های خاص با امتیازهای متفاوت

منابع و مستندات

منبع اصلی کد گرفته شده

منبع : https://docs.python.org/3/library/tkinter.html

منبع : https://docs.python.org/3/tutorial/

منبع : https://docs.python.org/3/library/random.html

منبع : https://docs.python.org/3/library/math.html