Further enhance the GUI and add some fixes and optimizations:

```
import g4f
from g4f.client import Client
import secrets
import string
import hashlib
import base64
import os
import re
import pygame
import sys
import time
from pygame.locals import QUIT, KEYDOWN, K_RETURN
import math
import asyncio
import threading
import queue

# ----------------- Configuration Constants -----------------
# Set a unique salt for hashing (In production, keep this secure and do not hardcode)
SALT = os.getenv('PASSWORD_SALT', 'a_unique_salt_value')  # Ideally, set this in environment variables

# Timer settings
TIME_LIMIT_SECONDS = 300  # 5 minutes

# Pygame Settings
FPS = 60  # Increased FPS for smoother visuals
FONT_NAME = pygame.font.match_font('arial')  # Use a standard font

# Pygame Colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (220, 20, 60)
GREEN = (34, 139, 34)
GRAY = (200, 200, 200)
LIGHT_GRAY = (230, 230, 230)
BLUE = (65, 105, 225)

# Dictionary import for comprehensive word checks
try:
    from english_words import english_words_set
except ImportError:
    # Fallback minimal dictionary
    english_words_set = {'password', 'admin', 'user', 'login', 'secret', 'welcome', 'qwerty', 'abc123'}

# -----------------------------------------------------------

client = Client(provider=g4f.Provider.Blackbox)

class SecurePasswordGenerator:
    def __init__(self, length=20):
        self.length = length
        self.password = self.generate_secure_password()

    def generate_secure_password(self):
        while True:
            # Define character pools
            lowercase = string.ascii_lowercase
            uppercase = string.ascii_uppercase
            digits = string.digits
            special = '!@#$%^&*()-_=+[]{}|;:,.<>?'

            # Ensure at least one character from each pool
            password = [
                secrets.choice(lowercase),
                secrets.choice(uppercase),
                secrets.choice(digits),
                secrets.choice(special)
            ]

            # Fill the rest of the password length with a random mix
            if self.length < 4:
                raise ValueError("Password length must be at least 4 characters.")
            while len(password) < self.length:
                pool = lowercase + uppercase + digits + special
                password.append(secrets.choice(pool))

            # Shuffle to prevent predictable sequences
            secrets.SystemRandom().shuffle(password)
            password_str = ''.join(password)

            # Enforce additional security rules
            if self.validate_password(password_str):
                return password_str

    @staticmethod
    def validate_password(password):
        # Enhanced security rules:
        # 1. Length check
        if len(password) < 20:
            return False
        # 2. Character type checks
        if not re.search(r'[a-z]', password):
            return False
        if not re.search(r'[A-Z]', password):
            return False
        if not re.search(r'\d', password):
            return False
        if not re.search(r'[!@#$%^&*()\-_+=\[\]{}|;:,.<>?]', password):
            return False
        # 3. No sequential characters
        if SecurePasswordGenerator.has_sequential_chars(password):
            return False
        # 4. No repeated substrings
        if re.search(r'(..+?)\1', password):
            return False
        # 5. No dictionary words (comprehensive check)
        if SecurePasswordGenerator.contains_dictionary_word(password):
            return False
        # 6. High entropy
        if SecurePasswordGenerator.calculate_entropy(password) < 80:  # Increased entropy threshold
            return False
        return True

    @staticmethod
    def has_sequential_chars(password):
        for i in range(len(password) - 3):
            # Check for ascending or descending sequences of 3
            seq = password[i:i+3]
            if all(ord(seq[j]) + 1 == ord(seq[j+1]) for j in range(len(seq)-1)) or \
               all(ord(seq[j]) - 1 == ord(seq[j+1]) for j in range(len(seq)-1)):
                return True
        return False

    @staticmethod
    def contains_dictionary_word(password):
        password_lower = password.lower()
        # Check for any dictionary word of length 4 or more
        for word in english_words_set:
            if len(word) >= 4 and word in password_lower:
                return True
        return False

    @staticmethod
    def calculate_entropy(password):
        pool = 0
        if re.search(r'[a-z]', password):
            pool += 26
        if re.search(r'[A-Z]', password):
            pool += 26
        if re.search(r'\d', password):
            pool += 10
        if re.search(r'[!@#$%^&*()\-_+=\[\]{}|;:,.<>?]', password):
            pool += 32  # Number of special characters used
        entropy = len(password) * math.log2(pool) if pool else 0
        return entropy

    def hash_password(self):
        # Hash the password with SHA-256 and a unique salt
        hasher = hashlib.sha256()
        hasher.update(SALT.encode('utf-8') + self.password.encode('utf-8'))
        return hasher.hexdigest()

class AIHintThread(threading.Thread):
    def __init__(self, input_queue, output_queue):
        super().__init__()
        self.input_queue = input_queue
        self.output_queue = output_queue
        self.daemon = True  # Daemonize thread

    def run(self):
        while True:
            user_prompt = self.input_queue.get()
            if user_prompt is None:
                break  # Exit signal
            hint = self.generate_hint(user_prompt)
            self.output_queue.put(hint)

    def generate_hint(self, prompt):
        try:
            response = client.chat.completions.create(
                messages=[{"role": "user", "content": prompt}],
                model="gpt-4",
            )
            return response.choices[0].message.content
        except Exception as e:
            return f"Error getting AI hint: {e}"

class HellPasswordGame:
    def __init__(self):
        self.client = Client(provider=g4f.Provider.Bing)
        self.password_generator = SecurePasswordGenerator(length=20)
        self.secure_password_hash = self.password_generator.hash_password()
        self.secure_password = self.password_generator.password  # Store for verification; remove in production
        self.attempts = 0
        self.max_attempts = 10
        self.hint_cost = 2  # Each hint costs 2 attempts
        self.start_time = time.time()
        self.time_limit = TIME_LIMIT_SECONDS

        # Initialize Pygame
        pygame.init()

        # Dynamic Resolution Handling
        infoObject = pygame.display.Info()
        self.screen_width = min(800, infoObject.current_w - 100)  # Limit max size
        self.screen_height = min(600, infoObject.current_h - 100)
        self.screen = pygame.display.set_mode((self.screen_width, self.screen_height), pygame.RESIZABLE)
        pygame.display.set_caption('Hell Password Game')

        self.clock = pygame.time.Clock()
        self.font = pygame.font.Font(FONT_NAME, 24)
        self.small_font = pygame.font.Font(FONT_NAME, 18)
        self.input_box_width = int(self.screen_width * 0.9)
        self.input_box_height = 40
        self.input_box = pygame.Rect(
            (self.screen_width - self.input_box_width) // 2,
            self.screen_height - self.input_box_height - 50,
            self.input_box_width,
            self.input_box_height
        )

        self.active = False
        self.color_inactive = GRAY
        self.color_active = GREEN
        self.color = self.color_inactive
        self.text = ''
        self.done = False
        self.messages = []
        self.message_timer = 0  # Timer for message display

        # AI Hint Handling
        self.input_queue = queue.Queue()
        self.output_queue = queue.Queue()
        self.ai_hint_thread = AIHintThread(self.input_queue, self.output_queue)
        self.ai_hint_thread.start()

        # Load Background Image or Set Color
        self.background_color = LIGHT_GRAY

    def check_password(self, guess):
        # Hash the guess and compare with stored hash
        guess_hash = hashlib.sha256(SALT.encode('utf-8') + guess.encode('utf-8')).hexdigest()
        return guess_hash == self.secure_password_hash

    def get_numerical_breakdown(self):
        # Secure numerical breakdown using Base64 encoding of the SHA-256 hash
        hashed_pw = hashlib.sha256(self.secure_password.encode('utf-8')).digest()
        numerical_breakdown = base64.b64encode(hashed_pw).decode('utf-8')
        return numerical_breakdown

    def get_password_split(self):
        return ' '.join(self.secure_password[i:i+4] for i in range(0, len(self.secure_password), 4))

    def get_cryptocode_encryption(self):
        return base64.b64encode(self.secure_password.encode()).decode()

    def get_ai_hint(self):
        prompt = "Provide a cryptic hint to guess a complex password without revealing any characters or patterns."
        self.input_queue.put(prompt)
        try:
            # Wait for AI to respond with a timeout to prevent blocking
            hint = self.output_queue.get(timeout=10)
            return hint
        except queue.Empty:
            return "Unable to retrieve hint at this time."

    def render_text(self, text, pos, color=BLACK, center=False, font=None):
        if not font:
            font = self.font
        rendered_text = font.render(text, True, color)
        text_rect = rendered_text.get_rect()
        if center:
            text_rect.center = pos
        else:
            text_rect.topleft = pos
        self.screen.blit(rendered_text, text_rect)

    def play(self):
        # Game Instructions
        instructions = [
            "Welcome to the Hell Password Game!",
            f"You have {self.max_attempts} attempts and {self.time_limit // 60} minutes to guess the secure password.",
            "Type your guess in the input box below and press Enter.",
            "Type 'hint' for a costly hint, or 'help' for additional information.",
        ]

        # Pre-render static instructions to increase performance
        rendered_instructions = [self.font.render(line, True, BLACK) for line in instructions]

        # Main Game Loop
        while not self.done:
            for event in pygame.event.get():
                if event.type == QUIT:
                    self.quit_game()
                elif event.type == pygame.VIDEORESIZE:
                    self.handle_window_resize(event.w, event.h)
                elif event.type == pygame.MOUSEBUTTONDOWN:
                    # If the user clicked on the input_box rect.
                    if self.input_box.collidepoint(event.pos):
                        self.active = True
                        self.color = self.color_active
                    else:
                        self.active = False
                        self.color = self.color_inactive
                elif event.type == KEYDOWN:
                    if self.active:
                        if event.key == K_RETURN:
                            user_input = self.text.strip()
                            self.text = ''
                            self.handle_user_input(user_input)
                        elif event.key == pygame.K_BACKSPACE:
                            self.text = self.text[:-1]
                        else:
                            if len(self.text) < 50:  # Limit input length
                                self.text += event.unicode

            # Calculate remaining time
            elapsed_time = time.time() - self.start_time
            remaining_time = max(0, self.time_limit - int(elapsed_time))

            # Dynamic Time Allocation based on attempts
            # Example: Decrease time left based on attempts
            dynamic_time_modifier = self.attempts * 2  # 2 seconds penalty per attempt
            adjusted_remaining_time = max(0, remaining_time - dynamic_time_modifier)

            # Check for timeout
            if adjusted_remaining_time <= 0 and not self.done:
                self.display_message("Time's up! You lost!", RED)
                # Optionally, display only the hashed password
                self.display_message(f"Password Hash: {self.secure_password_hash}", BLACK)
                self.done = True

            # Clear the screen
            self.screen.fill(self.background_color)

            # Render instructions
            for idx, rendered_line in enumerate(rendered_instructions):
                self.screen.blit(rendered_line, (50, 50 + idx * 30))

            # Render timer
            minutes = adjusted_remaining_time // 60
            seconds = adjusted_remaining_time % 60
            timer_text = f"Time Remaining: {minutes:02}:{seconds:02}"
            timer_color = RED if adjusted_remaining_time < 60 else BLACK
            self.render_text(timer_text, (self.screen_width - 250, 20), timer_color)

            # Render attempts
            attempts_text = f"Attempts: {self.attempts}/{self.max_attempts}"
            self.render_text(attempts_text, (50, 200), BLACK)

            # Render messages
            if self.messages and time.time() < self.message_timer:
                for idx, msg in enumerate(self.messages):
                    # Determine color based on message content
                    msg_color = GREEN if "Congratulations" in msg or "Hint" in msg else RED
                    self.render_text(msg, (50, 250 + idx * 30), msg_color)
            elif self.messages:
                self.messages = []  # Clear messages after timer

            # Render input box
            pygame.draw.rect(self.screen, self.color, self.input_box, 2)
            self.render_text(self.text, (self.input_box.x + 5, self.input_box.y + 5), BLACK)
            self.render_text("Your Guess: ", (self.input_box.x - 120, self.input_box.y + 5), BLACK)

            # Render Advanced Timer (Analog Clock)
            self.draw_analog_clock((self.screen_width - 150, 100), 50, adjusted_remaining_time)

            # Render Progress Bar
            self.draw_progress_bar((50, self.screen_height - 100), self.screen_width - 100, 20, adjusted_remaining_time)

            # Update the display
            pygame.display.flip()
            self.clock.tick(FPS)  # Maintain high FPS for no lag

        # Wait before quitting to show final messages
        pygame.time.wait(3000)
        pygame.quit()
        sys.exit()

    def handle_window_resize(self, width, height):
        # Update screen size
        self.screen_width = max(800, width)
        self.screen_height = max(600, height)
        self.screen = pygame.display.set_mode((self.screen_width, self.screen_height), pygame.RESIZABLE)

        # Update input box position
        self.input_box_width = int(self.screen_width * 0.9)
        self.input_box_height = 40
        self.input_box = pygame.Rect(
            (self.screen_width - self.input_box_width) // 2,
            self.screen_height - self.input_box_height - 50,
            self.input_box_width,
            self.input_box_height
        )

    def handle_user_input(self, user_input):
        if self.done:
            return

        if user_input.lower() == 'exit':
            self.quit_game()

        elif user_input.lower() == 'hint':
            if self.attempts + self.hint_cost <= self.max_attempts:
                self.attempts += self.hint_cost
                hint = self.get_ai_hint()
                self.display_message(f"AI Hint (cost: {self.hint_cost} attempts): {hint}", GREEN)
            else:
                self.display_message("Not enough attempts left for a hint!", RED)
            return

        elif user_input.lower() == 'help':
            help_info = (
                f"Numerical Breakdown: {self.get_numerical_breakdown()} | "
                f"Password Split: {self.get_password_split()} | "
                f"Encrypted Form: {self.get_cryptocode_encryption()} | "
                "Password requirements: 20+ characters, mix of lowercase, uppercase, digits, and special characters with no sequential or repeated patterns."
            )
            self.display_message(help_info, BLACK)
            return

        # Validate input
        if not isinstance(user_input, str) or not user_input:
            self.display_message("Invalid input. Please enter a valid password guess.", RED)
            return

        self.attempts += 1

        if self.check_password(user_input):
            self.display_message(f"Congratulations! You've cracked the password in {self.attempts} attempts!", GREEN)
            self.done = True
            return

        if self.attempts >= self.max_attempts:
            self.display_message("Incorrect password.\nYou've used all your attempts. Game Over!", RED)
            self.display_message(f"Password Hash: {self.secure_password_hash}", BLACK)
            self.done = True
            return

        self.display_message("Incorrect password. Try again.", RED)

    def display_message(self, message, color):
        # Split message into lines if too long
        lines = self.wrap_text(message, 60)
        self.messages = lines
        self.message_timer = time.time() + 3  # Display messages for 3 seconds

    def wrap_text(self, text, max_chars):
        words = text.split(' ')
        lines = []
        current_line = ""
        for word in words:
            if len(current_line) + len(word) + 1 <= max_chars:
                current_line += " " + word if current_line else word
            else:
                lines.append(current_line)
                current_line = word
        if current_line:
            lines.append(current_line)
        return lines

    def quit_game(self):
        # Stop AI thread
        self.input_queue.put(None)
        self.ai_hint_thread.join(timeout=1)
        pygame.quit()
        sys.exit()

    def draw_analog_clock(self, center, radius, remaining_time):
        """Draw an analog clock showing the remaining time."""
        # Calculate angle for remaining time
        total_seconds = TIME_LIMIT_SECONDS - (time.time() - self.start_time) + self.attempts * 2
        total_seconds = max(0, total_seconds)
        angle = (360 * (total_seconds / TIME_LIMIT_SECONDS)) % 360

        # Draw clock face
        pygame.draw.circle(self.screen, BLACK, center, radius, 2)
        pygame.draw.circle(self.screen, LIGHT_GRAY, center, radius - 5)

        # Draw clock ticks
        for i in range(60):
            tick_length = 5 if i % 5 != 0 else 10
            tick_color = BLACK if i % 5 == 0 else GRAY
            tick_start = (
                center[0] + (radius - 5) * math.cos(math.radians(i * 6 - 90)),
                center[1] + (radius - 5) * math.sin(math.radians(i * 6 - 90))
            )
            tick_end = (
                center[0] + (radius - 5 - tick_length) * math.cos(math.radians(i * 6 - 90)),
                center[1] + (radius - 5 - tick_length) * math.sin(math.radians(i * 6 - 90))
            )
            pygame.draw.line(self.screen, tick_color, tick_start, tick_end, 1)

        # Calculate hand positions
        hand_angle = math.radians(angle - 90)
        hand_length = radius - 10
        hand_end = (
            center[0] + hand_length * math.cos(hand_angle),
            center[1] + hand_length * math.sin(hand_angle)
        )

        # Draw hand
        pygame.draw.line(self.screen, RED, center, hand_end, 3)

    def draw_progress_bar(self, position, width, height, remaining_time):
        """Draw a progress bar representing the remaining time."""
        # Calculate progress
        progress = remaining_time / TIME_LIMIT_SECONDS
        progress_width = int(width * progress)

        # Draw background
        pygame.draw.rect(self.screen, GRAY, (*position, width, height))
        # Draw progress
        pygame.draw.rect(self.screen, GREEN, (*position, progress_width, height))
        # Draw border
        pygame.draw.rect(self.screen, BLACK, (*position, width, height), 2)

        # Add progress text
        progress_text = f"Time Progress: {int((1 - progress) * 100)}%"
        self.render_text(progress_text, (position[0] + width // 2, position[1] + height // 2 - 10), BLACK, center=True, font=self.small_font)

if __name__ == "__main__":
    try:
        game = HellPasswordGame()
        game.play()
    except Exception as e:
        print(f"An unexpected error occurred: {e}")
        pygame.quit()
        sys.exit()