Open In App

Create a Python Wordle Clone With Rich

Last Updated : 13 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

We are tasked with developing a Python Wordle clone using the rich library. This article will guide you through the process of creating a Python Wordle clone with rich.

What is Wordle Clone?

Wordle Clone is a game where, upon opening a web page, a hint is presented on the screen. Players must decipher the word based on the provided hint, with five chances indicated by five green-colored boxes. If a wrong word is guessed, the green boxes turn red. The game is lost when all boxes become red, and victory is achieved by correctly guessing the word. Regardless of the outcome, a flashing message will be displayed on the web page.

Create a Python Wordle Clone With Rich

Below are the basic steps to create a Python Wordle Clone:

Create a Virtual Environment

First, create the virtual environment using the below commands.

python -m venv env 
.\env\Scripts\activate.ps1

Install Flask Library

First, install Flask and Flask-Rich to facilitate the creation of the Wordle Clone in Python. Execute the following commands to install Flask and Flask-Rich:

pip install flask
pip install flask-rich

File Structure

Main/
|-- env
|-- app.py
|-- templates/
|-- index.html

Code Explanation

Here, the step-by-step explanation of Python Wordle Clone with Rich:

Step 1: Flask Setup and Initialization

Below, code imports the necessary modules for the Flask web application, including Flask itself for web functionality and rich for formatting console output. It also initializes a Flask application (app) and a rich console (console).

Python3
from flask import Flask, render_template, request, redirect, url_for
from rich.console import Console
from rich.table import Table
import random

app = Flask(__name__)
console = Console()

Step 2: Wordle Game Setup

Below, code defines a list of words with corresponding hints. It then initializes the Wordle game by randomly selecting a word from the list (word_to_guess), initializing an empty set for correct guesses (correct_guesses), and setting the initial number of remaining chances to 5 (remaining_chances).

Python3
# List of words and corresponding hints
word_list = [
    {"word": "python", "hint": "A programming language"},
    {"word": "flask", "hint": "A web framework for Python"},
    {"word": "banana", "hint": "A yellow fruit"},
    {"word": "mountain", "hint": "A land of green hills"},
    {"word": "sunflower", "hint": "A yellow color flower"}
    # Add more words and hints as needed
]

word_to_guess = random.choice(word_list)
correct_guesses = set()
remaining_chances = 5

Step 3: Wordle Game Logic Functions

Below created functions provide the core logic for the Wordle game:

  • display_word: Generates the displayed word with underscores for unguessed letters.
  • evaluate_guess: Checks if a guessed word matches the actual word and updates correct guesses accordingly.
  • game_status: Determines the game status (win or ongoing) based on correct guesses.
Python3
def display_word(word, correct_guesses):
    displayed_word = ""
    for letter in word:
        if letter in correct_guesses:
            displayed_word += letter
        else:
            displayed_word += "_"
    return displayed_word

def evaluate_guess(word, guess, correct_guesses):
    if guess.lower() == word.lower():
        correct_guesses.update(word)
        return True
    return False

def game_status(word, correct_guesses):
    if set(word.lower()) == correct_guesses:
        return "win"
    return "ongoing"

Step 4:Flask Routes and Web Interface

Below code defines two Flask routes:

  • /: Handles both GET and POST requests for the main game page. Manages user input, updates game state, and renders the HTML template with the appropriate information.
  • /reset: Resets the game state (word to guess, correct guesses, remaining chances) and redirects back to the main page.
Python3
@app.route("/", methods=["GET", "POST"])
def index():
    global word_to_guess, correct_guesses, remaining_chances

    message = None
    message_class = None

    if request.method == "POST":
        guess = request.form["guess"]
        if guess:
            guess = guess.lower()
            if evaluate_guess(word_to_guess["word"], guess, correct_guesses):
                status = game_status(word_to_guess["word"], correct_guesses)
                if status == "win":
                    message = "Congratulations! You guessed the word: {}".format(word_to_guess["word"])
                    message_class = "congratulations"
                return render_template("index.html", message=message, message_class=message_class)
            else:
                remaining_chances -= 1
                if remaining_chances == 0:
                    message = "Game Over! The correct word was: {}".format(word_to_guess["word"])
                    message_class = "game-over"
                    return render_template("index.html", message=message, message_class=message_class)

    status = game_status(word_to_guess["word"], correct_guesses)
    displayed_word = display_word(word_to_guess["word"], correct_guesses)
    table = Table(title="[bold]Wordle[/bold]", show_lines=True)
    table.add_row(displayed_word)
    console.print(table)
    incorrect_boxes = ["green" if i < remaining_chances else "red" for i in range(5)]

    if status == "ongoing":
        return render_template("index.html", word=displayed_word, hint=word_to_guess["hint"],
                               remaining_chances=remaining_chances, status=status, incorrect_boxes=incorrect_boxes, message=message, message_class=message_class)
    else:
        return render_template("index.html", message=message, message_class=message_class)


@app.route("/reset")
def reset():
    global word_to_guess, correct_guesses, remaining_chances
    word_to_guess = random.choice(word_list)
    correct_guesses = set()
    remaining_chances = 5
    return redirect(url_for("index"))

Complete Code

Below is the complete code of app.py that we have used in our article.

Python3
from flask import Flask, render_template, request, redirect, url_for
from rich.console import Console
from rich.table import Table
import random

app = Flask(__name__)
console = Console()

# List of words and corresponding hints
word_list = [
    {"word": "python", "hint": "A programming language"},
    {"word": "flask", "hint": "A web framework for Python"},
    {"word": "banana", "hint": "A yellow fruit"},
    {"word": "mountain", "hint": "A land of green hills"},
    {"word": "sunflower", "hint": "A yellow color flower"}
    # Add more words and hints as needed
]

# Initialize Wordle game with a random word
word_to_guess = random.choice(word_list)
correct_guesses = set()
remaining_chances = 5

def display_word(word, correct_guesses):
    displayed_word = ""
    for letter in word:
        if letter in correct_guesses:
            displayed_word += letter
        else:
            displayed_word += "_"
    return displayed_word

def evaluate_guess(word, guess, correct_guesses):
    if guess.lower() == word.lower():
        correct_guesses.update(word)
        return True
    return False

def game_status(word, correct_guesses):
    if set(word.lower()) == correct_guesses:
        return "win"
    return "ongoing"

@app.route("/", methods=["GET", "POST"])
def index():
    global word_to_guess, correct_guesses, remaining_chances

    message = None
    message_class = None

    if request.method == "POST":
        guess = request.form["guess"]
        if guess:
            guess = guess.lower()
            if evaluate_guess(word_to_guess["word"], guess, correct_guesses):
                status = game_status(word_to_guess["word"], correct_guesses)
                if status == "win":
                    message = "Congratulations! You guessed the word: {}".format(word_to_guess["word"])
                    message_class = "congratulations"
                return render_template("index.html", message=message, message_class=message_class)
            else:
                remaining_chances -= 1
                if remaining_chances == 0:
                    message = "Game Over! The correct word was: {}".format(word_to_guess["word"])
                    message_class = "game-over"
                    return render_template("index.html", message=message, message_class=message_class)

    status = game_status(word_to_guess["word"], correct_guesses)
    displayed_word = display_word(word_to_guess["word"], correct_guesses)
    table = Table(title="[bold]Wordle[/bold]", show_lines=True)
    table.add_row(displayed_word)
    console.print(table)
    incorrect_boxes = ["green" if i < remaining_chances else "red" for i in range(5)]

    if status == "ongoing":
        return render_template("index.html", word=displayed_word, hint=word_to_guess["hint"],
                               remaining_chances=remaining_chances, status=status, incorrect_boxes=incorrect_boxes, message=message, message_class=message_class)
    else:
        return render_template("index.html", message=message, message_class=message_class)


@app.route("/reset")
def reset():
    global word_to_guess, correct_guesses, remaining_chances
    word_to_guess = random.choice(word_list)
    correct_guesses = set()
    remaining_chances = 5
    return redirect(url_for("index"))

if __name__ == "__main__":
    app.run(debug=True)

Creating GUI

index.html : The HTML code structures a Wordle game web page with a clean, centered layout. It dynamically adjusts content based on game progress, displaying hints, user input forms, and visual feedback for incorrect guesses. The design is visually appealing, with colored elements changing based on game outcomes.

HTML
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Wordle Clone</title>
    <style>
        body {
            font-family: 'Arial', sans-serif;
            background-color: #f4f4f4;
            text-align: center;
            margin: 20px;
        }

        .container {
            max-width: 600px;
            margin: 0 auto;
            background-color: #fff;
            padding: 20px;
            border-radius: 10px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        }

        h1 {
            color: #333;
        }

        .remaining-chances {
            color: green;
            font-weight: bold;
            margin-top: 10px;
            font-size: 17px;
        }

        .hint {
            color: black;
            margin-bottom: 20px;
            font-size: 20px;
            font-family: 'Times New Roman', Times, serif;

        }

        form {
            margin-top: 20px;
        }

        label {
            font-size: 18px;
            color: #333;
            margin-right: 10px;
        }

        input[type="text"] {
            padding: 8px;
            font-size: 16px;
            border: 1px solid #ccc;
            border-radius: 4px;
            margin-right: 10px;
        }

        button {
            padding: 8px 15px;
            font-size: 16px;
            background-color: #4caf50;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }

        button:hover {
            background-color: #45a049;
        }

        .wordle-container {
            margin-top: 30px;
        }

        .wordle-box {
            display: inline-block;
            border: 2px solid #333;
            margin: 5px;
            padding: 10px;
            font-size: 24px;
            background-color: #fff;
            color: #333;
            border-radius: 5px;
        }

        .congratulations {
            color: #4caf50;
            font-weight: bold;
            margin-top: 20px;
        }

        .incorrect-guess {
            color: #d9534f;
            font-weight: bold;
            margin-top: 20px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Wordle</h1>
        
        {% if message %}
            <h2 class="{% if message_class == 'congratulations' %}congratulations{% elif message_class == 'game-over' %}incorrect-guess{% endif %}">{{ message }}</h2>
        {% else %}
            <p class="remaining-chances">Remaining Chances: {{ remaining_chances }}</p>
            <p class="hint">Hint : {{ hint }}</p>
            
            <form method="post" action="/">
                <label for="guess">Enter the word:</label>
                <input type="text" id="guess" name="guess" required>
                <button type="submit">Submit</button>
            </form>
            
            <div class="wordle-container">
                {% for box_color in incorrect_boxes %}
                    <div class="wordle-box" style="background-color: {{ box_color }};">&nbsp;</div>
                {% endfor %}
            </div>
        {% endif %}
        
        {% if message %}
            <button onclick="window.location.href='{{ url_for('reset') }}'">Play Again</button>
        {% endif %}
    </div>
</body>
</html>

Run the Server

For run the server use the below command

python main.py 

Output:

wordl-ezgifcom-video-to-gif-converter

Create a Python Wordle Clone With Rich




Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads