#These are the imports that i need to run the code.
import random
import time
import os

# This gives the print a typewriter effect.
# This was function was made by chat GPT.
def typewriter_print(text, delay=0.03):
    for char in text:
        print(char, end='', flush=True)
        time.sleep(delay)
    print()

# This is the title screen of my game. 
# I learned this from a Youtube video.
def title_screen():
    title = """
 ____      ____  ________  _____       ______    ___   ____    ____  ________  
|_  _|    |_  _||_   __  ||_   _|    .' ___  | .'   .|_   \  /   _||_   __  | 
  \ \  /\  / /    | |_ \_|  | |     / .'   \_|/  .-.  \ |   \/   |    | |_ \_| 
   \ \/  \/ /     |  _| _   | |   _ | |       | |   | | | |\  /| |    |  _| _  
    \  /\  /     _| |__/ | _| |__/ |\ .___.'\\  - _ /_| |_\/_| |_  _| |__/ | 
     \/  \/     |________||________|  .____ .' \ ___.'|_____||_____||________| 
                                                                               
    """
    os.system('cls' if os.name == 'nt' else 'clear')  # Clear screen
    for line in title.split("\n"):
        typewriter_print(line, 0.005)# This is how fast the welcome will come into the screen witht he typewriter affect
    time.sleep(1)

# This is another welcoming message to the player.
def show_title():
    typewriter_print("🎮 Welcome to my word guessing game 🎈")
    typewriter_print("--------------------------------")

# This is my wordlist for the game for each difficulty
def wordlist():
    words_list = {
        "easy": ["jade", "love", "beta", "fall", "game"],
        "medium": ["python", "sprite", "launch", "broast", "backup"],
        "hard": ["software", "backward", "crambled", "compiler", "protocol"]
    }
    #I got this colouring idea from Muhammad Irham but I leant it from Youtube shorts.
    #Easy is in green, medium is yellow, and hard is red
    print("\033[32mEasy\033[32m")
    print("\033[33mMedium\033[33m")
    print("\033[91mHard\033[0m")


    difficulty = input("Choose difficulty(easy,medium,hard): ").lower()
    while difficulty not in words_list:
        typewriter_print("❌ Invalid choice.")
        difficulty = input("Choose difficulty(easy,medium,hard): ").lower()

        if difficulty == 'easy':
           typewriter_print("This will consist of 4 letter words")
        if difficulty == 'medium':
            typewriter_print("This will consist of 6 letter words")
        else:
            typewriter_print("This will consist of 8 letter words")


    return random.choice(words_list[difficulty])

# Shows the rules to the player.
def show_rules():
    typewriter_print("\n📜 Game Rules:")
    typewriter_print("1️⃣ Guess the secret word one letter at a time.")
    typewriter_print("2️⃣ You have 10 incorrect attempts.")
    typewriter_print("3️⃣ Good luck!\n")

# Bomb stages for Beat the Bomb mode
# I got the ASCII stages from https://www.asciiart.eu/weapons/explosives
def bomb_stages(tries_left):
    stages = [
        """
        |\**/|      
        \ == /
         |  |
         |  |
         \  /
          \/
        """,
        """
        |\**/|      
        \ == /
         |  |*
         |  |
         \  /
          \/ 
        """,
        """
        |\**/|      
        \ == /
         |  |*
         |  |
         \  /*
          \/ 
        """,
        # You can add more detailed stages if desired; for brevity, reusing stages
        """
        |\**/|      
        \ == /
         |  |*
         |  |*
         \  /*
          \/ 
        """,
        """
        |\**/|      
        \ == /
       * |  |*
         |  |*
         \  /*
          \/ 
        """,
        """
        |\**/|      
        \ == /
       * |  |*
       * |  |*
         \  /*
          \/ 
        """,
        """
        |\**/|      
        \ == /
       * |  |*
       * |  |*
       * \  /*
          \/ 
        """,
        """
        |\**/|      
        \ == /
       * |  |*
       * |  |*
       * \  /*
          \/ 💥
        """,
        """
        |\💥/|      
        \ == /
       * |  |*
       * |  |*
       * \  /*
          \/ 💥
        """,
        """
        |\💥/|      
        \ == /
       * |  |*
       * |  | 🔥
       * \  /*
          \/ 💥
        """,
        """
        _.-^^---....,,--__       
     _--                 ---_  
    (< 💥💥💥💥💥💥💥💥💥>)
    |         BOOM!!          | 
     \._ 💥💥💥💥💥💥💥 _./  
          --. . , ; .--'''       
              | |   |             
   ---     .-=||  | |=-.   ---
           `-=#$%&%$#=-'   
     ---      | ;  :|     ---
     _____.,-#%&$@%#&#~,._____
    💥💥💥💥💥💥💥💥💥💥💥
        """
    ]
    # Since 10 tries max, index into stages by (10 - tries_left)
    index = 10 - tries_left
    if index >= len(stages):
        index = len(stages) - 1
    print(stages[index])

#This will load the higscores in the Data.txt textfile.
def load_highscores(filename="Data.txt"):
    highscores = []
    if os.path.exists(filename):
        with open(filename, "r") as f:
            for line in f:
                parts = line.strip().split(",")
                if len(parts) == 2:
                    name, score = parts
                    try:
                        score = int(score)
                        highscores.append((name, score))
                    except ValueError:
                        pass
    return highscores

def save_highscores(highscores, filename="Data.txt"):
    with open(filename, "w") as f:
        for name, score in highscores:
            f.write(f"{name},{score}\n")

# This function adds the player highscore in the leaderboard.
def add_highscore(name, score, filename="Data.txt"):
    highscores = load_highscores(filename)
    highscores.append((name, score))
    highscores.sort(key=lambda x: x[1], reverse=True)  # Sort descending by score
    highscores = highscores[:3]  # Keep top 3
    save_highscores(highscores, filename)

# This function shows the leaderboard after the player has put down the name
def show_leaderboard():
    print("\n🏆 Highscore Leaderboard 🏆")
    highscores = load_highscores()
    print(f"highscores: {highscores}")
    if not highscores:
        print("No highscores yet, be the first!\n")
        return
    for i, (name, score) in enumerate(highscores, 1):
        print(f"{i}. {name} - {score} tries left")
    print()

# This is the function for the classic game mode.
# I learned some of this from Mohammad Nasir on this and used Youtube to boost my knowledge.
def classic_game(secret_word):
    tries = 10 # Variable for amount of tries/attempts.
    guessed_letters = set()
    correct_letters = set(secret_word)
    while tries > 0:
        print("\nSecret word: ", end="")
        display_word = [letter if letter in guessed_letters else '_' for letter in secret_word] # Replaces the letters of the word with dashes.
        print(" ".join(display_word))
        print(f"Tries left: {tries}")
        guess = input("Guess a letter: ").lower()

        if len(guess) != 1 or not guess.isalpha():
            typewriter_print("Please guess a single letter.", 0.02 ) # If the player guesses more than 1 letter, then it will ask the player to input only 1 letter.
            continue

        if guess in guessed_letters:
            typewriter_print("You already guessed that letter." , 0.02)# If the player already guessed the letter before and inputs the same letter, it will tell the player to input a different letter.
            continue

        guessed_letters.add(guess)

        if guess in correct_letters:
            typewriter_print("✅Good guess!")
            if correct_letters.issubset(guessed_letters):
                typewriter_print(f"\n🎉 Congratulations! You guessed the word: {secret_word}")
                typewriter_print(f"You had {tries} tries left.")

                # Add to highscores
                name = input("Enter your name for the leaderboard: ").strip()
                if name:
                    add_highscore(name, tries)
                else:
                    print("No name entered. Score not added.")

                # Show leaderboard
                show_leaderboard()
                break
        else:
            typewriter_print("❌Wrong guess. Try again...")
            tries -= 1

    else:
        typewriter_print(f"\n:( 💔You lost. The word was: {secret_word}\n")

# This is the function for Beat the Bomb game mode
def beat_the_bomb(secret_word):
    guessed_word = ["_"] * len(secret_word) #
    guessed_letters = [] 
    attempts = 10 # Variable for the amount of attempts.

    typewriter_print("\nBeat the Bomb mode: Guess before the bomb explodes!")
    bomb_stages(attempts)  # This initiates the bomb stages

    print("Word:", " ".join(guessed_word))

    while attempts > 0 and "_" in guessed_word:
        guess = input("Guess a letter: ").lower()

        if not guess.isalpha() or len(guess) != 1:
            typewriter_print("❗ Please enter a single letter.")# when the player inputs more than 1 letter, it will ask the player to input only one letter.
            continue

        if guess in guessed_letters:
            typewriter_print("❗ You already guessed that letter.")
            continue

        guessed_letters.append(guess)

        if guess in secret_word:
            for i in range(len(secret_word)):
                if secret_word[i] == guess:
                    guessed_word[i] = guess
            typewriter_print("✅ Good guess!") # When the player guesses the correct letter it will typewriter print out "✅Good guess!"
        else:
            attempts -= 1
            typewriter_print(f"❌ Wrong guess! Attempts left: {attempts}")
            bomb_stages(attempts)

        print("Word:", " ".join(guessed_word))

    if "_" not in guessed_word:
        typewriter_print("🎉 You defused the bomb and guessed the word!")
        typewriter_print(f"you had {attempts} attempts left")
        
        #This asks for the players name and puts the person in the leader board
        name = input("Enter your name for leaderboard:").strip()
        if name:
            add_highscore(name, attempts)
        else:
            print("No name entered, score not added")
        
        show_leaderboard() # Shows where the player sits on the leaderboard.
        
    else:
        bomb_stages(0)
        typewriter_print(f"💥 Boom! The bomb exploded. The word was: {secret_word}")
        #This message will occur when the player run's out of attempts in the beat the bomb gamemode.
    
   

# This is the main menu at the end which allows the game to run. 
def main():
    title_screen()# Shows the titlescreen function
    show_title()# Shows the title function
    show_rules()# Shows the rules function

    #This asks the player in a typewriter affect to select the gamemode.
    typewriter_print("Select Game Mode:")
    typewriter_print("1️⃣ Classic Mode🕹️")
    typewriter_print("2️⃣ Beat the Bomb🚀")

#This only allows the player to input 1 or 2 for the game selection
    mode = input("Enter 1 or 2: ").strip()
    while mode not in ("1", "2"):
        typewriter_print("❌ Invalid choice. Please enter 1 or 2.")
        mode = input("Enter 1 or 2: ").strip()

    secret_word = wordlist()# This choses the secret word from the wordlist

    if mode == "1":
        classic_game(secret_word) #If the player picks 1 then it will play the classic gamemode else it will play the beat the bomb mode.
    else:
        beat_the_bomb(secret_word)

    # This asks if player wants to play again
    play_again = input("\nWish to play again? (yes/no): ").lower()
    if play_again.startswith('y'):
        main()
    else:
        typewriter_print("Thanks for playing! Goodbye! 👋")# Goodbye message to the player upon leaving

if __name__ == "__main__":
    main()      - Keep all hashtags but make highscore leaderboard for each difficulty in this code.