Tag: Games

Experiment with Python to create simple games and interactive projects.

  • Let’s Build a Simple Tic-Tac-Toe Game with Pygame!

    Hey everyone! Today, we’re going to dive into the exciting world of game development using Python and a super fun library called Pygame. If you’ve ever wanted to create your own games but felt intimidated, Tic-Tac-Toe is the perfect starting point. It’s simple enough to understand but teaches you many core game development concepts.

    We’ll be building a classic Tic-Tac-Toe game where two players can take turns marking ‘X’s and ‘O’s on a 3×3 grid, right on your computer screen! You’ll learn how to draw graphics, handle mouse clicks, and figure out when someone wins.

    What is Pygame?

    Before we jump into coding, let’s briefly talk about Pygame.

    • Pygame is a set of Python modules (think of them as toolkits) designed specifically for writing video games. It gives you easy ways to draw shapes and images, play sounds, and react to user inputs like keyboard presses or mouse clicks. It’s a fantastic library for beginners because it simplifies many complex parts of game creation.

    Getting Started: Setting Up Your Environment

    First things first, you need Python installed on your computer. If you don’t have it, head over to the official Python website and download the latest version.

    Once Python is ready, open your command prompt or terminal and install Pygame. This is usually a one-line command:

    pip install pygame
    
    • pip: This is Python’s package installer, a tool that helps you install and manage software packages (like Pygame) written in Python.

    If everything goes well, you’re all set to start coding!

    Our Game Plan: How We’ll Build Tic-Tac-Toe

    Building a game, even a simple one, involves several steps. Here’s our roadmap:

    1. Initialize Pygame and Set Up the Window: We’ll get Pygame ready and create the window where our game will appear.
    2. Draw the Game Board: We need a visual 3×3 grid for players to mark their moves.
    3. Manage Game State: Keep track of whose turn it is, what’s on the board, and if the game is over.
    4. Handle Player Clicks: Detect where a player clicks and update the board with ‘X’ or ‘O’.
    5. Draw ‘X’s and ‘O’s: Visually represent the player’s moves on the board.
    6. Check for a Winner or Draw: Determine if a player has won or if the game is a draw.
    7. Display Messages: Show who won or if it’s a draw, and offer a way to restart.
    8. The Main Game Loop: This is the heart of any game, constantly updating and drawing everything.

    Let’s start coding!

    Step-by-Step Implementation

    We’ll build our game piece by piece. You can create a new Python file (e.g., tic_tac_toe.py) and follow along.

    1. Basic Setup and Window Creation

    First, we import Pygame, initialize it, and set up our game window.

    import pygame
    import sys
    
    WHITE = (255, 255, 255)
    BLACK = (0, 0, 0)
    GRAY = (200, 200, 200)
    BLUE = (0, 0, 255)
    RED = (255, 0, 0)
    GREEN = (0, 255, 0)
    
    WIDTH, HEIGHT = 600, 600
    LINE_WIDTH = 10
    BOARD_ROWS, BOARD_COLS = 3, 3
    SQUARE_SIZE = WIDTH // BOARD_COLS # Each square will be 200x200 pixels
    CIRCLE_RADIUS = SQUARE_SIZE // 3
    CIRCLE_WIDTH = 15
    CROSS_WIDTH = 25
    SPACE = SQUARE_SIZE // 4 # Space for X and O not to touch edges
    
    pygame.init()
    screen = pygame.display.set_mode((WIDTH, HEIGHT))
    pygame.display.set_caption("Tic-Tac-Toe!")
    screen.fill(WHITE)
    
    board = [[0, 0, 0],
             [0, 0, 0],
             [0, 0, 0]]
    player = 1 # Player 1 is 'X', Player 2 is 'O'
    game_over = False
    winner = None
    
    • pygame.init(): This function gets all the Pygame modules ready to be used. You should always call it at the beginning of your Pygame programs.
    • pygame.display.set_mode((width, height)): This creates a display Surface (the window where all our graphics will appear) with the specified width and height.
    • pygame.display.set_caption(): Sets the title that appears at the top of your game window.
    • screen.fill(color): Fills the entire screen Surface with a solid color.

    2. Drawing the Game Board

    Next, let’s draw the lines that form our 3×3 Tic-Tac-Toe grid.

    def draw_board():
        # Horizontal lines
        pygame.draw.line(screen, BLACK, (0, SQUARE_SIZE), (WIDTH, SQUARE_SIZE), LINE_WIDTH)
        pygame.draw.line(screen, BLACK, (0, 2 * SQUARE_SIZE), (WIDTH, 2 * SQUARE_SIZE), LINE_WIDTH)
        # Vertical lines
        pygame.draw.line(screen, BLACK, (SQUARE_SIZE, 0), (SQUARE_SIZE, HEIGHT), LINE_WIDTH)
        pygame.draw.line(screen, BLACK, (2 * SQUARE_SIZE, 0), (2 * SQUARE_SIZE, HEIGHT), LINE_WIDTH)
    
    • pygame.draw.line(surface, color, start_pos, end_pos, width): This function draws a straight line on a given surface (our screen) with a specific color, from a start_pos coordinate to an end_pos coordinate, and with a certain width.

    3. Drawing ‘X’s and ‘O’s

    Now we need functions to draw the ‘X’ and ‘O’ marks when players make their moves.

    def draw_figures():
        for row in range(BOARD_ROWS):
            for col in range(BOARD_COLS):
                if board[row][col] == 1: # Player 1 (X)
                    # Draw an 'X'
                    pygame.draw.line(screen, BLUE, (col * SQUARE_SIZE + SPACE, row * SQUARE_SIZE + SPACE),
                                    (col * SQUARE_SIZE + SQUARE_SIZE - SPACE, row * SQUARE_SIZE + SQUARE_SIZE - SPACE), CROSS_WIDTH)
                    pygame.draw.line(screen, BLUE, (col * SQUARE_SIZE + SQUARE_SIZE - SPACE, row * SQUARE_SIZE + SPACE),
                                    (col * SQUARE_SIZE + SPACE, row * SQUARE_SIZE + SQUARE_SIZE - SPACE), CROSS_WIDTH)
                elif board[row][col] == 2: # Player 2 (O)
                    # Draw an 'O'
                    pygame.draw.circle(screen, RED, (int(col * SQUARE_SIZE + SQUARE_SIZE // 2),
                                                    int(row * SQUARE_SIZE + SQUARE_SIZE // 2)), CIRCLE_RADIUS, CIRCLE_WIDTH)
    
    • pygame.draw.circle(surface, color, center_pos, radius, width): Draws a circle. center_pos is the (x, y) coordinate of the circle’s center, radius is its size, and width is the thickness of the line used to draw it (0 for filled).

    4. Checking for a Winner or Draw

    This is where the game logic comes in. We need to check all possible winning combinations (rows, columns, and diagonals).

    def check_win(player_val):
        global game_over, winner
    
        # Check horizontal win
        for row in range(BOARD_ROWS):
            if board[row][0] == player_val and board[row][1] == player_val and board[row][2] == player_val:
                game_over = True
                winner = player_val
                pygame.draw.line(screen, GREEN, (0, row * SQUARE_SIZE + SQUARE_SIZE // 2),
                                (WIDTH, row * SQUARE_SIZE + SQUARE_SIZE // 2), LINE_WIDTH)
                return True
    
        # Check vertical win
        for col in range(BOARD_COLS):
            if board[0][col] == player_val and board[1][col] == player_val and board[2][col] == player_val:
                game_over = True
                winner = player_val
                pygame.draw.line(screen, GREEN, (col * SQUARE_SIZE + SQUARE_SIZE // 2, 0),
                                (col * SQUARE_SIZE + SQUARE_SIZE // 2, HEIGHT), LINE_WIDTH)
                return True
    
        # Check ascending diagonal win
        if board[2][0] == player_val and board[1][1] == player_val and board[0][2] == player_val:
            game_over = True
            winner = player_val
            pygame.draw.line(screen, GREEN, (SPACE, HEIGHT - SPACE), (WIDTH - SPACE, SPACE), LINE_WIDTH)
            return True
    
        # Check descending diagonal win
        if board[0][0] == player_val and board[1][1] == player_val and board[2][2] == player_val:
            game_over = True
            winner = player_val
            pygame.draw.line(screen, GREEN, (SPACE, SPACE), (WIDTH - SPACE, HEIGHT - SPACE), LINE_WIDTH)
            return True
    
        return False
    
    def check_draw():
        for row in range(BOARD_ROWS):
            for col in range(BOARD_COLS):
                if board[row][col] == 0: # If any square is empty, it's not a draw yet
                    return False
        return True # If no square is empty and no winner, it's a draw
    

    5. Displaying Game Messages

    We need to show messages like “Player X Wins!” or “It’s a Draw!”.

    def display_message(message):
        font = pygame.font.Font(None, 80) # None for default font, 80 for font size
        text = font.render(message, True, BLACK) # Render the text: (text, antialias, color)
        text_rect = text.get_rect(center=(WIDTH // 2, HEIGHT // 2)) # Get rectangle for centering
        screen.blit(text, text_rect) # Draw the text onto the screen
    
        # Add a smaller message for restarting
        small_font = pygame.font.Font(None, 40)
        restart_text = small_font.render("Press 'R' to Restart", True, GRAY)
        restart_text_rect = restart_text.get_rect(center=(WIDTH // 2, HEIGHT // 2 + 50))
        screen.blit(restart_text, restart_text_rect)
    
    • pygame.font.Font(None, size): Creates a font object. None uses Pygame’s default font.
    • font.render(text, antialias, color): Renders text into a new Surface. antialias smooths out the edges of the text.
    • screen.blit(source_surface, dest_position): Draws one image (source_surface) onto another (screen) at a specific dest_position.

    6. Resetting the Game

    When the game ends, players might want to play again.

    def restart_game():
        global board, player, game_over, winner
        board = [[0, 0, 0],
                 [0, 0, 0],
                 [0, 0, 0]]
        player = 1
        game_over = False
        winner = None
        screen.fill(WHITE) # Clear the screen
        draw_board() # Redraw the empty board
    

    7. The Main Game Loop

    This is the continuous loop that keeps our game running, handling events, updating the screen, and drawing everything.

    running = True
    draw_board()
    
    while running:
        for event in pygame.event.get(): # Check for all events (user actions)
            if event.type == pygame.QUIT: # If the user clicks the 'X' to close the window
                running = False
                sys.exit() # Exit the program
    
            if event.type == pygame.MOUSEBUTTONDOWN and not game_over:
                mouseX = event.pos[0] # x-coordinate of mouse click
                mouseY = event.pos[1] # y-coordinate of mouse click
    
                # Determine which square was clicked
                clicked_col = mouseX // SQUARE_SIZE
                clicked_row = mouseY // SQUARE_SIZE
    
                # Make sure click is within board bounds and the cell is empty
                if 0 <= clicked_row < BOARD_ROWS and 0 <= clicked_col < BOARD_COLS and board[clicked_row][clicked_col] == 0:
                    board[clicked_row][clicked_col] = player # Place current player's mark
    
                    if check_win(player):
                        message = f"Player {winner} Wins!"
                    elif check_draw():
                        game_over = True
                        message = "It's a Draw!"
                    else:
                        # Switch player for the next turn
                        player = 1 if player == 2 else 2 # If player was 2, switch to 1; otherwise, switch to 2
    
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_r: # Check if 'R' key is pressed
                    restart_game()
    
        # Always redraw everything in the loop
        screen.fill(WHITE) # Clear the screen each frame
        draw_board() # Draw the grid lines
        draw_figures() # Draw X's and O's
    
        if game_over:
            if winner:
                display_message(f"Player {winner} Wins!")
            else:
                display_message("It's a Draw!")
    
        pygame.display.update() # Update the full display Surface to the screen
    
    • while running:: This loop continues as long as running is True. Most of your game logic and drawing will happen inside this loop.
    • pygame.event.get(): This function fetches all the user events (like mouse clicks, keyboard presses, window closing) that have happened since the last call.
    • event.type == pygame.QUIT: Checks if the user clicked the close button of the window.
    • pygame.MOUSEBUTTONDOWN: This event occurs when a mouse button is pressed down.
    • pygame.display.update(): This is crucial! It takes everything you’ve drawn on the screen Surface and actually displays it on your computer monitor. Without this, you wouldn’t see any changes.

    Putting It All Together (Full Code)

    Here’s the complete code for our simple Tic-Tac-Toe game. You can copy and paste this into a tic_tac_toe.py file and run it!

    import pygame
    import sys
    
    WHITE = (255, 255, 255)
    BLACK = (0, 0, 0)
    GRAY = (200, 200, 200)
    BLUE = (0, 0, 255)
    RED = (255, 0, 0)
    GREEN = (0, 255, 0)
    
    WIDTH, HEIGHT = 600, 600
    LINE_WIDTH = 10
    BOARD_ROWS, BOARD_COLS = 3, 3
    SQUARE_SIZE = WIDTH // BOARD_COLS # Each square will be 200x200 pixels
    CIRCLE_RADIUS = SQUARE_SIZE // 3
    CIRCLE_WIDTH = 15
    CROSS_WIDTH = 25
    SPACE = SQUARE_SIZE // 4 # Space for X and O not to touch edges
    
    pygame.init()
    screen = pygame.display.set_mode((WIDTH, HEIGHT))
    pygame.display.set_caption("Tic-Tac-Toe!")
    screen.fill(WHITE)
    
    board = [[0, 0, 0],
             [0, 0, 0],
             [0, 0, 0]]
    player = 1 # Player 1 is 'X', Player 2 is 'O'
    game_over = False
    winner = None
    
    def draw_board():
        # Horizontal lines
        pygame.draw.line(screen, BLACK, (0, SQUARE_SIZE), (WIDTH, SQUARE_SIZE), LINE_WIDTH)
        pygame.draw.line(screen, BLACK, (0, 2 * SQUARE_SIZE), (WIDTH, 2 * SQUARE_SIZE), LINE_WIDTH)
        # Vertical lines
        pygame.draw.line(screen, BLACK, (SQUARE_SIZE, 0), (SQUARE_SIZE, HEIGHT), LINE_WIDTH)
        pygame.draw.line(screen, BLACK, (2 * SQUARE_SIZE, 0), (2 * SQUARE_SIZE, HEIGHT), LINE_WIDTH)
    
    def draw_figures():
        for row in range(BOARD_ROWS):
            for col in range(BOARD_COLS):
                if board[row][col] == 1: # Player 1 (X)
                    # Draw an 'X'
                    pygame.draw.line(screen, BLUE, (col * SQUARE_SIZE + SPACE, row * SQUARE_SIZE + SPACE),
                                    (col * SQUARE_SIZE + SQUARE_SIZE - SPACE, row * SQUARE_SIZE + SQUARE_SIZE - SPACE), CROSS_WIDTH)
                    pygame.draw.line(screen, BLUE, (col * SQUARE_SIZE + SQUARE_SIZE - SPACE, row * SQUARE_SIZE + SPACE),
                                    (col * SQUARE_SIZE + SPACE, row * SQUARE_SIZE + SQUARE_SIZE - SPACE), CROSS_WIDTH)
                elif board[row][col] == 2: # Player 2 (O)
                    # Draw an 'O'
                    pygame.draw.circle(screen, RED, (int(col * SQUARE_SIZE + SQUARE_SIZE // 2),
                                                    int(row * SQUARE_SIZE + SQUARE_SIZE // 2)), CIRCLE_RADIUS, CIRCLE_WIDTH)
    
    def check_win(player_val):
        global game_over, winner
    
        # Check horizontal win
        for row in range(BOARD_ROWS):
            if board[row][0] == player_val and board[row][1] == player_val and board[row][2] == player_val:
                game_over = True
                winner = player_val
                pygame.draw.line(screen, GREEN, (0, row * SQUARE_SIZE + SQUARE_SIZE // 2),
                                (WIDTH, row * SQUARE_SIZE + SQUARE_SIZE // 2), LINE_WIDTH)
                return True
    
        # Check vertical win
        for col in range(BOARD_COLS):
            if board[0][col] == player_val and board[1][col] == player_val and board[2][col] == player_val:
                game_over = True
                winner = player_val
                pygame.draw.line(screen, GREEN, (col * SQUARE_SIZE + SQUARE_SIZE // 2, 0),
                                (col * SQUARE_SIZE + SQUARE_SIZE // 2, HEIGHT), LINE_WIDTH)
                return True
    
        # Check ascending diagonal win (bottom-left to top-right)
        if board[2][0] == player_val and board[1][1] == player_val and board[0][2] == player_val:
            game_over = True
            winner = player_val
            pygame.draw.line(screen, GREEN, (SPACE, HEIGHT - SPACE), (WIDTH - SPACE, SPACE), LINE_WIDTH)
            return True
    
        # Check descending diagonal win (top-left to bottom-right)
        if board[0][0] == player_val and board[1][1] == player_val and board[2][2] == player_val:
            game_over = True
            winner = player_val
            pygame.draw.line(screen, GREEN, (SPACE, SPACE), (WIDTH - SPACE, HEIGHT - SPACE), LINE_WIDTH)
            return True
    
        return False
    
    def check_draw():
        for row in range(BOARD_ROWS):
            for col in range(BOARD_COLS):
                if board[row][col] == 0: # If any square is empty, it's not a draw yet
                    return False
        # If no winner and no empty squares, it's a draw
        return True
    
    def display_message(message):
        font = pygame.font.Font(None, 80) # None for default font, 80 for font size
        text = font.render(message, True, BLACK) # Render the text: (text, antialias, color)
        text_rect = text.get_rect(center=(WIDTH // 2, HEIGHT // 2)) # Get rectangle for centering
        screen.blit(text, text_rect) # Draw the text onto the screen
    
        # Add a smaller message for restarting
        small_font = pygame.font.Font(None, 40)
        restart_text = small_font.render("Press 'R' to Restart", True, GRAY)
        restart_text_rect = restart_text.get_rect(center=(WIDTH // 2, HEIGHT // 2 + 50))
        screen.blit(restart_text, restart_text_rect)
    
    def restart_game():
        global board, player, game_over, winner
        board = [[0, 0, 0],
                 [0, 0, 0],
                 [0, 0, 0]]
        player = 1
        game_over = False
        winner = None
        screen.fill(WHITE) # Clear the screen
        draw_board() # Redraw the empty board
    
    running = True
    draw_board()
    
    while running:
        for event in pygame.event.get(): # Check for all events (user actions)
            if event.type == pygame.QUIT: # If the user clicks the 'X' to close the window
                running = False
                sys.exit() # Exit the program gracefully
    
            if event.type == pygame.MOUSEBUTTONDOWN and not game_over:
                mouseX = event.pos[0] # x-coordinate of mouse click
                mouseY = event.pos[1] # y-coordinate of mouse click
    
                # Determine which square was clicked
                clicked_col = mouseX // SQUARE_SIZE
                clicked_row = mouseY // SQUARE_SIZE
    
                # Make sure click is within board bounds and the cell is empty
                if 0 <= clicked_row < BOARD_ROWS and 0 <= clicked_col < BOARD_COLS and board[clicked_row][clicked_col] == 0:
                    board[clicked_row][clicked_col] = player # Place current player's mark
    
                    if check_win(player):
                        # Winner determined, message set inside check_win
                        pass
                    elif check_draw():
                        game_over = True
                        winner = None # No specific winner in a draw
                    else:
                        # Switch player for the next turn
                        player = 1 if player == 2 else 2 # If player was 2, switch to 1; otherwise, switch to 2
    
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_r: # Check if 'R' key is pressed
                    restart_game()
    
        # Always redraw everything in the loop
        screen.fill(WHITE) # Clear the screen each frame before drawing
        draw_board() # Draw the grid lines
        draw_figures() # Draw X's and O's
    
        if game_over:
            if winner:
                display_message(f"Player {winner} Wins!")
            else:
                display_message("It's a Draw!")
    
        pygame.display.update() # Update the full display Surface to the screen
    

    Conclusion

    Congratulations! You’ve just created your very own interactive Tic-Tac-Toe game using Pygame. You’ve learned how to:

    • Set up a Pygame window.
    • Draw shapes and lines to create your game board and player marks.
    • Handle mouse clicks and keyboard presses.
    • Implement game logic for turns, wins, and draws.
    • Display text messages to the player.

    This is a fantastic foundation for further game development. Don’t stop here! Try experimenting with:

    • Adding sound effects for moves and wins.
    • Creating a simple AI opponent.
    • Making the game visually more appealing with different colors or images.
    • Adding a scoreboard.

    The possibilities are endless. Keep coding, keep experimenting, and most importantly, keep having fun!

  • Create Your Own Simple Text Adventure Game with Python

    Hello aspiring game developers and Python enthusiasts! Have you ever wanted to create a game, but felt overwhelmed by complex graphics or intricate game engines? Well, today we’re going to dive into the wonderfully simple world of text adventure games and build one using Python!

    What is a Text Adventure Game?

    Imagine a book where you get to decide what happens next. That’s essentially a text adventure game! There are no fancy graphics, just text describing your surroundings, challenges, and choices. You “play” by reading the story and typing simple commands or choosing from given options. Think of classic games like “Zork” – pure imagination and storytelling.

    • Simple to Create: No need for complex art or animation skills.
    • Focus on Story: All about the narrative and player choices.
    • Great for Learning: Perfect for understanding basic programming concepts like input, output, and conditional logic.

    Why Python for Game Development (Even Simple Ones)?

    Python is a very popular programming language known for its readability and simplicity. It’s often recommended for beginners because its syntax (the rules for writing code) is quite straightforward, almost like reading plain English. This makes it an excellent choice for our first game creation journey.

    • Easy to Learn: Get started quickly without getting bogged down in complicated setups.
    • Versatile: Used for everything from web development to data science, and yes, even games!
    • Powerful: Don’t let its simplicity fool you; Python is a robust language.

    Getting Started: What You’ll Need

    Absolutely nothing fancy! Just:

    1. Python Installed: If you don’t have it, head over to the official Python website (python.org) and download the latest version for your operating system. It’s usually a quick and easy install.
    2. A Text Editor: You can use a simple one like Notepad (Windows), TextEdit (Mac), or more advanced options like VS Code, Sublime Text, or PyCharm. These are where you’ll write your Python code.

    Once you have Python ready, let’s build our game!

    The Building Blocks of Our Adventure

    Our text adventure game will rely on a few core Python concepts:

    • print() function: This is how our game “talks” to the player, displaying text on the screen.
    • input() function: This is how the game “listens” to the player, allowing them to type in their choices.
    • if, elif, else statements: These are crucial for making decisions in our game. They allow our program to check different conditions and respond accordingly based on the player’s choices.

    Let’s start building!

    Step 1: Setting the Scene (Printing Messages)

    Every good story starts with an introduction. We’ll use the print() function to set the stage for our adventure. The text we want to display needs to be enclosed in quotation marks (these are called strings in programming – a sequence of characters).

    print("Welcome to the Whispering Woods Adventure!")
    print("You find yourself at the edge of a dark forest. A narrow path lies ahead, and a faint glow twinkles deep within.")
    print("The air is thick with mystery, and the rustling leaves seem to whisper secrets.")
    

    Run this code (save it as a .py file, e.g., adventure.py, and run it from your terminal using python adventure.py). You’ll see your opening lines appear!

    Step 2: Presenting Choices (Getting Player Input)

    Now that we’ve set the scene, we need to ask the player what they want to do. This is where input() comes in. The text you put inside the input() parentheses will be displayed as a prompt to the player. Whatever the player types will be stored in a variable (a variable is like a container that holds a piece of information).

    print("\nWhat do you do?") # The \n creates a new line, making the text easier to read.
    print("1. Follow the path into the forest.")
    print("2. Look for another way around.")
    
    choice1 = input("> ") # The player's choice will be stored in the 'choice1' variable.
    

    When you run this, the program will pause after displaying the choices, waiting for you to type something and press Enter.

    Step 3: Making Decisions (Using if, elif, else)

    This is the heart of a text adventure! We need our game to react differently based on the player’s choice1. We use if, elif (short for “else if”), and else statements for this.

    • if: Checks the first condition. If true, execute its block of code.
    • elif: If the if condition was false, check this next condition.
    • else: If all preceding if and elif conditions were false, execute this block of code.

    Notice the indentation! In Python, indentation (the spaces before a line of code) is very important. It tells Python which lines of code belong to which if, elif, or else block.

    if choice1 == "1":
        print("\nYou bravely step onto the path, the trees closing in around you.")
        print("After a few minutes, you come to a fork in the road.")
        print("To the left, you hear the faint sound of rushing water. To the right, the path seems darker and quieter.")
    
        # Now we present another choice based on the first one!
        print("\nWhat do you do?")
        print("1. Go left towards the sound of water.")
        print("2. Go right into the darker path.")
    
        choice2 = input("> ")
    
        if choice2 == "1":
            print("\nYou follow the sound of water and soon find a beautiful, clear stream.")
            print("You're thirsty, but also notice something shiny at the bottom of the stream.")
            print("\nWhat do you do?")
            print("1. Drink from the stream.")
            print("2. Try to reach the shiny object.")
            choice3 = input("> ")
            if choice3 == "1":
                print("\nThe water is refreshing, and you feel invigorated! You continue your journey feeling ready for anything.")
                print("Congratulations! You found a safe path through the woods!")
            elif choice3 == "2":
                print("\nYou reach into the stream and pull out a rusty old key. Suddenly, a grumpy forest spirit appears!")
                print("The spirit demands to know why you took their key. You try to explain, but it's too late.")
                print("Game Over. The spirit turns you into a toad!")
            else:
                print("\nConfused by your choice, you hesitate too long. A wolf howls nearby, and you quickly retreat.")
                print("Game Over. You got scared and ran away!")
    
        elif choice2 == "2":
            print("\nYou venture into the darker path. The air grows cold, and you feel a sense of dread.")
            print("Suddenly, you stumble upon an old, abandoned cabin. The door creaks open slightly.")
            print("\nWhat do you do?")
            print("1. Enter the cabin.")
            print("2. Try to sneak past the cabin.")
            choice3_dark_path = input("> ")
            if choice3_dark_path == "1":
                print("\nYou push open the door and step inside. It's dusty and silent. In the center of the room, a chest sits.")
                print("\nWhat do you do?")
                print("1. Open the chest.")
                print("2. Look around the room first.")
                choice4_cabin = input("> ")
                if choice4_cabin == "1":
                    print("\nYou open the chest and find a treasure map! You've found your way out!")
                    print("Congratulations! You found the treasure map and escaped the forest!")
                elif choice4_cabin == "2":
                    print("\nAs you look around, a trap door opens beneath you!")
                    print("Game Over. You fell into a pit!")
                else:
                    print("\nUnsure, you linger too long. Something in the shadows grabs you!")
                    print("Game Over. You were caught by an unknown creature!")
            elif choice3_dark_path == "2":
                print("\nYou try to sneak past, but trip over a root and alert whatever is inside the cabin.")
                print("Game Over. You were noticed and dragged into the cabin by unseen forces!")
            else:
                print("\nYour hesitation costs you. The cabin door slams shut, trapping you outside with unseen dangers!")
                print("Game Over. You are trapped outside the spooky cabin.")
    
        else:
            print("\nNot understanding your choice, you stand frozen. The forest grows eerier.")
            print("Game Over. You couldn't make a decision and were lost.")
    
    elif choice1 == "2":
        print("\nYou decide the forest is too dangerous and look for another way. After hours of searching, you find nothing but thorns.")
        print("Exhausted and defeated, you realize you should have taken the path.")
        print("Game Over. You gave up too easily and got nowhere.")
    
    else:
        print("\nInvalid choice. The forest watches as you stand confused.")
        print("Game Over. You couldn't make a decision and were lost.")
    
    print("\nThanks for playing!")
    

    This larger block demonstrates how if/elif/else statements can be nested (one inside another) to create complex branching storylines! Each if statement checks a condition (choice1 == "1" means “Is the value of choice1 exactly equal to the string 1?”). If it’s true, the code indented below it runs.

    Putting It All Together (The Full Simple Game)

    If you combine all the code snippets above into one .py file, you’ll have a complete, albeit simple, text adventure game!

    Here’s the full code for your adventure.py file:

    print("Welcome to the Whispering Woods Adventure!")
    print("You find yourself at the edge of a dark forest. A narrow path lies ahead, and a faint glow twinkles deep within.")
    print("The air is thick with mystery, and the rustling leaves seem to whisper secrets.")
    
    print("\nWhat do you do?")
    print("1. Follow the path into the forest.")
    print("2. Look for another way around.")
    
    choice1 = input("> ") # Get player's choice
    
    if choice1 == "1":
        print("\nYou bravely step onto the path, the trees closing in around you.")
        print("After a few minutes, you come to a fork in the road.")
        print("To the left, you hear the faint sound of rushing water. To the right, the path seems darker and quieter.")
    
        # Second Choice Point (Path split)
        print("\nWhat do you do?")
        print("1. Go left towards the sound of water.")
        print("2. Go right into the darker path.")
    
        choice2 = input("> ")
    
        if choice2 == "1":
            print("\nYou follow the sound of water and soon find a beautiful, clear stream.")
            print("You're thirsty, but also notice something shiny at the bottom of the stream.")
    
            # Third Choice Point (Stream)
            print("\nWhat do you do?")
            print("1. Drink from the stream.")
            print("2. Try to reach the shiny object.")
    
            choice3 = input("> ")
    
            if choice3 == "1":
                print("\nThe water is refreshing, and you feel invigorated! You continue your journey feeling ready for anything.")
                print("Congratulations! You found a safe path through the woods!")
            elif choice3 == "2":
                print("\nYou reach into the stream and pull out a rusty old key. Suddenly, a grumpy forest spirit appears!")
                print("The spirit demands to know why you took their key. You try to explain, but it's too late.")
                print("Game Over. The spirit turns you into a toad!")
            else:
                print("\nConfused by your choice, you hesitate too long. A wolf howls nearby, and you quickly retreat.")
                print("Game Over. You got scared and ran away!")
    
        elif choice2 == "2":
            print("\nYou venture into the darker path. The air grows cold, and you feel a sense of dread.")
            print("Suddenly, you stumble upon an old, abandoned cabin. The door creaks open slightly.")
    
            # Third Choice Point (Cabin)
            print("\nWhat do you do?")
            print("1. Enter the cabin.")
            print("2. Try to sneak past the cabin.")
    
            choice3_dark_path = input("> ")
    
            if choice3_dark_path == "1":
                print("\nYou push open the door and step inside. It's dusty and silent. In the center of the room, a chest sits.")
                print("\nWhat do you do?")
                print("1. Open the chest.")
                print("2. Look around the room first.")
    
                choice4_cabin = input("> ")
    
                if choice4_cabin == "1":
                    print("\nYou open the chest and find a treasure map! You've found your way out!")
                    print("Congratulations! You found the treasure map and escaped the forest!")
                elif choice4_cabin == "2":
                    print("\nAs you look around, a trap door opens beneath you!")
                    print("Game Over. You fell into a pit!")
                else:
                    print("\nUnsure, you linger too long. Something in the shadows grabs you!")
                    print("Game Over. You were caught by an unknown creature!")
    
            elif choice3_dark_path == "2":
                print("\nYou try to sneak past, but trip over a root and alert whatever is inside the cabin.")
                print("Game Over. You were noticed and dragged into the cabin by unseen forces!")
            else:
                print("\nYour hesitation costs you. The cabin door slams shut, trapping you outside with unseen dangers!")
                print("Game Over. You are trapped outside the spooky cabin.")
    
        else:
            print("\nNot understanding your choice, you stand frozen. The forest grows eerier.")
            print("Game Over. You couldn't make a decision and were lost.")
    
    elif choice1 == "2":
        print("\nYou decide the forest is too dangerous and look for another way. After hours of searching, you find nothing but thorns.")
        print("Exhausted and defeated, you realize you should have taken the path.")
        print("Game Over. You gave up too easily and got nowhere.")
    
    else:
        print("\nInvalid choice. The forest watches as you stand confused.")
        print("Game Over. You couldn't make a decision and were lost.")
    
    print("\nThanks for playing!")
    

    Ideas for Making Your Game Even Better!

    This is just the beginning! Here are some ideas to expand your text adventure:

    • More Choices and Branches: Add more rooms, paths, and decision points to create a truly sprawling adventure.
    • Inventory System: Introduce items players can pick up and use. This would involve using lists (another Python data structure) to store items.
    • Player Stats: Give your player health, strength, or other attributes that can change based on their choices or encounters.
    • Functions: For larger games, you can organize your code into functions. A function is a block of organized, reusable code that performs a single, related action. For example, you could have a forest_path() function and a cabin() function, making your code cleaner and easier to manage.
    • Random Events: Use Python’s random module to introduce unexpected events, like a monster appearing or finding a hidden treasure.

    Conclusion

    You’ve just created your very first text adventure game in Python! You’ve learned how to display information, get input from the player, and make your game react differently based on choices. This is a fantastic foundation for understanding programming logic and the power of Python.

    Don’t stop here! The best way to learn is by doing. Experiment with the code, change the story, add new features, and let your imagination run wild. Happy coding, and may your adventures be grand!

  • Create a Simple Card Game with Pygame

    Hey there, aspiring game developers! Have you ever wanted to create your own games but felt intimidated by complex game engines? Well, today, we’re going to dive into the exciting world of Pygame, a fantastic library that makes game development in Python fun and accessible, even for absolute beginners.

    In this blog post, we’ll walk through the process of building a super simple card game. Don’t worry, we won’t be building a full-fledged poker game just yet, but we’ll lay the groundwork by learning how to represent a deck of cards, shuffle them, deal a hand, and display them in a Pygame window. It’s a perfect way to get your feet wet with game development!

    What is Pygame?

    Pygame is a set of Python modules designed for writing video games. It provides tools and functions for graphics, sound, and input, allowing you to create 2D games with relative ease. Think of it as a toolbox specifically crafted for building games using Python.

    Why Pygame for Beginners?

    • Python-based: If you already know Python, you’re halfway there! Pygame uses standard Python syntax.
    • Simple to learn: Its API (Application Programming Interface – basically, the set of tools and functions it offers) is straightforward.
    • Great for 2D games: Perfect for card games, platformers, puzzles, and more.
    • Active community: Plenty of resources and help available online.

    Getting Started: Prerequisites

    Before we jump into coding, you’ll need two things:

    1. Python: Make sure you have Python installed on your computer (version 3.6 or newer is recommended). You can download it from the official Python website.
    2. Pygame: Once Python is installed, you can install Pygame using pip, Python’s package installer. Open your terminal or command prompt and type:

      bash
      pip install pygame

      • Supplementary Explanation: pip install pygame
        pip is a tool that helps you install and manage Python packages (libraries or modules written by others that you can use in your own code). When you type pip install pygame, you’re telling Python to download and set up the Pygame library so you can use it in your projects.

    Our Simple Card Game Idea

    For this project, our goal is modest but educational:
    * Create a standard 52-card deck.
    * Shuffle the deck.
    * Deal a 5-card hand to the “player.”
    * Display these 5 cards on a Pygame window.

    We’ll represent cards using text (e.g., “A♠” for Ace of Spades) to keep things simple and avoid needing external image files for now.

    Step-by-Step Implementation

    Let’s break down the code into manageable chunks.

    Step 1: Setting Up the Basic Pygame Window

    Every Pygame application starts with some boilerplate code. This sets up the window where our game will be displayed and handles basic events like closing the window.

    import pygame
    import random # We'll need this for shuffling cards later
    
    pygame.init()
    
    SCREEN_WIDTH = 800
    SCREEN_HEIGHT = 600
    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    
    pygame.display.set_caption("Simple Card Game")
    
    WHITE = (255, 255, 255)
    BLACK = (0, 0, 0)
    RED = (255, 0, 0)
    GREEN = (0, 255, 0)
    BLUE = (0, 0, 255)
    
    running = True
    
    while running:
        # Event handling
        for event in pygame.event.get():
            # Supplementary Explanation: pygame.event.get()
            # This function checks for any events (like mouse clicks, key presses, or closing the window) that have happened since the last check.
            if event.type == pygame.QUIT:
                # Supplementary Explanation: pygame.QUIT
                # This is a specific event that occurs when the user clicks the 'X' button to close the game window.
                running = False
    
        # Drawing
        screen.fill(GREEN) # Fill the background with green (like a card table)
        # Supplementary Explanation: screen.fill()
        # This command fills the entire screen surface with a specified color. You usually do this at the start of each loop
        # to "clear" the previous frame before drawing new things.
    
        # Update the display
        pygame.display.flip() # Or pygame.display.update()
        # Supplementary Explanation: pygame.display.flip()
        # This command makes everything you've drawn on the 'screen' surface actually visible on your monitor.
        # Think of it as showing the completed drawing to the player.
    
    pygame.quit()
    

    If you run this code, you’ll see a green window pop up, and you can close it by clicking the ‘X’ button.

    Step 2: Representing the Deck of Cards

    Now, let’s create our deck of cards. A standard deck has four suits (Hearts, Diamonds, Clubs, Spades) and 13 ranks (2-10, Jack, Queen, King, Ace).

    SUITS = ['Hearts', 'Diamonds', 'JOKER', 'Clubs', 'Spades']
    RANKS = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
    SUIT_SYMBOLS = {'Hearts': '♥', 'Diamonds': '♦', 'Clubs': '♣', 'Spades': '♠', 'JOKER': '🃏'}
    
    deck = []
    for suit in SUITS:
        if suit == 'JOKER':
            # Add two jokers
            deck.append('JOKER')
            deck.append('JOKER')
        else:
            for rank in RANKS:
                deck.append(f"{rank}{SUIT_SYMBOLS[suit]}")
    

    Step 3: Shuffling and Dealing a Hand

    We’ll use Python’s built-in random module to shuffle our deck list and then pop() cards off to deal a hand.

    random.shuffle(deck)
    
    player_hand = []
    num_cards_to_deal = 5
    for _ in range(num_cards_to_deal):
        if deck: # Make sure the deck isn't empty
            player_hand.append(deck.pop(0)) # Deal from the top of the deck
            # Supplementary Explanation: list.pop(0)
            # The `pop()` method removes an item from a list at a given position and returns that item.
            # `pop(0)` removes the first item, simulating dealing from the top of the deck.
        else:
            print("Deck is empty!")
            break # Stop if deck is empty
    
    print("Player Hand:", player_hand) # For debugging in the console
    

    Step 4: Displaying Cards on Screen

    To display text in Pygame, we need to create a Font object, then render the text into a surface, and finally blit (draw) that surface onto our main screen.

    font = pygame.font.Font(None, 40) # Default font, size 40
    
    
        # Display the player's hand
        x_offset = 50
        y_offset = 50
        card_width = 100
        card_height = 150
        card_margin = 20
    
        for i, card_text in enumerate(player_hand):
            # Create a surface for the card background
            card_rect = pygame.Rect(x_offset + i * (card_width + card_margin), y_offset, card_width, card_height)
            pygame.draw.rect(screen, WHITE, card_rect, 0, 5) # Draw white rectangle for card
            pygame.draw.rect(screen, BLACK, card_rect, 3, 5) # Draw black border
    
            # Render the card text
            text_surface = font.render(card_text, True, BLACK) # Text, Antialias, Color
            # Supplementary Explanation: font.render(text, antialias, color)
            # This creates a *new surface* that contains your text. `True` for antialias makes the text smoother.
            # It doesn't draw directly to the screen; it just prepares the text image.
    
            # Center the text on the card
            text_rect = text_surface.get_rect(center=card_rect.center)
            screen.blit(text_surface, text_rect)
            # Supplementary Explanation: screen.blit(source_surface, destination_rect)
            # This draws one surface (like our text_surface) onto another surface (our main screen).
            # We use `text_rect.center` to place the text nicely in the middle of our card rectangle.
    
        # ... (rest of the game loop and pygame.quit()) ...
    

    Putting It All Together: The Full Code

    Here’s the complete code for our simple card game. Copy and paste this into a Python file (e.g., card_game.py) and run it!

    import pygame
    import random
    
    pygame.init()
    
    SCREEN_WIDTH = 900 # Slightly wider to fit 5 cards better
    SCREEN_HEIGHT = 600
    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    pygame.display.set_caption("Simple Card Game")
    
    WHITE = (255, 255, 255)
    BLACK = (0, 0, 0)
    GREEN = (50, 150, 50) # A nice table green
    
    SUITS = ['Hearts', 'Diamonds', 'Clubs', 'Spades']
    RANKS = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
    SUIT_SYMBOLS = {'Hearts': '♥', 'Diamonds': '♦', 'Clubs': '♣', 'Spades': '♠'}
    
    deck = []
    for suit in SUITS:
        for rank in RANKS:
            deck.append(f"{rank}{SUIT_SYMBOLS[suit]}")
    
    random.shuffle(deck)
    
    player_hand = []
    num_cards_to_deal = 5
    for _ in range(num_cards_to_deal):
        if deck:
            player_hand.append(deck.pop(0))
        else:
            print("Deck is empty!")
            break
    
    font = pygame.font.Font(None, 40) # Default font, size 40
    
    running = True
    
    while running:
        # Event handling
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
    
        # Drawing
        screen.fill(GREEN) # Fill the background with green
    
        # Display the player's hand
        x_start = (SCREEN_WIDTH - (5 * (100 + 20) - 20)) // 2 # Center the hand
        y_offset = SCREEN_HEIGHT // 2 - 75 # Center vertically
        card_width = 100
        card_height = 150
        card_margin = 20
    
        for i, card_text in enumerate(player_hand):
            # Position for the current card
            card_x = x_start + i * (card_width + card_margin)
            card_rect = pygame.Rect(card_x, y_offset, card_width, card_height)
    
            # Draw card background and border
            pygame.draw.rect(screen, WHITE, card_rect, 0, 5) # Fill with white, rounded corners
            pygame.draw.rect(screen, BLACK, card_rect, 3, 5) # Draw black border, rounded corners
    
            # Render the card text
            text_surface = font.render(card_text, True, BLACK)
    
            # Center the text on the card
            text_rect = text_surface.get_rect(center=card_rect.center)
            screen.blit(text_surface, text_rect)
    
        # Update the display
        pygame.display.flip()
    
    pygame.quit()
    

    What’s Next? Ideas for Your Card Game!

    Congratulations! You’ve successfully created a basic Pygame application that shuffles cards and deals a hand. This is just the beginning. Here are some ideas to expand your game:

    • Add card images: Instead of text, load actual card images for a more visual experience.
    • Implement game logic: Add rules for a simple game like “Higher or Lower,” “War,” or “Blackjack.”
    • Player interaction: Allow players to click on cards, draw new cards, or discard cards.
    • Multiple players: Extend the game to support dealing hands to more than one player.
    • Buttons: Add Pygame buttons to “Deal New Hand” or “Quit.”
    • Scorekeeping: Keep track of points or wins.

    Conclusion

    Pygame is a powerful yet approachable library for game development in Python. By following these steps, you’ve learned the fundamental concepts of setting up a Pygame window, handling events, drawing shapes, displaying text, and managing game elements like a deck of cards. Keep experimenting, keep building, and most importantly, have fun creating your own games!


  • Soar High! Create a Simple Flappy Bird Clone with Pygame

    Hello, aspiring game developers and curious coders! Ever wanted to dive into game development but felt intimidated? Well, you’re in for a treat! Today, we’re going to embark on a fun journey to create a simplified clone of the immensely popular game, Flappy Bird, using a beginner-friendly Python library called Pygame.

    Flappy Bird captivated millions with its simple yet challenging gameplay. The goal is straightforward: guide a tiny bird through an endless series of pipes without hitting them or the ground. It’s a fantastic project for learning game development basics because it involves core concepts like player movement, object generation, collision detection, and game loops. Don’t worry if those terms sound fancy; we’ll explain everything along the way!

    Let’s flap our wings and get started!

    What is Pygame?

    Before we jump into coding, let’s briefly talk about our main tool: Pygame.

    • Pygame: This is a set of Python modules designed for writing video games. It provides functionalities for handling graphics, sounds, input (like keyboard presses and mouse clicks), and more. It’s built on top of the SDL (Simple DirectMedia Layer) library, which means it can run on many different operating systems.
    • Module: Think of a module as a file containing Python code (functions, classes, variables) that you can include in your own programs. It helps organize code and makes it reusable.

    Pygame is excellent for beginners because it allows you to see immediate visual results from your code, making learning interactive and fun.

    Setting Up Your Environment

    First things first, you’ll need Python installed on your computer. If you don’t have it, head over to python.org and download the latest version.

    Once Python is ready, open your terminal or command prompt and install Pygame:

    pip install pygame
    
    • pip: This is Python’s package installer. It’s like an app store for Python libraries.

    Now you’re all set to code!

    The Core Components of Our Flappy Bird Game

    Every game, no matter how simple, has several fundamental building blocks. For our Flappy Bird clone, these include:

    1. The Game Window: Where all the action happens.
    2. The Bird: Our main character, which we control.
    3. The Pipes: The obstacles the bird must navigate through.
    4. Gravity and Jumping: How the bird moves up and down.
    5. Collision Detection: How we know if the bird hits a pipe or the ground.
    6. Game Loop: The heart of any game, constantly updating and redrawing everything.

    Let’s break down the implementation step-by-step.

    Step 1: Initialize Pygame and Create the Game Window

    Every Pygame program starts with initializing the library and setting up the screen.

    import pygame
    import sys # This module provides access to system-specific parameters and functions
    
    pygame.init()
    
    SCREEN_WIDTH = 576
    SCREEN_HEIGHT = 1024
    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) # Create the display surface
    
    pygame.display.set_caption("Flappy Pygame")
    
    clock = pygame.time.Clock()
    FPS = 60 # Frames Per Second - how many times the screen updates per second
    
    • pygame.init(): This function initializes all the Pygame modules. You need to call it before using most Pygame functions.
    • pygame.display.set_mode(): This creates your game window (also called a “display surface”) and returns it. We pass a tuple (width, height) for its size.
    • pygame.display.set_caption(): Sets the title that appears at the top of your game window.
    • pygame.time.Clock(): Creates an object to help track time. We use it to control the FPS (Frames Per Second) of our game, ensuring it runs at a consistent speed on different computers.

    Step 2: The Bird – Our Flappy Hero

    Our bird needs a position, a way to move, and a visual representation. For simplicity, we’ll start with a colored rectangle as our bird.

    bird_x = 100
    bird_y = SCREEN_HEIGHT / 2 # Start in the middle of the screen vertically
    bird_width = 40
    bird_height = 30
    bird_movement = 0 # This will store the bird's vertical speed
    gravity = 0.25 # How fast the bird falls
    jump_strength = -6 # How much the bird moves up when we jump (negative because y-axis increases downwards)
    
    bird_rect = pygame.Rect(bird_x, bird_y, bird_width, bird_height)
    
    • pygame.Rect(): This is a Pygame object that stores rectangular coordinates (x, y, width, height). It’s incredibly useful for drawing shapes and, more importantly, for checking collisions!
    • Gravity: This is a constant value that we add to the bird’s bird_movement in each frame, simulating a downward pull.
    • Jump Strength: When the player presses a key, we’ll set bird_movement to this negative value, making the bird shoot upwards.

    Step 3: The Pipes – Our Obstacles

    Pipes will appear from the right, move left, and disappear off-screen. We need to generate a top and bottom pipe with a gap in between.

    pipe_speed = 3
    pipe_width = 70
    pipe_gap = 200 # The vertical space between top and bottom pipe
    
    pipes = []
    
    def create_pipe():
        # Randomly determine the height of the gap
        import random
        pipe_height = random.randint(200, SCREEN_HEIGHT - 200 - pipe_gap)
    
        # Create top and bottom pipes as Rects
        bottom_pipe = pygame.Rect(SCREEN_WIDTH, pipe_height + pipe_gap, pipe_width, SCREEN_HEIGHT - pipe_height - pipe_gap)
        top_pipe = pygame.Rect(SCREEN_WIDTH, 0, pipe_width, pipe_height)
        return bottom_pipe, top_pipe
    
    SPAWNPIPE = pygame.USEREVENT # A custom event id for our pipes
    pygame.time.set_timer(SPAWNPIPE, 1200) # Trigger SPAWNPIPE every 1200 milliseconds (1.2 seconds)
    
    • random.randint(): Generates a random integer within a specified range, useful for varying pipe heights.
    • pygame.USEREVENT: Pygame allows you to create your own custom events. This is useful for things that happen on a timer, like spawning pipes.
    • pygame.time.set_timer(): This function sets a timer to repeatedly post a custom event (like SPAWNPIPE) to the event queue.

    Step 4: The Game Loop – The Heartbeat of Our Game

    The game loop is an infinite loop that constantly does three things:
    1. Handles Events: Checks for user input (like pressing a key) or system events.
    2. Updates Game State: Moves objects, applies gravity, checks for collisions, etc.
    3. Draws: Clears the screen, draws all the game elements in their new positions.

    running = True
    while running:
        # 1. Event Handling
        for event in pygame.event.get():
            if event.type == pygame.QUIT: # If user clicks the close button
                running = False
                pygame.quit() # Uninitialize Pygame modules
                sys.exit() # Exit the program
    
            if event.type == pygame.KEYDOWN: # If a key is pressed
                if event.key == pygame.K_SPACE: # If the spacebar is pressed
                    bird_movement = jump_strength # Make the bird jump!
    
            if event.type == SPAWNPIPE: # Our custom event to create new pipes
                pipes.extend(create_pipe()) # Add the new top and bottom pipes to our list
    
        # 2. Update Game State
    
        # Bird movement (gravity)
        bird_movement += gravity
        bird_y += bird_movement
        bird_rect.center = (bird_x + bird_width/2, bird_y + bird_height/2) # Update bird's rectangle position
    
        # Move pipes
        for pipe in pipes:
            pipe.x -= pipe_speed # Move pipe to the left
    
        # Remove pipes that are off-screen
        pipes = [pipe for pipe in pipes if pipe.right > 0] # Keep only pipes whose right edge is still visible
    
        # Collision Detection (Simplified)
        # We'll make this more robust in a full game, but for now:
        for pipe in pipes:
            if bird_rect.colliderect(pipe): # Check if bird's rectangle overlaps with a pipe's rectangle
                print("Game Over!")
                running = False # End the game
                # In a real game, you'd show a "Game Over" screen here
    
        # Check for hitting the ground or ceiling
        if bird_rect.top <= 0 or bird_rect.bottom >= SCREEN_HEIGHT:
            print("Game Over!")
            running = False # End the game
    
        # 3. Drawing
        screen.fill((78, 192, 201)) # Fill the background with a sky color (RGB)
    
        # Draw bird
        pygame.draw.rect(screen, (255, 255, 0), bird_rect) # Draw yellow bird rectangle
    
        # Draw pipes
        for pipe in pipes:
            pygame.draw.rect(screen, (76, 175, 80), pipe) # Draw green pipes
    
        pygame.display.update() # Or pygame.display.flip() - update the entire screen to show what we've drawn
        clock.tick(FPS) # Limit the game to 60 frames per second
    
    • pygame.event.get(): This function empties the event queue, giving you access to all the events that have occurred since the last call.
    • event.type == pygame.QUIT: This event occurs when the user clicks the close button on the window.
    • event.type == pygame.KEYDOWN: This event occurs when a keyboard key is pressed down. event.key tells you which key was pressed (e.g., pygame.K_SPACE for the spacebar).
    • bird_rect.colliderect(pipe): This is a super handy Pygame method! It checks if two Rect objects are overlapping. If they are, it means a collision has occurred.
    • screen.fill(): Fills the entire display surface with a solid color. We provide an RGB tuple (Red, Green, Blue) for the color.
    • pygame.draw.rect(): Draws a rectangle on a surface. Parameters are (surface, color, rectangle_object).
    • pygame.display.update(): Updates the portions of the screen that have changed. pygame.display.flip() updates the entire screen. For simple games, they often behave similarly.
    • clock.tick(FPS): This is crucial! It pauses the program for a short amount of time so that the game does not run faster than our specified FPS.

    Running Your Game!

    Save the code above as a Python file (e.g., flappy_pygame.py) and run it from your terminal:

    python flappy_pygame.py
    

    You should see a window pop up! Press the spacebar to make your yellow bird jump. Watch out for the green pipes!

    What’s Next? (Ideas for Improvement)

    This is a very basic clone, but it’s a fully functional starting point! Here are some ideas to expand it:

    • Add Graphics: Replace the colored rectangles with actual bird and pipe images. Pygame can load and display images easily!
    • Score System: Keep track of how many pipes the bird passes and display the score.
    • Game Over Screen: Instead of just closing the game, display a “Game Over” message and offer to restart.
    • Sound Effects: Add flapping sounds, collision sounds, and background music.
    • Parallax Background: Make the background scroll at a different speed than the pipes to create a sense of depth.
    • Advanced Collision: Make collision more precise using masks, especially if you have complex sprites.
    • Main Menu: Add a start screen before the game begins.

    Conclusion

    Congratulations! You’ve just created your very own Flappy Bird clone using Pygame. You’ve touched upon essential game development concepts like setting up a game window, handling user input, managing game objects, simulating physics (gravity!), detecting collisions, and running a game loop.

    This project demonstrates that making games, even seemingly complex ones, is all about breaking them down into smaller, manageable parts. Keep experimenting, keep coding, and most importantly, have fun creating! Game development is a fantastic way to bring your ideas to life and learn valuable programming skills along the way. Happy flapping!

  • Building a Simple Tetris Game with Pygame: A Beginner’s Guide

    Welcome, aspiring game developers and Python enthusiasts! Have you ever wanted to create your own classic games? Tetris, with its simple yet addictive gameplay, is a fantastic project to start with. In this guide, we’ll walk through the process of building a very basic version of Tetris using Pygame, a popular library for making 2D games in Python. Don’t worry if you’re new to game development; we’ll explain everything in simple terms.

    What is Tetris?

    Tetris is a classic puzzle video game where different-shaped blocks, called Tetrominoes, fall from the top of the screen. Your goal is to rotate and move these blocks to form complete horizontal lines at the bottom of the screen. When a line is complete, it disappears, and you score points. The game ends when the blocks stack up and reach the top of the screen.

    Why Pygame?

    Pygame is a set of Python modules designed for writing video games. It provides functionalities for graphics, sound, input (keyboard, mouse, joystick), and more. It’s relatively easy to learn for beginners and is excellent for creating 2D games, making it perfect for our Tetris project!

    Getting Started: Prerequisites

    Before we dive into coding, you’ll need two things:

    • Python: Make sure you have Python installed on your computer. You can download it from the official Python website (python.org). We recommend Python 3.x.
    • Pygame: Once Python is installed, you can install Pygame using pip, Python’s package installer.

    Open your terminal or command prompt and type:

    pip install pygame
    

    This command downloads and installs the Pygame library, making it available for your Python projects.

    Core Concepts of Our Tetris Game

    To build Tetris, we’ll need to understand a few fundamental concepts:

    1. The Game Window: This is where our game will be displayed.
    2. Colors: We’ll define various colors for our blocks and background.
    3. The Game Grid: Tetris is played on a grid, so we need a way to represent this in our code.
    4. Tetrominoes (Shapes): The seven different block shapes.
    5. Game Loop: The heart of any game, continuously updating and drawing everything.
    6. User Input: Handling keyboard presses to move and rotate blocks.
    7. Collision Detection: Checking if a block hits the bottom, another block, or the side walls.
    8. Line Clearing: Detecting and removing complete lines.

    For this simple guide, we’ll focus on setting up the window, defining colors, creating the grid, representing shapes, and implementing basic drawing and movement within the game loop. Implementing full collision detection and line clearing can get quite complex for a beginner guide, but we’ll outline the logic.

    Step 1: Setting up the Pygame Window and Basic Constants

    Let’s start by importing Pygame, initializing it, and setting up our game window. We’ll also define some basic constants like screen dimensions and colors.

    import pygame
    import random
    
    SCREEN_WIDTH = 300
    SCREEN_HEIGHT = 600
    BLOCK_SIZE = 30 # Each Tetris block will be 30x30 pixels
    
    GRID_WIDTH = SCREEN_WIDTH // BLOCK_SIZE  # 10 blocks wide
    GRID_HEIGHT = SCREEN_HEIGHT // BLOCK_SIZE # 20 blocks high
    
    WHITE = (255, 255, 255)
    BLACK = (0, 0, 0)
    GRAY = (50, 50, 50)
    LIGHT_GRAY = (100, 100, 100)
    
    CYAN = (0, 255, 255)    # I-shape
    BLUE = (0, 0, 255)      # J-shape
    ORANGE = (255, 165, 0)  # L-shape
    YELLOW = (255, 255, 0)  # O-shape
    GREEN = (0, 255, 0)     # S-shape
    PURPLE = (128, 0, 128)  # T-shape
    RED = (255, 0, 0)       # Z-shape
    
    TETROMINO_COLORS = [CYAN, BLUE, ORANGE, YELLOW, GREEN, PURPLE, RED]
    
    pygame.init() # This function initializes all the Pygame modules needed for our game.
    SCREEN = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) # Creates the game window.
    pygame.display.set_caption("Simple Tetris") # Sets the title of the game window.
    CLOCK = pygame.time.Clock() # This helps us control the game's frame rate.
    
    • import pygame: Imports the Pygame library.
    • import random: We’ll use this later to pick random Tetromino shapes.
    • SCREEN_WIDTH, SCREEN_HEIGHT: Define how wide and tall our game window will be in pixels.
    • BLOCK_SIZE: Sets the size of each individual block, making our game grid.
    • GRID_WIDTH, GRID_HEIGHT: Calculate how many blocks can fit across and down the screen.
    • Color Definitions: Standard RGB (Red, Green, Blue) tuples for easy color access.
    • pygame.init(): Always call this at the beginning of your Pygame program.
    • pygame.display.set_mode(...): Creates the actual window where your game will appear.
    • pygame.display.set_caption(...): Puts text on the window’s title bar.
    • pygame.time.Clock(): Used to manage the game’s frame rate, ensuring it runs smoothly on all computers.

    Step 2: Defining Tetromino Shapes

    Each Tetromino is made up of four blocks. We can represent their shapes as lists of coordinates, where each coordinate is an offset from a central point. For simplicity, we’ll define their initial rotations as well.

    TETROMINOES = {
        'I': [[(0, 1), (1, 1), (2, 1), (3, 1)], # Horizontal
              [(1, 0), (1, 1), (1, 2), (1, 3)]], # Vertical
        'J': [[(0, 0), (0, 1), (1, 1), (2, 1)],
              [(1, 0), (2, 0), (1, 1), (1, 2)],
              [(0, 1), (1, 1), (2, 1), (2, 2)],
              [(1, 0), (1, 1), (0, 2), (1, 2)]],
        'L': [[(2, 0), (0, 1), (1, 1), (2, 1)],
              [(1, 0), (1, 1), (1, 2), (2, 2)],
              [(0, 1), (1, 1), (2, 1), (0, 2)],
              [(0, 0), (1, 0), (1, 1), (1, 2)]],
        'O': [[(0, 0), (1, 0), (0, 1), (1, 1)]], # Only one rotation
        'S': [[(1, 0), (2, 0), (0, 1), (1, 1)],
              [(0, 0), (0, 1), (1, 1), (1, 2)]],
        'T': [[(1, 0), (0, 1), (1, 1), (2, 1)],
              [(1, 0), (0, 1), (1, 1), (1, 2)],
              [(0, 1), (1, 1), (2, 1), (1, 2)],
              [(1, 0), (1, 1), (2, 1), (1, 2)]],
        'Z': [[(0, 0), (1, 0), (1, 1), (2, 1)],
              [(1, 0), (0, 1), (1, 1), (0, 2)]]
    }
    
    TETROMINO_KEYS = list(TETROMINOES.keys()) # List of shape names for random selection
    
    • TETROMINOES: A dictionary where keys are the names of the shapes (like ‘I’, ‘J’, ‘L’) and values are lists of their possible rotations. Each rotation is itself a list of (x, y) tuples representing the relative positions of the blocks that make up the Tetromino.

    Step 3: Drawing Functions

    We need a way to draw individual blocks and the entire game grid.

    def draw_block(surface, color, x, y):
        """Draws a single block on the given surface at (x, y) grid coordinates."""
        # Convert grid coordinates to pixel coordinates
        pixel_x = x * BLOCK_SIZE
        pixel_y = y * BLOCK_SIZE
        pygame.draw.rect(surface, color, (pixel_x, pixel_y, BLOCK_SIZE, BLOCK_SIZE), 0) # Fills the rectangle
        pygame.draw.rect(surface, LIGHT_GRAY, (pixel_x, pixel_y, BLOCK_SIZE, BLOCK_SIZE), 1) # Draws a border
    
    • draw_block(surface, color, x, y): This function takes a surface (our SCREEN), a color, and grid x, y coordinates. It converts these grid coordinates into pixel coordinates and then uses pygame.draw.rect to draw a filled rectangle (our block) and a lighter border around it.

    Step 4: The Game Loop (Main Logic)

    The game loop is where all the action happens. It continuously:
    1. Handles Events: Checks for user input (keyboard, mouse).
    2. Updates Game State: Moves blocks, checks for collisions, clears lines, etc.
    3. Draws Everything: Renders the current state of the game to the screen.

    def main():
        game_over = False
        current_piece = None
        current_x = 0
        current_y = 0
        current_rotation = 0
        current_color = None
    
        # Represents the fallen blocks on the grid
        # A 2D list where each element stores the color of the block at that position, or None if empty.
        game_grid = [[None for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]
    
        # --- Game Loop ---
        running = True
        while running:
            # 1. Event Handling
            for event in pygame.event.get():
                if event.type == pygame.QUIT: # User clicked the 'X' to close the window
                    running = False
                elif event.type == pygame.KEYDOWN: # A key was pressed down
                    if event.key == pygame.K_LEFT:
                        # Move piece left (need to add collision check later)
                        current_x -= 1
                    elif event.key == pygame.K_RIGHT:
                        # Move piece right (need to add collision check later)
                        current_x += 1
                    elif event.key == pygame.K_DOWN:
                        # Speed up piece fall (need to add collision check later)
                        current_y += 1
                    elif event.key == pygame.K_UP:
                        # Rotate piece (need to add collision check later)
                        current_rotation = (current_rotation + 1) % len(TETROMINOES[current_piece[0]])
    
            # 2. Update Game State (Simplified for now)
            # If no current piece, create a new one
            if current_piece is None:
                piece_type = random.choice(TETROMINO_KEYS)
                current_piece = TETROMINOES[piece_type]
                current_color = TETROMINO_COLORS[TETROMINO_KEYS.index(piece_type)]
                current_x = GRID_WIDTH // 2 - 2 # Start roughly in the middle
                current_y = 0
                current_rotation = 0
    
            # Simulate gravity (piece falls slowly)
            # In a real game, this would be based on a timer
            # For this simple example, we'll just move it down every few frames or on a timer event.
            # For now, let's make it fall one block down every 60 frames (1 second at 60 FPS)
            if pygame.time.get_ticks() % 60 == 0: # This is a very basic way to simulate fall. Better to use a timer.
                 current_y += 1
    
            # --- Basic Collision Check (Highly simplified) ---
            # For a full game, you'd check if the piece hits the bottom or other blocks.
            # If current_y goes beyond GRID_HEIGHT, or if piece collides, it 'lands'.
            # For simplicity, if it goes too low, reset it and add to grid.
            if current_y + len(current_piece[current_rotation]) > GRID_HEIGHT:
                # Piece landed, 'lock' it into the game_grid
                for dx, dy in current_piece[current_rotation]:
                    if 0 <= current_x + dx < GRID_WIDTH and 0 <= current_y + dy -1 < GRID_HEIGHT:
                        game_grid[current_y + dy -1][current_x + dx] = current_color # Place block one step up
                current_piece = None # Get a new piece
                current_y = 0
                current_x = GRID_WIDTH // 2 - 2
    
            # 3. Drawing
            SCREEN.fill(BLACK) # Fill the background with black
    
            # Draw the grid lines
            for x in range(0, SCREEN_WIDTH, BLOCK_SIZE):
                pygame.draw.line(SCREEN, GRAY, (x, 0), (x, SCREEN_HEIGHT))
            for y in range(0, SCREEN_HEIGHT, BLOCK_SIZE):
                pygame.draw.line(SCREEN, GRAY, (0, y), (SCREEN_WIDTH, y))
    
            # Draw landed blocks
            for y_grid in range(GRID_HEIGHT):
                for x_grid in range(GRID_WIDTH):
                    if game_grid[y_grid][x_grid] is not None:
                        draw_block(SCREEN, game_grid[y_grid][x_grid], x_grid, y_grid)
    
            # Draw the current falling piece
            if current_piece:
                for dx, dy in current_piece[current_rotation]:
                    draw_block(SCREEN, current_color, current_x + dx, current_y + dy)
    
            # 4. Update the display
            pygame.display.flip() # Makes everything drawn visible on the screen.
            CLOCK.tick(60) # Limits the game to 60 frames per second.
    
        pygame.quit() # Uninitializes Pygame when the loop ends.
    
    if __name__ == "__main__":
        main()
    
    • main() function: Encapsulates our game logic.
    • game_over: A flag to track if the game has ended.
    • current_piece: Stores the current falling Tetromino’s shape data.
    • current_x, current_y: The current position (top-left block) of the falling Tetromino on the grid.
    • current_rotation: Which rotation of the current Tetromino is active.
    • game_grid: A 2D list representing our playing field. Each cell will either be None (empty) or hold the color of a landed block.
    • while running:: This is our game loop. It continues as long as running is True.
    • pygame.event.get(): Gathers all recent user inputs and system events.
    • pygame.QUIT: Triggered when the user clicks the close button on the window.
    • pygame.KEYDOWN: Triggered when a key is pressed. We check event.key to see which key it was (e.g., pygame.K_LEFT for the left arrow key).
    • SCREEN.fill(BLACK): Clears the screen each frame by filling it with black. Without this, previous drawings would remain.
    • Drawing Grid Lines: We draw light gray lines to show the grid.
    • Drawing Landed Blocks: We iterate through game_grid and draw any blocks that have landed.
    • Drawing Current Piece: We draw the currently falling Tetromino using its current_x, current_y, and current_rotation.
    • pygame.display.flip(): Updates the entire screen to show what we’ve just drawn.
    • CLOCK.tick(60): Tells Pygame to pause briefly if the game is running too fast, aiming for 60 frames per second. This ensures consistent game speed.
    • pygame.quit(): Cleans up Pygame resources when the game loop finishes.

    Expanding Your Game (Next Steps)

    This is a very basic foundation. To make it a full Tetris game, you would need to add:

    • Robust Collision Detection: Check if the current piece can legally move or rotate without overlapping with other landed blocks or going out of bounds.
    • Landing Logic: When a piece can no longer fall, “lock” it into the game_grid (which our simplified code does, but needs more robust checking).
    • Line Clearing: After a piece lands, check if any horizontal lines are fully filled. If so, remove them and shift all blocks above down.
    • Scoring System: Keep track of the player’s score.
    • Game Over Condition: If a new piece spawns and immediately collides with existing blocks, the game is over.
    • Next Piece Display: Show the player what the next falling Tetromino will be.
    • Hold Piece: Allow players to “hold” a piece for later use.

    Conclusion

    You’ve just set up the basic framework for a Tetris game using Pygame! While our example is simplified, you now understand the core concepts: setting up the window, defining shapes, handling user input, and the continuous game loop. This is an excellent starting point for diving deeper into game development. Don’t hesitate to experiment with the code, add new features, and make it your own! Happy coding!

  • Let’s Build a Simple Maze Game with Pygame!

    Hello aspiring game developers and Python enthusiasts! Have you ever wanted to create your own game, even a simple one? Today, we’re going to dive into the exciting world of Pygame and build a fun, basic maze game. Don’t worry if you’re new to game development or even Python; we’ll break down every step into easy-to-understand chunks.

    What is Pygame?

    Before we start, let’s quickly explain what Pygame is.
    Pygame is a popular set of Python modules designed for writing video games. Think of it as a toolkit that provides functions and classes to handle graphics, sounds, user input (like keyboard presses or mouse clicks), and other common game development tasks. It makes it much easier to create games without having to worry about the really low-level details.
    A module or library is simply a collection of pre-written code that you can use in your own Python programs to perform specific actions, saving you time and effort.

    What Will We Build?

    Our goal is to create a simple maze game where:
    * You control a player character (a colored square).
    * You navigate through a static maze.
    * The player cannot pass through walls.
    * The game ends when you reach a specific “exit” point.

    This project is fantastic for beginners because it covers fundamental game development concepts like drawing shapes, handling user input, creating a game loop, and basic collision detection.

    Getting Started: Prerequisites

    Before we write any code, you’ll need two things:

    1. Python: Make sure you have Python installed on your computer. You can download it from the official Python website (python.org). Python 3.6 or newer is recommended.
    2. Pygame: Once Python is installed, you can install Pygame using pip, Python’s package installer. Open your terminal or command prompt and type:

      bash
      pip install pygame

      If you’re using a specific Python version, you might use pip3 install pygame.

    That’s it for the setup! Now, let’s get into the code.

    The Foundation: Setting Up Our Pygame Window

    Every Pygame application starts by initializing Pygame and setting up a display window.

    Step 1: Import Pygame and Initialize

    First, we import the Pygame library and initialize all its modules.

    import pygame
    
    pygame.init()
    

    Step 2: Define Game Constants

    It’s a good practice to define constants for things like screen dimensions, colors, and player speed. This makes your code cleaner and easier to modify.

    Constants are values that don’t change throughout the program’s execution. We often write them in UPPER_CASE to distinguish them from regular variables.

    SCREEN_WIDTH = 800
    SCREEN_HEIGHT = 600
    
    CELL_SIZE = 40
    
    WHITE = (255, 255, 255)
    BLACK = (0, 0, 0)
    RED = (255, 0, 0)
    GREEN = (0, 255, 0)
    BLUE = (0, 0, 255)
    YELLOW = (255, 255, 0) # For our player!
    
    PLAYER_SIZE = CELL_SIZE - 10 # Slightly smaller than a cell
    PLAYER_SPEED = CELL_SIZE # Player moves one cell at a time
    
    WALL_THICKNESS = 5
    

    Step 3: Create the Game Window

    Now, we create the actual window where our game will be displayed.

    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    
    pygame.display.set_caption("Simple Maze Game")
    

    Designing Our Maze

    How do we represent a maze in code? A common and easy way for simple grid-based games is to use a 2D list (or “list of lists”) where each element represents a cell in the maze. We can use numbers to signify different types of cells:
    * 0: Path (empty space)
    * 1: Wall
    * 2: Player start position
    * 3: Exit point

    Let’s define a simple maze layout. Remember, each 1 (wall) will be CELL_SIZE by CELL_SIZE pixels.

    maze_layout = [
        [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
        [1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
        [1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1],
        [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1],
        [1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1],
        [1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1],
        [1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1],
        [1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
        [1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1],
        [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1],
        [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    ]
    
    MAZE_WIDTH_CELLS = len(maze_layout[0])
    MAZE_HEIGHT_CELLS = len(maze_layout)
    
    SCREEN_WIDTH = MAZE_WIDTH_CELLS * CELL_SIZE
    SCREEN_HEIGHT = MAZE_HEIGHT_CELLS * CELL_SIZE
    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) # Re-set screen after recalculating
    

    The Game Loop: The Heart of Every Game

    Every game has a game loop. This is a while loop that runs continuously, doing three main things:
    1. Event Handling: Checking for user input (like keyboard presses) or system events (like closing the window).
    2. Updating Game State: Changing positions of objects, checking for collisions, etc.
    3. Drawing: Redrawing everything on the screen in its new position.

    player_grid_x = 0
    player_grid_y = 0
    
    for y in range(MAZE_HEIGHT_CELLS):
        for x in range(MAZE_WIDTH_CELLS):
            if maze_layout[y][x] == 2:
                player_grid_x = x
                player_grid_y = y
                break # Found player, no need to search more in this row
        if maze_layout[player_grid_y][player_grid_x] == 2: # If player found, break outer loop too
            break
    
    player_pixel_x = player_grid_x * CELL_SIZE + (CELL_SIZE - PLAYER_SIZE) // 2
    player_pixel_y = player_grid_y * CELL_SIZE + (CELL_SIZE - PLAYER_SIZE) // 2
    
    game_over = False
    running = True # This variable controls our game loop
    
    while running:
        # 1. Event Handling
        for event in pygame.event.get():
            if event.type == pygame.QUIT: # If the user clicks the 'X' to close the window
                running = False # Stop the game loop
    
            if event.type == pygame.KEYDOWN and not game_over: # If a key is pressed and game is not over
                # Try to move the player based on arrow keys
                new_player_grid_x = player_grid_x
                new_player_grid_y = player_grid_y
    
                if event.key == pygame.K_LEFT:
                    new_player_grid_x -= 1
                elif event.key == pygame.K_RIGHT:
                    new_player_grid_x += 1
                elif event.key == pygame.K_UP:
                    new_player_grid_y -= 1
                elif event.key == pygame.K_DOWN:
                    new_player_grid_y += 1
    
                # Check for collision with walls
                # "Collision detection" is the process of figuring out if two objects in a game are overlapping or touching.
                if 0 <= new_player_grid_x < MAZE_WIDTH_CELLS and \
                   0 <= new_player_grid_y < MAZE_HEIGHT_CELLS and \
                   maze_layout[new_player_grid_y][new_player_grid_x] != 1: # 1 is a wall
    
                    player_grid_x = new_player_grid_x
                    player_grid_y = new_player_grid_y
    
                    # Update player's pixel position
                    player_pixel_x = player_grid_x * CELL_SIZE + (CELL_SIZE - PLAYER_SIZE) // 2
                    player_pixel_y = player_grid_y * CELL_SIZE + (CELL_SIZE - PLAYER_SIZE) // 2
    
                    # Check if player reached the exit
                    if maze_layout[player_grid_y][player_grid_x] == 3:
                        game_over = True
                        print("You won!")
    
        # 2. Drawing
        # Clear the screen by filling it with a background color
        screen.fill(BLACK)
    
        # Draw the maze
        for y in range(MAZE_HEIGHT_CELLS):
            for x in range(MAZE_WIDTH_CELLS):
                cell_type = maze_layout[y][x]
                rect = pygame.Rect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE) # A `Rect` object represents a rectangular area.
    
                if cell_type == 1: # Wall
                    pygame.draw.rect(screen, BLUE, rect)
                elif cell_type == 3: # Exit
                    pygame.draw.rect(screen, GREEN, rect)
    
        # Draw the player
        player_rect = pygame.Rect(player_pixel_x, player_pixel_y, PLAYER_SIZE, PLAYER_SIZE)
        pygame.draw.rect(screen, YELLOW, player_rect)
    
        # If game is over, display a message
        if game_over:
            font = pygame.font.Font(None, 74) # `pygame.font.Font` creates a font object; `None` uses default font.
            text = font.render("YOU WIN!", True, GREEN) # `render` creates a surface with the text. `True` is for anti-aliasing.
            text_rect = text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2))
            screen.blit(text, text_rect) # `blit` draws one image onto another.
    
        # Update the full display Surface to the screen
        # This makes everything we've drawn actually appear on the window.
        pygame.display.flip()
    
    pygame.quit()
    

    How the Code Works (Detailed Explanations)

    Let’s break down some key parts of the code:

    • pygame.init(): This function initializes all the Pygame modules necessary for game development. Without it, many Pygame functions won’t work.
    • pygame.display.set_mode((width, height)): This creates the actual window where your game will run. The (width, height) tuple specifies the size in pixels. A pixel is the smallest unit of a digital image or display.
    • pygame.display.set_caption("Title"): This sets the text that appears in the title bar of your game window.
    • while running:: This is our main game loop. The running variable (a boolean – true/false value) controls whether the loop continues or stops. When running becomes False, the loop finishes.
    • for event in pygame.event.get():: Pygame collects all user actions (like key presses, mouse clicks, closing the window) as “events.” This loop goes through each event that happened since the last frame.
    • event.type == pygame.QUIT: This checks if the specific event was the user clicking the ‘X’ button to close the window.
    • event.type == pygame.KEYDOWN: This checks if a key was pressed down.
    • event.key == pygame.K_LEFT: This checks which key was pressed (e.g., the left arrow key). Pygame provides constants for many keys (e.g., K_RIGHT, K_UP, K_DOWN).
    • maze_layout[new_player_grid_y][new_player_grid_x] != 1: This is our simple collision detection. Before moving the player, we check the maze_layout at the target cell. If it’s 1 (a wall), we don’t allow the move.
    • screen.fill(BLACK): Before drawing anything new in each frame, we “clear” the screen by filling it with a background color (black in our case). This prevents “ghosting” effects where old drawings remain.
    • pygame.Rect(x, y, width, height): Pygame uses Rect objects to represent rectangular areas. These are very useful for drawing and for collision detection. x and y are the coordinates (position on the screen).
    • pygame.draw.rect(surface, color, rect_object): This function draws a rectangle on a given surface (our screen), with a specified color, and at the position and size defined by the rect_object.
    • pygame.display.flip(): This command updates the entire screen to show everything that has been drawn since the last flip() or update(). Without this, you wouldn’t see anything!
    • pygame.quit(): This uninitializes all Pygame modules and cleans up resources, which is good practice when your program finishes.

    Running Your Game!

    Save the code above as a Python file (e.g., maze_game.py). Then, open your terminal or command prompt, navigate to the directory where you saved the file, and run it using:

    python maze_game.py
    

    You should see a window pop up with your maze! Use the arrow keys to move your yellow square player through the maze. Try to reach the green exit square.

    Ideas for Improvement

    This is a very basic maze game, but it’s a great starting point! Here are some ideas to make it even better:

    • More Complex Mazes: Implement an algorithm to generate random mazes.
    • Timer/Score: Add a timer to see how fast the player can complete the maze, or a score.
    • Sound Effects: Add sounds for movement, reaching the exit, or hitting a wall.
    • Different Player Graphics: Instead of a square, use an image for the player.
    • Multiple Levels: Create an array of maze_layouts and switch between them.
    • Smoother Movement: Instead of moving one CELL_SIZE at a time, move a few pixels per frame for smoother animation. (This requires more complex collision detection).
    • Start Screen/End Screen: Add proper title screens and game over screens.

    Conclusion

    Congratulations! You’ve just built your very own simple maze game using Pygame. You’ve learned about setting up a game window, handling user input, drawing shapes, and the essential game loop. These are fundamental skills that will serve you well in any future game development adventures. Keep experimenting, keep coding, and most importantly, have fun!


  • Level Up Your Web Skills: Creating a Simple “Guess the Number” Game with Django

    Welcome, aspiring web developers and coding enthusiasts! Have you ever wanted to build something interactive on the web, perhaps a simple game, but felt overwhelmed by complex frameworks? Well, you’re in luck! Today, we’re going to dive into the exciting world of Django and create a fun, classic “Guess the Number” game.

    Django is a powerful and popular web framework for Python.
    Web Framework: Think of a web framework as a toolkit that provides all the essential tools and structures you need to build a website or web application quickly and efficiently, without starting entirely from scratch.
    Django helps you build robust web applications with less code, making it perfect for both beginners and experienced developers. While it’s often used for complex sites, its simplicity and clear structure make it surprisingly great for fun, experimental projects like a game!

    By the end of this guide, you’ll have a basic understanding of how Django works and a working “Guess the Number” game you can play right in your browser. Let’s get started!

    What We’ll Build: “Guess the Number”

    Our game will be straightforward:
    * The computer will randomly pick a secret number between 1 and 100.
    * You, the player, will guess a number.
    * The game will tell you if your guess is “too high,” “too low,” or “correct.”
    * It will also keep track of how many guesses you’ve made.

    This game will introduce you to key Django concepts like views, URLs, and templates, along with a touch of Python logic.

    Prerequisites: Getting Ready

    Before we jump into Django, make sure you have these essentials in place:

    • Python: You should have Python installed on your computer (version 3.6 or higher is recommended). If not, head over to python.org to download and install it.
    • Basic Python Knowledge: Familiarity with Python basics like variables, functions, and conditional statements (if/else) will be very helpful.
    • pip: This is Python’s package installer, usually included with Python installations. We’ll use it to install Django.

    Step 1: Setting Up Your Django Project

    It’s good practice to set up a virtual environment for each Django project.

    • Virtual Environment: Imagine a separate, isolated space on your computer where your project’s Python packages live. This prevents conflicts between different projects that might need different versions of the same package.

    Let’s open your terminal or command prompt and get started:

    1. Create a Project Folder:
      First, create a folder for your game project and navigate into it.

      bash
      mkdir django_game
      cd django_game

    2. Create and Activate a Virtual Environment:
      bash
      python -m venv venv

      • On Windows:
        bash
        venv\Scripts\activate
      • On macOS/Linux:
        bash
        source venv/bin/activate

        You’ll see (venv) appearing at the beginning of your terminal prompt, indicating that your virtual environment is active.
    3. Install Django:
      Now that your virtual environment is active, install Django using pip.

      bash
      pip install django

    4. Start a New Django Project:
      A Django project is a collection of settings and applications that together make a website.

      bash
      django-admin startproject guess_the_number_project .

      guess_the_number_project: This is the name of your project.
      .: This tells Django to create the project files in the current directory (your django_game folder), rather than creating another nested folder.

    5. Create a Django App:
      Within your project, you typically create one or more “apps.” An app is a self-contained module that does one specific thing, like handling users, blogs, or, in our case, the game itself. This keeps your code organized.

      bash
      python manage.py startapp game

      This creates a new folder named game with several files inside.

    6. Register Your App:
      Django needs to know about the new app you’ve created. Open the guess_the_number_project/settings.py file and add 'game' to the INSTALLED_APPS list.

      “`python

      guess_the_number_project/settings.py

      INSTALLED_APPS = [
      ‘django.contrib.admin’,
      ‘django.contrib.auth’,
      ‘django.contrib.contenttypes’,
      ‘django.contrib.sessions’,
      ‘django.contrib.messages’,
      ‘django.contrib.staticfiles’,
      ‘game’, # Add your new app here
      ]
      “`

    7. Run Migrations (Optional but Good Practice):
      Django uses migrations to set up and update your database schema (the structure of your database). Even though our simple game won’t use a database for its core logic, it’s good practice to run migrations after creating a project.

      bash
      python manage.py migrate

    Step 2: Defining URLs

    URLs are how users access different parts of your website. We need to tell Django which URL patterns should trigger which parts of our game logic.

    1. Project-Level urls.py:
      First, open guess_the_number_project/urls.py and tell Django to look for URLs defined within our game app.

      “`python

      guess_the_number_project/urls.py

      from django.contrib import admin
      from django.urls import path, include # Import include

      urlpatterns = [
      path(‘admin/’, admin.site.urls),
      path(‘game/’, include(‘game.urls’)), # Include game app URLs
      ]
      ``
      Here,
      path(‘game/’, include(‘game.urls’))means that any URL starting with/game/will be handed over to thegameapp'surls.py` file.

    2. App-Level urls.py:
      Now, inside your game app folder, create a new file named urls.py. This file will define the specific URL patterns for our game.

      “`python

      game/urls.py

      from django.urls import path
      from . import views

      urlpatterns = [
      path(”, views.start_game, name=’start_game’),
      path(‘play/’, views.play_game, name=’play_game’),
      ]
      ``
      -
      path(”, views.start_game, name=’start_game’): When someone visits/game/(because of theinclude(‘game.urls’)above), this will call thestart_gamefunction ingame/views.py.
      -
      path(‘play/’, views.play_game, name=’play_game’): When someone visits/game/play/, this will call theplay_gamefunction ingame/views.py`.

    Step 3: Crafting the Game Logic (Views)

    Django “views” are Python functions that receive a web request, process it, and return a web response (like an HTML page). Our game logic will live here.

    Open game/views.py and replace its content with the following:

    from django.shortcuts import render, redirect
    import random
    
    
    def start_game(request):
        """
        Initializes a new game: generates a secret number and resets guess count.
        """
        request.session['secret_number'] = random.randint(1, 100)
        request.session['guesses'] = 0
        request.session['feedback'] = "I'm thinking of a number between 1 and 100. Can you guess it?"
        return redirect('play_game') # Redirect to the play page
    
    def play_game(request):
        """
        Handles user guesses and provides feedback.
        """
        secret_number = request.session.get('secret_number')
        guesses = request.session.get('guesses')
        feedback = request.session.get('feedback')
    
        if secret_number is None or guesses is None:
            # If session data is missing, start a new game
            return redirect('start_game')
    
        message = feedback
        guess_made = False
    
        if request.method == 'POST':
            # --- Supplementary Explanation: HTTP POST Request ---
            # HTTP POST Request: Used when a web browser sends data to the server,
            # typically from a form submission. It's used here to send the user's guess.
            try:
                user_guess = int(request.POST.get('guess'))
                guesses += 1
                request.session['guesses'] = guesses
                guess_made = True
    
                if user_guess < secret_number:
                    message = "Too low! Try again."
                elif user_guess > secret_number:
                    message = "Too high! Try again."
                else:
                    message = f"Congratulations! You guessed the number {secret_number} in {guesses} guesses!"
                    # Game over, clear session data or offer to restart
                    request.session['secret_number'] = None # Clear secret number
                    request.session['guesses'] = None # Clear guesses
                    request.session['feedback'] = message + " Click 'Restart Game' to play again."
    
            except (ValueError, TypeError):
                message = "Invalid input. Please enter a whole number."
    
            request.session['feedback'] = message # Update feedback for next rendering
    
            # After POST, redirect to the same page to prevent re-submission on refresh
            # This is a common pattern called Post/Redirect/Get (PRG)
            return redirect('play_game')
    
        # For GET requests or after POST-redirect, render the game page
        context = {
            'message': message,
            'guesses': guesses,
            'game_over': request.session.get('secret_number') is None # True if game is over
        }
        return render(request, 'game/game.html', context)
    
    • start_game: This function is called when a new game begins. It generates a random secret number and initializes the guess count, storing them in the user’s session. It then redirects to the play_game view.
    • play_game: This is the main game logic.
      • It retrieves the secret number, guess count, and feedback message from the session.
      • If the request is a POST (meaning the user submitted a guess), it processes the guess: checks if it’s too high, too low, or correct, updates the guess count, and stores new feedback.
      • It uses request.session to store temporary data specific to the current user’s interaction with the website, which is perfect for our game state.
      • Finally, it prepares data (context) and renders the game/game.html template.

    Step 4: Designing the User Interface (Templates)

    Django “templates” are HTML files with special Django syntax that allow you to display dynamic content from your Python views.

    1. Create Template Folders:
      Inside your game app folder, create a new folder named templates, and inside that, another folder named game. This structure (app_name/templates/app_name/your_template.html) helps Django find your templates and keeps them organized.

      django_game/
      ├── guess_the_number_project/
      ├── game/
      │ ├── templates/
      │ │ └── game/
      │ │ └── game.html <-- This is where our game's HTML will go
      │ ├── __init__.py
      │ ├── admin.py
      │ ├── apps.py
      │ ├── models.py
      │ ├── tests.py
      │ ├── urls.py
      │ └── views.py
      ├── manage.py
      └── venv/

    2. Create game.html:
      Now, create a file named game.html inside game/templates/game/ and add the following HTML:

      “`html

      <!DOCTYPE html>




      Guess the Number!


      Guess the Number!

          <p class="message">{{ message }}</p>
      
          {% if game_over %}
              <p>What a game! You can restart below.</p>
              <form action="{% url 'start_game' %}" method="post">
                  {% csrf_token %} {# Required for all Django forms #}
                  <button type="submit">Restart Game</button>
              </form>
          {% else %}
              <form action="{% url 'play_game' %}" method="post">
                  {% csrf_token %} {# Required for all Django forms #}
                  <input type="number" name="guess" min="1" max="100" placeholder="Enter your guess" required autofocus>
                  <button type="submit">Guess</button>
              </form>
              <p class="guesses">Guesses: {{ guesses }}</p>
          {% endif %}
      
      </div>
      



      ``
      * **
      {{ message }}and{{ guesses }}:** These are Django template tags that display themessageandguessesvariables passed from ourplay_gameview function via thecontextdictionary.
      * **
      {% if game_over %}and{% else %}:** These are Django template tags for conditional logic, allowing us to display different content based on whether the game is over or not.
      * **

      :** This creates an HTML form.
      *
      action=”{% url ‘play_game’ %}”: The{% url %}template tag dynamically generates the URL for theplay_gameview, ensuring it's always correct.
      *
      method=”post”: This means the form data will be sent using an HTTP POST request.
      * **
      {% csrf_token %}:** This is a crucial security feature in Django.
      * **CSRF (Cross-Site Request Forgery):** A type of malicious exploit where an attacker tricks a logged-in user into unknowingly submitting a request to a web application. The
      csrf_token` protects your forms from this by ensuring that the request originated from your own website. Always include it in your forms!

    Step 5: Running Your Game

    You’ve done all the hard work! Now it’s time to see your game in action.

    1. Start the Development Server:
      Make sure your virtual environment is active and you are in the django_game directory (the one containing manage.py).

      bash
      python manage.py runserver

      You should see output similar to this:

      “`
      Watching for file changes with StatReloader
      Performing system checks…

      System check identified no issues (0 silenced).

      You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
      Run ‘python manage.py migrate’ to apply them.
      August 09, 2023 – 14:30:00
      Django version 4.2.4, using settings ‘guess_the_number_project.settings’
      Starting development server at http://127.0.0.1:8000/
      Quit the server with CONTROL-C.
      “`

    2. Open in Browser:
      Open your web browser and navigate to http://127.0.0.1:8000/game/.

      You should see your “Guess the Number!” game. Try guessing numbers, and the game will tell you if you’re too high or too low. Once you guess correctly, you’ll see a congratulatory message and a “Restart Game” button.

    What’s Next? Ideas for Improvement

    This simple game is just the beginning! Here are some ideas to expand your project and learn more about Django:

    • Add a High Score List: This would involve creating a Django Model (a Python class that represents a table in your database) to store player names and their number of guesses. You’d then learn how to save and retrieve data from a database.
    • Multiple Difficulty Levels: Allow players to choose a range (e.g., 1-10, 1-1000).
    • User Accounts: Use Django’s built-in authentication system to allow users to create accounts, log in, and track their personal best scores.
    • CSS Styling: Improve the look and feel with more advanced CSS or a CSS framework like Bootstrap.
    • Make it a “Hangman” or “Tic-Tac-Toe” Game: Challenge yourself to implement more complex game logic within the Django framework.

    Conclusion

    Congratulations! You’ve successfully built a basic web-based game using Django. You’ve touched upon setting up a project, defining URLs, writing view logic, and creating HTML templates. Django provides a robust and elegant way to build web applications, and even simple games can be a fantastic way to learn its core concepts. Keep experimenting, keep building, and have fun on your coding journey!


  • Creating a Simple Minesweeper Game with Python

    Introduction: Digging into Fun!

    Welcome, aspiring Pythonistas and game enthusiasts! Today, we’re going to embark on a fun project: building a simplified version of the classic game Minesweeper using Python. Even if you’re new to programming, don’t worry! We’ll break down each step using simple language and clear explanations.

    What is Minesweeper?

    Minesweeper is a single-player puzzle game. The goal is to clear a rectangular board containing hidden “mines” without detonating any of them. If you click on a cell with a mine, you lose! If you click on a safe cell, it reveals a number. This number tells you how many mines are in the eight surrounding cells (including diagonals). These numbers are your clues to figure out where the mines are located.

    Why Build it in Python?

    Python is a fantastic language for beginners because it’s easy to read and write. Creating a game like Minesweeper is an excellent way to practice several core programming concepts:

    • Variables and Data Structures: Storing information like our game board.
    • Loops: Repeating actions, like checking all cells or running the game.
    • Conditional Statements: Making decisions, like “Is this a mine?”
    • Functions: Organizing our code into reusable blocks.
    • User Input: Interacting with the player.

    By the end of this tutorial, you’ll have a working text-based Minesweeper game and a better understanding of how these concepts come together. Let’s get started!

    The Building Blocks of Our Game

    Before we write any code, let’s think about the main parts we need for our game:

    • The Grid (Game Board): This is where all the action happens. We need a way to represent a grid of cells.
    • Mines: These are the hidden dangers. We’ll need to place them randomly on our grid.
    • Numbers (Clues): For every cell that doesn’t have a mine, we need to calculate and store a number indicating how many mines are nearby.
    • Player Actions: The player needs to be able to “click” (or choose) a cell on the board.
    • Display: We need to show the player what the board looks like, hiding unrevealed cells and showing numbers or mines for revealed ones.

    Setting Up Your Python Project

    The great news is you don’t need to install anything special for this project! Python comes with everything we need. Just make sure you have Python installed on your computer. You can write your code in any text editor and run it from your terminal or command prompt.

    Step-by-Step Implementation

    We’ll build our game step by step, explaining each piece of code.

    1. Representing the Game Board

    How do we represent a grid in Python? The easiest way for a game board is using a “list of lists,” also known as a 2D list or nested list.
    Imagine a spreadsheet: each row is a list, and all those row lists are put together into one big list.

    We’ll need two main grids:
    * board: This will store the actual content of each cell (either a mine 'M' or a number 0-8).
    * display_board: This is what the player sees. Initially, all cells are hidden (e.g., '-'). When a player reveals a cell, we update display_board with the content from board.

    Let’s start by initializing these boards.

    import random
    
    def initialize_boards(rows, cols):
        """
        Creates two empty boards: one for game logic and one for display.
    
        Args:
            rows (int): The number of rows in the board.
            cols (int): The number of columns in the board.
    
        Returns:
            tuple: A tuple containing (board, display_board).
                   'board' holds '0' for empty cells initially.
                   'display_board' holds '-' for hidden cells.
        """
        board = [['0' for _ in range(cols)] for _ in range(rows)]
        display_board = [['-' for _ in range(cols)] for _ in range(rows)]
        return board, display_board
    

    2. Placing the Mines

    Now, let’s randomly place our mines on the board. We’ll use Python’s built-in random module for this.

    Technical Term: random module
    The random module in Python provides functions to generate random numbers. random.randint(a, b) will give you a random whole number between a and b (inclusive). This is perfect for picking random row and column numbers.

    def place_mines(board, num_mines):
        """
        Randomly places mines ('M') on the game board.
    
        Args:
            board (list of lists): The game board where mines will be placed.
            num_mines (int): The total number of mines to place.
        """
        rows = len(board)
        cols = len(board[0])
        mines_placed = 0
    
        while mines_placed < num_mines:
            r = random.randint(0, rows - 1) # Pick a random row
            c = random.randint(0, cols - 1) # Pick a random column
    
            if board[r][c] != 'M': # If there isn't already a mine here
                board[r][c] = 'M'
                mines_placed += 1
    

    3. Calculating the Clues (Numbers)

    After placing mines, we need to calculate the numbers for all the non-mine cells. For each cell that is not a mine, we look at its eight surrounding neighbors (up, down, left, right, and diagonals) and count how many of them contain a mine.

    Technical Term: Adjacent Cells
    “Adjacent” simply means “next to.” In a grid, a cell typically has 8 adjacent cells: one directly above, below, left, right, and one in each of the four diagonal directions.

    def calculate_numbers(board):
        """
        Calculates the number of adjacent mines for each non-mine cell.
    
        Args:
            board (list of lists): The game board with mines placed.
        """
        rows = len(board)
        cols = len(board[0])
    
        for r in range(rows):
            for c in range(cols):
                if board[r][c] == 'M':
                    continue # Skip if it's a mine
    
                mine_count = 0
                # Check all 8 adjacent cells
                for dr in [-1, 0, 1]: # Delta row: -1 (up), 0 (same row), 1 (down)
                    for dc in [-1, 0, 1]: # Delta col: -1 (left), 0 (same col), 1 (right)
                        if dr == 0 and dc == 0: # Skip the current cell itself
                            continue
    
                        nr, nc = r + dr, c + dc # Neighbor row, neighbor col
    
                        # Check if the neighbor is within the board boundaries
                        if 0 <= nr < rows and 0 <= nc < cols:
                            if board[nr][nc] == 'M':
                                mine_count += 1
                board[r][c] = str(mine_count) # Store the count as a string
    

    4. Displaying the Board to the Player

    This function will print the display_board to the console, making it readable for the player. We’ll also add row and column numbers to help the player choose cells.

    def print_display_board(display_board):
        """
        Prints the current state of the display board to the console.
        """
        rows = len(display_board)
        cols = len(display_board[0])
    
        # Print column numbers
        print("  ", end="")
        for c in range(cols):
            print(f" {c}", end="")
        print()
    
        # Print a separator line
        print("  " + "---" * cols)
    
        # Print row numbers and board content
        for r in range(rows):
            print(f"{r} |", end="")
            for c in range(cols):
                print(f" {display_board[r][c]}", end="")
            print(" |")
        print("  " + "---" * cols)
    

    5. Handling Player Moves

    The game needs to ask the player for their desired move (row and column) and make sure it’s a valid choice.

    def get_player_move(rows, cols):
        """
        Prompts the player to enter their move (row and column).
    
        Args:
            rows (int): Total number of rows on the board.
            cols (int): Total number of columns on the board.
    
        Returns:
            tuple: (row, col) if input is valid, otherwise asks again.
        """
        while True:
            try:
                move_input = input(f"Enter your move (row column, e.g., 0 0): ").split()
                r, c = int(move_input[0]), int(move_input[1])
    
                if 0 <= r < rows and 0 <= c < cols:
                    return r, c
                else:
                    print("Invalid input. Row and column must be within board limits.")
            except (ValueError, IndexError):
                print("Invalid input format. Please enter two numbers separated by a space.")
    

    6. Putting It All Together: The Game Loop

    This is where the magic happens! The play_game function will bring all our previous functions together, managing the game flow, checking win/loss conditions, and letting the player keep playing until the game ends.

    Technical Term: Game Loop
    A “game loop” is a fundamental concept in game programming. It’s a while loop that continuously runs the main actions of the game: getting player input, updating the game state, and displaying the game, until a condition (like game over or win) is met.

    def play_game():
        """
        Main function to run the Minesweeper game.
        """
        print("Welcome to Simple Minesweeper!")
    
        # You can change these values to make the board bigger or smaller
        board_rows = 5
        board_cols = 5
        number_of_mines = 4 
    
        # Initialize the board and display board
        game_board, current_display = initialize_boards(board_rows, board_cols)
        place_mines(game_board, number_of_mines)
        calculate_numbers(game_board)
    
        game_over = False
        mines_hit = False
        safe_cells_revealed = 0
        total_safe_cells = (board_rows * board_cols) - number_of_mines
    
        while not game_over:
            print_display_board(current_display)
    
            # Get player move
            row, col = get_player_move(board_rows, board_cols)
    
            # Check if the cell is already revealed
            if current_display[row][col] != '-':
                print("This cell is already revealed. Choose another one.")
                continue
    
            # Reveal the cell
            cell_content = game_board[row][col]
            current_display[row][col] = cell_content # Update what the player sees
    
            if cell_content == 'M':
                mines_hit = True
                game_over = True
                print("\nBOOM! You hit a mine. Game Over!")
            else:
                safe_cells_revealed += 1
                if safe_cells_revealed == total_safe_cells:
                    game_over = True
                    print("\nCongratulations! You've cleared all the safe cells. You Win!")
    
        # After game over, reveal the full board for review
        print("\n--- Game Board Revealed ---")
        # Temporarily copy game_board content to display to show all mines
        final_display = [['0' for _ in range(board_cols)] for _ in range(board_rows)]
        for r in range(board_rows):
            for c in range(board_cols):
                final_display[r][c] = game_board[r][c]
        print_display_board(final_display)
    
    if __name__ == "__main__":
        play_game()
    

    The Complete Simple Minesweeper Code

    Here’s the entire code for your simple Minesweeper game:

    import random
    
    def initialize_boards(rows, cols):
        """
        Creates two empty boards: one for game logic and one for display.
    
        Args:
            rows (int): The number of rows in the board.
            cols (int): The number of columns in the board.
    
        Returns:
            tuple: A tuple containing (board, display_board).
                   'board' holds '0' for empty cells initially.
                   'display_board' holds '-' for hidden cells.
        """
        board = [['0' for _ in range(cols)] for _ in range(rows)]
        display_board = [['-' for _ in range(cols)] for _ in range(rows)]
        return board, display_board
    
    def place_mines(board, num_mines):
        """
        Randomly places mines ('M') on the game board.
    
        Args:
            board (list of lists): The game board where mines will be placed.
            num_mines (int): The total number of mines to place.
        """
        rows = len(board)
        cols = len(board[0])
        mines_placed = 0
    
        while mines_placed < num_mines:
            r = random.randint(0, rows - 1) # Pick a random row
            c = random.randint(0, cols - 1) # Pick a random column
    
            if board[r][c] != 'M': # If there isn't already a mine here
                board[r][c] = 'M'
                mines_placed += 1
    
    def calculate_numbers(board):
        """
        Calculates the number of adjacent mines for each non-mine cell.
    
        Args:
            board (list of lists): The game board with mines placed.
        """
        rows = len(board)
        cols = len(board[0])
    
        for r in range(rows):
            for c in range(cols):
                if board[r][c] == 'M':
                    continue # Skip if it's a mine
    
                mine_count = 0
                # Check all 8 adjacent cells
                for dr in [-1, 0, 1]: # Delta row: -1 (up), 0 (same row), 1 (down)
                    for dc in [-1, 0, 1]: # Delta col: -1 (left), 0 (same col), 1 (right)
                        if dr == 0 and dc == 0: # Skip the current cell itself
                            continue
    
                        nr, nc = r + dr, c + dc # Neighbor row, neighbor col
    
                        # Check if the neighbor is within the board boundaries
                        if 0 <= nr < rows and 0 <= nc < cols:
                            if board[nr][nc] == 'M':
                                mine_count += 1
                board[r][c] = str(mine_count) # Store the count as a string
    
    def print_display_board(display_board):
        """
        Prints the current state of the display board to the console.
        """
        rows = len(display_board)
        cols = len(display_board[0])
    
        # Print column numbers
        print("  ", end="")
        for c in range(cols):
            print(f" {c}", end="")
        print()
    
        # Print a separator line
        print("  " + "---" * cols)
    
        # Print row numbers and board content
        for r in range(rows):
            print(f"{r} |", end="")
            for c in range(cols):
                print(f" {display_board[r][c]}", end="")
            print(" |")
        print("  " + "---" * cols)
    
    def get_player_move(rows, cols):
        """
        Prompts the player to enter their move (row and column).
    
        Args:
            rows (int): Total number of rows on the board.
            cols (int): Total number of columns on the board.
    
        Returns:
            tuple: (row, col) if input is valid, otherwise asks again.
        """
        while True:
            try:
                move_input = input(f"Enter your move (row column, e.g., 0 0): ").split()
                r, c = int(move_input[0]), int(move_input[1])
    
                if 0 <= r < rows and 0 <= c < cols:
                    return r, c
                else:
                    print("Invalid input. Row and column must be within board limits.")
            except (ValueError, IndexError):
                print("Invalid input format. Please enter two numbers separated by a space.")
    
    def play_game():
        """
        Main function to run the Minesweeper game.
        """
        print("Welcome to Simple Minesweeper!")
    
        # You can change these values to make the board bigger or smaller
        board_rows = 5
        board_cols = 5
        number_of_mines = 4 
    
        # Initialize the board and display board
        game_board, current_display = initialize_boards(board_rows, board_cols)
        place_mines(game_board, number_of_mines)
        calculate_numbers(game_board)
    
        game_over = False
        safe_cells_revealed = 0
        total_safe_cells = (board_rows * board_cols) - number_of_mines
    
        while not game_over:
            print_display_board(current_display)
    
            # Get player move
            row, col = get_player_move(board_rows, board_cols)
    
            # Check if the cell is already revealed
            if current_display[row][col] != '-':
                print("This cell is already revealed. Choose another one.")
                continue
    
            # Reveal the cell
            cell_content = game_board[row][col]
            current_display[row][col] = cell_content # Update what the player sees
    
            if cell_content == 'M':
                game_over = True
                print("\nBOOM! You hit a mine. Game Over!")
            else:
                safe_cells_revealed += 1
                if safe_cells_revealed == total_safe_cells:
                    game_over = True
                    print("\nCongratulations! You've cleared all the safe cells. You Win!")
    
        # After game over, reveal the full board for review
        print("\n--- Game Board Revealed ---")
        # Temporarily copy game_board content to display to show all mines
        final_display = [['0' for _ in range(board_cols)] for _ in range(board_rows)]
        for r in range(board_rows):
            for c in range(board_cols):
                final_display[r][c] = game_board[r][c]
        print_display_board(final_display)
    
    if __name__ == "__main__":
        play_game()
    

    How to Play Your Game

    1. Save the Code: Save the entire code block above into a file named minesweeper.py (or any name ending with .py).
    2. Open a Terminal/Command Prompt: Navigate to the directory where you saved your file.
    3. Run the Game: Type python minesweeper.py and press Enter.
    4. Enter Moves: The game will prompt you to enter a row and column number (e.g., 0 0 for the top-left corner).
    5. Try to Win!: Avoid mines and reveal all the safe cells. Good luck!

    Conclusion: You’ve Swept the Mines!

    Congratulations! You’ve successfully built a basic Minesweeper game using Python. You’ve learned about creating 2D lists, using the random module, implementing loops and conditionals, defining functions, and managing game flow.

    This is a great foundation! You can further enhance this game by adding features like:
    * Allowing players to “flag” potential mine locations.
    * Implementing the automatic revealing of empty cells and their neighbors.
    * Adding difficulty levels (changing board size and mine count).
    * Creating a graphical user interface (GUI) instead of a text-based one.

    Keep experimenting and happy coding!

  • Let’s Gobble! Create a Simple Pac-Man Game with Python (Beginner-Friendly)

    Have you ever wanted to build your own video game? It might sound complicated, but with Python, one of the most popular and beginner-friendly programming languages, it’s totally achievable! Today, we’re going to dive into creating a very simple version of the classic arcade game, Pac-Man. Don’t worry if you’re new to programming; we’ll break down every step using clear, simple language.

    This project is a fantastic way to learn some fundamental game development concepts like creating game objects, handling user input, detecting collisions, and keeping score. We’ll use a special Python module called turtle for our graphics, which is perfect for getting started with visual programming.

    Why Python and the Turtle Module?

    Python is a fantastic language for beginners because its syntax (the rules for writing code) is very readable, almost like plain English. This makes it easier to understand what your code is doing.

    The turtle module is a built-in Python library that lets you create simple graphics and animations. Think of it like drawing with a robot turtle on a canvas. You tell the turtle to move forward, turn, lift its pen, or put its pen down, and it draws on the screen. It’s an excellent tool for visualizing how programming commands translate into actions on a screen, making it ideal for our simple Pac-Man game.

    • Python: A versatile (meaning it can do many different things) and easy-to-read programming language.
    • Turtle Module: A Python library for creating graphics by issuing commands to a virtual “turtle” that draws on a screen.

    What Will Our Simple Pac-Man Game Do?

    Our version of Pac-Man will be quite basic, focusing on the core elements:
    * A player-controlled Pac-Man.
    * Multiple food pellets (dots) for Pac-Man to eat.
    * Pac-Man moving around the screen using keyboard controls.
    * A scoring system that increases when Pac-Man eats food.
    * Food pellets disappearing when eaten.

    We won’t be adding ghosts or complex mazes in this beginner-friendly version, as that would add too much complexity for our first game. But once you understand these basics, you’ll be well-equipped to add more features!

    Setting Up Your Development Environment

    Before we start coding, you’ll need Python installed on your computer. If you don’t have it, you can download it from the official Python website (python.org). Most operating systems come with a basic text editor, but a more advanced one like Visual Studio Code (VS Code) or PyCharm can make coding easier. For running our simple game, a basic text editor and command prompt will work perfectly.

    Step-by-Step Game Creation

    Let’s build our game piece by piece.

    1. Initialize the Game Window

    First, we need to set up the game window where everything will appear.

    import turtle
    import math # We'll use this later for distance calculations
    
    wn = turtle.Screen() # This creates our game window
    wn.setup(width=600, height=600) # Sets the size of the window
    wn.bgcolor("black") # Sets the background color to black
    wn.title("Simple Pac-Man") # Gives our window a title
    wn.tracer(0) # This turns off screen updates, we'll update manually for smoother animation
    
    • import turtle: This line brings in the turtle module so we can use its functions.
    • wn = turtle.Screen(): We create an object called wn (short for window) which represents our game screen.
    • wn.setup(width=600, height=600): This makes our game window 600 pixels wide and 600 pixels tall. A pixel is a tiny dot on your screen.
    • wn.bgcolor("black"): Sets the background color of our game window.
    • wn.title("Simple Pac-Man"): Puts “Simple Pac-Man” in the title bar of the window.
    • wn.tracer(0): This is a very important line for game animation. By default, turtle updates the screen every time something moves. This can make animations look choppy. wn.tracer(0) tells turtle to not update automatically. We’ll manually update the screen later using wn.update() to make movements smoother.

    2. Create the Player (Pac-Man)

    Now, let’s create our Pac-Man character. We’ll use another turtle object for this.

    player = turtle.Turtle() # Creates a new turtle object for our player
    player.shape("circle") # Makes the player look like a circle
    player.color("yellow") # Sets Pac-Man's color
    player.penup() # Lifts the "pen" so it doesn't draw lines when moving
    player.goto(0, 0) # Sets Pac-Man's starting position at the center of the screen
    player.direction = "stop" # A variable to keep track of Pac-Man's current movement direction
    
    • player = turtle.Turtle(): We create an object named player that is a turtle.
    • player.shape("circle"): We change the default arrow shape of the turtle to a circle.
    • player.color("yellow"): Our Pac-Man will be yellow!
    • player.penup(): When a turtle moves, it usually draws a line. penup() lifts its “pen” so it moves without drawing. pendown() would put the pen back down.
    • player.goto(0, 0): In turtle graphics, the center of the screen is (0, 0). X-coordinates go left-right, Y-coordinates go up-down.
    • player.direction = "stop": We create a custom variable direction for our player turtle to store which way it’s supposed to move. Initially, it’s “stop”.

    3. Create the Food Pellets

    We need some food for Pac-Man to eat! We’ll create a list of turtle objects for our food.

    foods = []
    
    food_positions = [
        (-200, 200), (-150, 200), (-100, 200), (-50, 200), (0, 200), (50, 200), (100, 200), (150, 200), (200, 200),
        (-200, 150), (-100, 150), (0, 150), (100, 150), (200, 150),
        (-200, 100), (-150, 100), (-50, 100), (50, 100), (150, 100), (200, 100),
        (-200, 0), (-100, 0), (0, 0), (100, 0), (200, 0), # Note: (0,0) is player start, we'll remove it later
        (-200, -100), (-150, -100), (-50, -100), (50, -100), (150, -100), (200, -100),
        (-200, -150), (-100, -150), (0, -150), (100, -150), (200, -150),
        (-200, -200), (-150, -200), (-100, -200), (-50, -200), (0, -200), (50, -200), (100, -200), (150, -200), (200, -200)
    ]
    
    for pos in food_positions:
        food = turtle.Turtle()
        food.shape("circle")
        food.color("white")
        food.shapesize(0.5) # Makes the food circles smaller
        food.penup()
        food.goto(pos)
        foods.append(food) # Add each food pellet to our 'foods' list
    
    for food in foods:
        if food.distance(player) < 1: # If food is very close to the player
            food.hideturtle() # Make it invisible
            foods.remove(food) # Remove it from our list
            break # Exit the loop once found and removed
    
    • foods = []: This creates an empty list. A list is like a container that can hold multiple items. We’ll store all our food turtle objects here.
    • food_positions = [...]: We define a list of (x, y) coordinates where our food pellets will appear.
    • for pos in food_positions:: This is a for loop, which means it will repeat the code inside it for each item in food_positions. For each pos (position):
      • We create a new food turtle.
      • Set its shape to “circle”, color to “white”, and make it smaller with shapesize(0.5).
      • Move it to the current pos.
      • foods.append(food): We add this newly created food turtle to our foods list.
    • food.distance(player) < 1: The distance() method calculates the distance between two turtles. If it’s less than 1, they are essentially at the same spot.
    • food.hideturtle(): Makes the food turtle invisible.
    • foods.remove(food): Deletes the food turtle from our foods list.

    4. Implement Player Movement

    We need functions to tell Pac-Man which way to go when the user presses a key.

    def go_up():
        player.direction = "up"
    
    def go_down():
        player.direction = "down"
    
    def go_left():
        player.direction = "left"
    
    def go_right():
        player.direction = "right"
    
    wn.listen() # Tells the window to listen for keyboard input
    wn.onkeypress(go_up, "w") # When 'w' is pressed, call go_up()
    wn.onkeypress(go_down, "s") # When 's' is pressed, call go_down()
    wn.onkeypress(go_left, "a") # When 'a' is pressed, call go_left()
    wn.onkeypress(go_right, "d") # When 'd' is pressed, call go_right()
    
    wn.onkeypress(go_up, "Up")
    wn.onkeypress(go_down, "Down")
    wn.onkeypress(go_left, "Left")
    wn.onkeypress(go_right, "Right")
    
    • go_up(), go_down(), etc.: These are simple functions that just update our player.direction variable. Pac-Man won’t move immediately when a key is pressed; instead, we’ll check this direction variable inside our main game loop to move him consistently.
    • wn.listen(): This line is crucial; it tells the game window to start listening for keyboard presses.
    • wn.onkeypress(function, key): This connects a key press to a function. For example, when the ‘w’ key is pressed, the go_up() function will be called.

    5. Display the Score

    We need a way to show the player’s score. We’ll use another turtle for this, but this turtle will only write text.

    score = 0
    
    score_display = turtle.Turtle()
    score_display.speed(0) # Fastest animation speed
    score_display.color("white")
    score_display.penup()
    score_display.hideturtle() # We don't want to see the turtle itself, just its writing
    score_display.goto(0, 260) # Position it near the top of the screen
    score_display.write("Score: 0", align="center", font=("Courier", 24, "normal")) # Display initial score
    
    • score = 0: Initializes our score variable.
    • score_display = turtle.Turtle(): Creates a turtle for displaying text.
    • score_display.hideturtle(): We don’t want to see the turtle drawing the score, just the score text itself.
    • score_display.goto(0, 260): Moves the turtle to the top of the screen.
    • score_display.write(...): This command makes the turtle write text.
      • "Score: 0": The actual text to display.
      • align="center": Centers the text.
      • font=("Courier", 24, "normal"): Sets the font style, size, and weight.

    6. The Main Game Loop

    This is the heart of our game. The game loop runs continuously, updating everything on the screen and checking for actions.

    while True: # This loop will run forever until the program is closed
        wn.update() # Manually update the screen (because we used wn.tracer(0))
    
        # Move the player
        if player.direction == "up":
            y = player.ycor() # Get current Y coordinate
            player.sety(y + 2) # Move up by 2 pixels
        if player.direction == "down":
            y = player.ycor()
            player.sety(y - 2)
        if player.direction == "left":
            x = player.xcor() # Get current X coordinate
            player.setx(x - 2) # Move left by 2 pixels
        if player.direction == "right":
            x = player.xcor()
            player.setx(x + 2)
    
        # Wrap around the edges (simple boundary)
        if player.xcor() > 290: # If Pac-Man goes too far right
            player.setx(-290) # Warp to the left side
        if player.xcor() < -290: # If Pac-Man goes too far left
            player.setx(290) # Warp to the right side
        if player.ycor() > 290: # If Pac-Man goes too far up
            player.sety(-290) # Warp to the bottom side
        if player.ycor() < -290: # If Pac-Man goes too far down
            player.sety(290) # Warp to the top side
    
        # Check for collision with food
        # We iterate backwards through the list to safely remove items
        for i in range(len(foods) - 1, -1, -1):
            food = foods[i]
            if player.distance(food) < 15: # If Pac-Man is close enough to the food (adjust 15 as needed)
                food.hideturtle() # Make the food disappear
                foods.pop(i) # Remove the food from the list
                score += 10 # Increase the score
                score_display.clear() # Clear the old score text
                score_display.write(f"Score: {score}", align="center", font=("Courier", 24, "normal")) # Write the new score
    
        # Check for game over (all food eaten)
        if not foods: # If the 'foods' list is empty
            score_display.clear()
            score_display.goto(0, 0) # Move score display to center
            score_display.write(f"GAME OVER! Your Score: {score}", align="center", font=("Courier", 30, "bold"))
            player.hideturtle() # Hide Pac-Man
            wn.update() # Update one last time
            break # Exit the game loop
    
    • while True:: This creates an infinite loop. The code inside will run again and again until the program is closed or a break statement is encountered.
    • wn.update(): This is where we manually refresh the screen. Because wn.tracer(0) is on, all movements and changes only become visible after wn.update() is called.
    • player.ycor() / player.xcor(): These functions get the current Y (vertical) or X (horizontal) coordinate of the player turtle.
    • player.sety(y + 2) / player.setx(x - 2): These functions set the new Y or X coordinate. We add or subtract 2 to move Pac-Man in the desired direction. This ‘2’ represents his speed.
    • Wrap around edges: These if statements check if Pac-Man has gone off one side of the screen and, if so, goto() the opposite side. This creates a classic Pac-Man “wrap-around” effect.
    • for i in range(len(foods) - 1, -1, -1):: This loop goes through the foods list backwards. This is a common and safe practice when you might be removing items from a list while you’re looping through it. If you iterate forwards and remove an item, the list shortens and the indices (positions of items) shift, which can lead to errors.
    • player.distance(food) < 15: This checks if Pac-Man is close enough to a food pellet to “eat” it. The number 15 is a radius; you can adjust it if you want Pac-Man to have to be closer or further away to eat food.
    • foods.pop(i): This removes the food item at index i from the foods list.
    • score_display.clear(): Before writing a new score, we clear the old one so it doesn’t overlap.
    • if not foods:: This checks if the foods list is empty. If it is, it means Pac-Man has eaten all the food, and the game ends!

    Putting It All Together (Complete Code)

    Here’s the complete code for your simple Pac-Man game. You can copy and paste this into a Python file (e.g., pacman_simple.py) and run it.

    import turtle
    import math
    
    wn = turtle.Screen()
    wn.setup(width=600, height=600)
    wn.bgcolor("black")
    wn.title("Simple Pac-Man")
    wn.tracer(0) # Turn off screen updates for smoother animation
    
    player = turtle.Turtle()
    player.shape("circle")
    player.color("yellow")
    player.penup()
    player.goto(0, 0)
    player.direction = "stop" # Initial direction
    
    foods = []
    food_positions = [
        (-200, 200), (-150, 200), (-100, 200), (-50, 200), (0, 200), (50, 200), (100, 200), (150, 200), (200, 200),
        (-200, 150), (-100, 150), (0, 150), (100, 150), (200, 150),
        (-200, 100), (-150, 100), (-50, 100), (50, 100), (150, 100), (200, 100),
        (-200, 0), (-100, 0), (100, 0), (200, 0), # (0,0) excluded here to avoid overlap with player start
        (-200, -100), (-150, -100), (-50, -100), (50, -100), (150, -100), (200, -100),
        (-200, -150), (-100, -150), (0, -150), (100, -150), (200, -150),
        (-200, -200), (-150, -200), (-100, -200), (-50, -200), (0, -200), (50, -200), (100, -200), (150, -200), (200, -200)
    ]
    
    for pos in food_positions:
        food = turtle.Turtle()
        food.shape("circle")
        food.color("white")
        food.shapesize(0.5)
        food.penup()
        food.goto(pos)
        foods.append(food)
    
    def go_up():
        player.direction = "up"
    def go_down():
        player.direction = "down"
    def go_left():
        player.direction = "left"
    def go_right():
        player.direction = "right"
    
    wn.listen()
    wn.onkeypress(go_up, "w")
    wn.onkeypress(go_down, "s")
    wn.onkeypress(go_left, "a")
    wn.onkeypress(go_right, "d")
    wn.onkeypress(go_up, "Up")
    wn.onkeypress(go_down, "Down")
    wn.onkeypress(go_left, "Left")
    wn.onkeypress(go_right, "Right")
    
    score = 0
    score_display = turtle.Turtle()
    score_display.speed(0)
    score_display.color("white")
    score_display.penup()
    score_display.hideturtle()
    score_display.goto(0, 260)
    score_display.write("Score: 0", align="center", font=("Courier", 24, "normal"))
    
    while True:
        wn.update() # Manually update the screen
    
        # Move the player
        if player.direction == "up":
            y = player.ycor()
            player.sety(y + 2)
        elif player.direction == "down": # Use elif to ensure only one direction is processed
            y = player.ycor()
            player.sety(y - 2)
        elif player.direction == "left":
            x = player.xcor()
            player.setx(x - 2)
        elif player.direction == "right":
            x = player.xcor()
            player.setx(x + 2)
    
        # Wrap around the edges
        if player.xcor() > 290:
            player.setx(-290)
        elif player.xcor() < -290:
            player.setx(290)
        elif player.ycor() > 290:
            player.sety(-290)
        elif player.ycor() < -290:
            player.sety(290)
    
        # Check for collision with food
        for i in range(len(foods) - 1, -1, -1): # Loop backwards
            food = foods[i]
            if player.distance(food) < 15: # Collision distance
                food.hideturtle()
                foods.pop(i)
                score += 10
                score_display.clear()
                score_display.write(f"Score: {score}", align="center", font=("Courier", 24, "normal"))
    
        # Check for game over (all food eaten)
        if not foods:
            score_display.clear()
            score_display.goto(0, 0)
            score_display.write(f"GAME OVER! Your Score: {score}", align="center", font=("Courier", 30, "bold"))
            player.hideturtle()
            wn.update()
            break # Exit the game loop
    

    How to Run Your Game

    1. Save: Save the code above into a file named pacman_simple.py (or any name ending with .py).
    2. Open Terminal/Command Prompt: Navigate to the folder where you saved your file using your terminal or command prompt.
    3. Run: Type python pacman_simple.py and press Enter.

    A new window should pop up, showing your black game screen, a yellow Pac-Man, and white food pellets. Use the ‘W’, ‘A’, ‘S’, ‘D’ keys or the arrow keys to move Pac-Man and start gobbling up those pellets!

    Next Steps and Improvements

    Congratulations! You’ve just created your very own simple game in Python. This is just the beginning. Here are some ideas to expand your game:

    • Add Walls/Maze: You could create simple “walls” using more turtle objects or by drawing lines and preventing Pac-Man from passing through them.
    • Introduce Ghosts: This is a big step, but you could create other turtle objects (ghosts) that move independently and end the game if they touch Pac-Man.
    • Different Food Types: Add larger pellets that give more points or special power-ups.
    • Levels: Once all food is eaten, reset the game with more food or a different layout.
    • Sounds: Python has modules (like winsound on Windows or pygame.mixer) to play sound effects when food is eaten or the game ends.

    Conclusion

    Building games is a fantastic way to learn programming. The turtle module in Python provides an intuitive and visual way to understand core programming concepts without getting bogged down in complex graphics libraries. You’ve taken your first steps into game development, and hopefully, you’ve seen how a few lines of code can bring an idea to life. Keep experimenting, keep coding, and most importantly, have fun!


  • Jump, Run, and Code! Build Your First Platformer Game with Python and Pygame

    Hello there, fellow adventurers and aspiring game developers! Have you ever dreamed of creating your own video game, even if it’s just a simple one? Well, today is your lucky day! We’re going to embark on an exciting journey to build a basic platformer game using Python and a fantastic library called Pygame.

    Platformer games are a classic genre where you control a character who runs, jumps, and sometimes climbs across different platforms to reach a goal. Think Super Mario Bros. or Celeste! They’re not only incredibly fun to play but also a great starting point for learning game development because they introduce fundamental concepts like player movement, gravity, and collision detection.

    By the end of this guide, you’ll have a simple but functional game where you can control a little rectangle (our hero!) that can jump and move across a basic ground platform. Ready to bring your ideas to life? Let’s dive in!

    What You’ll Need

    Before we start coding, we need to make sure you have the right tools. Don’t worry, it’s pretty straightforward!

    • Python: You’ll need Python installed on your computer. We recommend Python 3. If you don’t have it, you can download it from the official Python website: python.org.
    • Pygame: This is a powerful library that makes game development with Python much easier. It handles things like graphics, sounds, and user input.

    Installing Pygame

    Once Python is installed, opening your computer’s terminal or command prompt and running a single command will install Pygame.

    pip install pygame
    
    • pip (Package Installer for Python): This is Python’s standard package manager, used to install and manage software packages (libraries) written in Python.

    If the installation is successful, you’re all set!

    Game Basics: The Window and Game Loop

    Every game needs a window to display its visuals and a “game loop” that continuously runs to update the game world and handle player actions.

    Setting up Pygame and the Display

    First, we’ll initialize Pygame and create our game window.

    import pygame
    import sys
    
    pygame.init()
    
    SCREEN_WIDTH = 800
    SCREEN_HEIGHT = 600
    SCREEN = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    
    pygame.display.set_caption("My Simple Platformer")
    
    WHITE = (255, 255, 255)
    BLACK = (0, 0, 0)
    RED = (255, 0, 0)
    BLUE = (0, 0, 255)
    GREEN = (0, 255, 0)
    

    The Heart of the Game: The Game Loop

    The game loop is an endless cycle where the game checks for inputs (like keyboard presses), updates game elements (like player position), and then draws everything on the screen.

    running = True
    while running:
        # 1. Event Handling: Check for user input (keyboard, mouse, closing window)
        for event in pygame.event.get():
            if event.type == pygame.QUIT: # If the user clicks the 'X' to close the window
                running = False # Stop the game loop
        # Technical Term: Event Handling - This is how our game listens for and responds to anything that happens, like a key press or mouse click.
        # Technical Term: pygame.QUIT - This is a specific event that occurs when the user tries to close the game window.
    
        # 2. Update game state (we'll add player movement here later)
    
        # 3. Drawing: Clear the screen and draw game objects
        SCREEN.fill(BLUE) # Fill the background with blue (our sky)
    
        # (We'll draw our player and ground here soon!)
    
        # 4. Update the display to show what we've drawn
        pygame.display.flip()
        # Technical Term: pygame.display.flip() - This updates the entire screen to show everything that has been drawn since the last update.
    
    pygame.quit()
    sys.exit()
    

    If you run this code now, you’ll see a blue window pop up and stay there until you close it. That’s our basic game structure!

    Our Player: A Simple Rectangle

    Let’s give our game a hero! For simplicity, our player will be a red rectangle. We’ll define its size, position, and properties needed for movement.

    player_width = 30
    player_height = 50
    player_x = SCREEN_WIDTH // 2 - player_width // 2 # Start in the middle
    player_y = SCREEN_HEIGHT - player_height - 50 # Start a bit above the bottom
    player_velocity_x = 0 # Horizontal speed
    player_velocity_y = 0 # Vertical speed (for jumping and gravity)
    player_speed = 5
    jump_power = -15 # Negative because y-axis increases downwards
    gravity = 0.8
    is_grounded = False # To check if the player is on a surface
    

    Now, let’s add code to draw our player inside the game loop, right before pygame.display.flip().

    player_rect = pygame.Rect(player_x, player_y, player_width, player_height)
    pygame.draw.rect(SCREEN, RED, player_rect)
    

    Bringing in Gravity and Jumping

    Gravity is what makes things fall! We’ll apply it to our player, and then allow the player to defy gravity with a jump.

    Implementing Gravity

    Gravity will constantly pull our player downwards by increasing player_velocity_y.

    player_velocity_y += gravity
    player_y += player_velocity_y
    

    If you run this now, our red rectangle will fall off the screen! We need a ground to land on.

    Making a Ground

    Let’s create a green rectangle at the bottom of the screen to serve as our ground.

    ground_height = 20
    ground_x = 0
    ground_y = SCREEN_HEIGHT - ground_height
    ground_width = SCREEN_WIDTH
    
    ground_rect = pygame.Rect(ground_x, ground_y, ground_width, ground_height)
    
    pygame.draw.rect(SCREEN, GREEN, ground_rect)
    

    Collision Detection: Player and Ground

    Our player currently falls through the ground. We need to detect when the player’s rectangle hits the ground’s rectangle and stop its vertical movement.

    if player_rect.colliderect(ground_rect):
        player_y = ground_y - player_height # Place player on top of ground
        player_velocity_y = 0 # Stop vertical movement
        is_grounded = True # Player is now on the ground
    else:
        is_grounded = False # Player is in the air
    

    Now your player should fall and stop on the green ground!

    Adding the Jump

    We’ll make the player jump when the spacebar is pressed, but only if they are is_grounded.

    if event.type == pygame.KEYDOWN: # If a key is pressed down
        if event.key == pygame.K_SPACE and is_grounded: # If it's the spacebar and player is on ground
            player_velocity_y = jump_power # Apply upward velocity for jump
            is_grounded = False # Player is no longer grounded
    

    Try it out! Your player can now jump!

    Horizontal Movement

    What’s a platformer without being able to move left and right? We’ll use the left and right arrow keys.

    Pygame has a convenient function, pygame.key.get_pressed(), which tells us which keys are currently held down. This is great for continuous movement.

    keys = pygame.key.get_pressed()
    
    player_velocity_x = 0 # Reset horizontal velocity each frame
    if keys[pygame.K_LEFT]:
        player_velocity_x = -player_speed
    if keys[pygame.K_RIGHT]:
        player_velocity_x = player_speed
    
    player_x += player_velocity_x
    

    Now, combine everything, and you’ve got a basic platformer!

    Putting It All Together: The Complete Code

    Here’s the full code for our simple platformer game. Copy and paste this into a Python file (e.g., platformer.py) and run it!

    import pygame
    import sys
    
    pygame.init()
    
    SCREEN_WIDTH = 800
    SCREEN_HEIGHT = 600
    SCREEN = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    
    pygame.display.set_caption("My Simple Platformer")
    
    WHITE = (255, 255, 255)
    BLACK = (0, 0, 0)
    RED = (255, 0, 0)
    BLUE = (0, 0, 255)
    GREEN = (0, 255, 0)
    
    player_width = 30
    player_height = 50
    player_x = SCREEN_WIDTH // 2 - player_width // 2 # Start in the middle horizontally
    player_y = SCREEN_HEIGHT - player_height - 50    # Start a bit above the bottom
    player_velocity_x = 0
    player_velocity_y = 0
    player_speed = 5
    jump_power = -15
    gravity = 0.8
    is_grounded = False
    
    ground_height = 20
    ground_x = 0
    ground_y = SCREEN_HEIGHT - ground_height
    ground_width = SCREEN_WIDTH
    ground_rect = pygame.Rect(ground_x, ground_y, ground_width, ground_height)
    
    running = True
    clock = pygame.time.Clock() # For controlling frame rate
    
    while running:
        # 8. Event Handling
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE and is_grounded:
                    player_velocity_y = jump_power
                    is_grounded = False
    
        # 9. Handle horizontal movement with continuous key presses
        keys = pygame.key.get_pressed()
        player_velocity_x = 0 # Reset horizontal velocity each frame
        if keys[pygame.K_LEFT]:
            player_velocity_x = -player_speed
        if keys[pygame.K_RIGHT]:
            player_velocity_x = player_speed
    
        # 10. Update player's horizontal position
        player_x += player_velocity_x
    
        # 11. Apply gravity
        player_velocity_y += gravity
        player_y += player_velocity_y
    
        # 12. Create player rectangle for collision detection and drawing
        player_rect = pygame.Rect(player_x, player_y, player_width, player_height)
    
        # 13. Collision detection with ground
        if player_rect.colliderect(ground_rect):
            player_y = ground_y - player_height # Place player on top of ground
            player_velocity_y = 0               # Stop vertical movement
            is_grounded = True                  # Player is now on the ground
        else:
            is_grounded = False                 # Player is in the air
    
        # 14. Keep player within screen bounds horizontally
        if player_x < 0:
            player_x = 0
        if player_x > SCREEN_WIDTH - player_width:
            player_x = SCREEN_WIDTH - player_width
    
        # 15. Drawing
        SCREEN.fill(BLUE) # Fill background with blue
    
        pygame.draw.rect(SCREEN, GREEN, ground_rect) # Draw the ground
        pygame.draw.rect(SCREEN, RED, player_rect)   # Draw the player
    
        # 16. Update the display
        pygame.display.flip()
    
        # 17. Cap the frame rate (e.g., to 60 FPS)
        clock.tick(60) # This makes sure our game doesn't run too fast
        # Technical Term: FPS (Frames Per Second) - How many times the game updates and draws everything in one second. 60 FPS is generally a smooth experience.
    
    pygame.quit()
    sys.exit()
    

    Next Steps for Fun & Experiments!

    You’ve built the foundation of a platformer! Now the real fun begins: customizing and expanding your game. Here are some ideas:

    • Add more platforms: Instead of just one ground, create multiple pygame.Rect objects for platforms at different heights.
    • Collectibles: Draw small squares or circles that disappear when the player touches them.
    • Enemies: Introduce simple enemies that move back and forth, and figure out what happens when the player collides with them.
    • Sprites: Replace the plain red rectangle with actual character images (sprites). Pygame makes it easy to load and display images.
    • Backgrounds: Add a fancy background image instead of a solid blue color.
    • Level design: Create more complex layouts for your platforms.
    • Game over conditions: What happens if the player falls off the bottom of the screen?

    Conclusion

    Congratulations! You’ve successfully built your very first platformer game from scratch using Python and Pygame. You’ve learned about game loops, event handling, player movement, gravity, and collision detection – all core concepts in game development.

    This project is just the beginning. Game development is a creative and rewarding field, and with the basics you’ve learned today, you have a solid foundation to explore more advanced techniques and build even more amazing games. Keep experimenting, keep coding, and most importantly, have fun! Happy coding!