Further enhance the Smart Agent algorithm. Make it generate live.

```
import pygame
import random

# Initialize Pygame
pygame.init()

# Maze dimensions
WIDTH, HEIGHT = 800, 800
ROWS, COLS = 40, 40
CELL_SIZE = WIDTH // COLS

# Colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
BLUE = (0, 0, 255)

# Set up the display
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Smart Agent Maze Generator")

class Cell:
    def __init__(self, row, col):
        self.row = row
        self.col = col
        self.walls = {'N': True, 'S': True, 'E': True, 'W': True}
        self.visited = False

    def draw(self, win):
        x = self.col * CELL_SIZE
        y = self.row * CELL_SIZE

        if self.visited:
            pygame.draw.rect(win, WHITE, (x, y, CELL_SIZE, CELL_SIZE))

        # Draw walls
        if self.walls['N']:
            pygame.draw.line(win, BLACK, (x, y), (x + CELL_SIZE, y), 2)
        if self.walls['S']:
            pygame.draw.line(win, BLACK, (x, y + CELL_SIZE), (x + CELL_SIZE, y + CELL_SIZE), 2)
        if self.walls['E']:
            pygame.draw.line(win, BLACK, (x + CELL_SIZE, y), (x + CELL_SIZE, y + CELL_SIZE), 2)
        if self.walls['W']:
            pygame.draw.line(win, BLACK, (x, y), (x, y + CELL_SIZE), 2)

def get_neighbors(cell, grid):
    neighbors = []
    directions = {'N': (-1, 0), 'S': (1, 0), 'E': (0, 1), 'W': (0, -1)}
    for direction, (dr, dc) in directions.items():
        r, c = cell.row + dr, cell.col + dc
        if 0 <= r < ROWS and 0 <= c < COLS:
            neighbor = grid[r][c]
            if not neighbor.visited:
                neighbors.append((direction, neighbor))
    return neighbors

def remove_walls(current, next_cell, direction):
    opposites = {'N': 'S', 'S': 'N', 'E': 'W', 'W': 'E'}
    current.walls[direction] = False
    next_cell.walls[opposites[direction]] = False

def smart_agent_maze():
    grid = [[Cell(r, c) for c in range(COLS)] for r in range(ROWS)]
    stack = []

    # Starting point
    current = grid[0][0]
    current.visited = True
    stack.append(current)

    while stack:
        # Find all unvisited neighbors
        neighbors = get_neighbors(current, grid)

        if neighbors:
            # Scoring directions based on number of unvisited neighbors of neighbors
            scored_neighbors = []
            for direction, neighbor in neighbors:
                score = len(get_neighbors(neighbor, grid))
                scored_neighbors.append((score, (direction, neighbor)))

            # Choose the direction with the highest score
            scored_neighbors.sort(reverse=True, key=lambda x: x[0])
            max_score = scored_neighbors[0][0]
            top_choices = [choice for choice in scored_neighbors if choice[0] == max_score]
            chosen = random.choice(top_choices)[1]

            direction, chosen_cell = chosen
            remove_walls(current, chosen_cell, direction)
            chosen_cell.visited = True
            stack.append(chosen_cell)
            current = chosen_cell
        else:
            # Backtrack
            current = stack.pop()

    return grid

def draw_maze(win, grid):
    for row in grid:
        for cell in row:
            cell.draw(win)

def main():
    run = True
    clock = pygame.time.Clock()

    grid = smart_agent_maze()

    while run:
        clock.tick(60)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False

        WIN.fill(BLACK)
        draw_maze(WIN, grid)

        # Highlight start and end
        pygame.draw.rect(WIN, GREEN, (0, 0, CELL_SIZE, CELL_SIZE))
        pygame.draw.rect(WIN, RED, ((COLS -1)*CELL_SIZE, (ROWS -1)*CELL_SIZE, CELL_SIZE, CELL_SIZE))

        pygame.display.update()

    pygame.quit()

if __name__ == "__main__":
    main()