t pygame import sys import random
--- Настройки ---

cell_size = 60 GUESSES = 6 # Значение по умолчанию, может быть изменено пользователем FONT_SIZE = 48 FPS = 60 COLORS = { 'WHITE': (255, 255, 255), 'GRAY': (150, 150, 150), 'YELLOW': (201, 180, 88), 'GREEN': (106, 170, 100), 'BLACK': (0, 0, 0), 'EMPTY_BORDER': (220, 220, 220), 'BG_COLOR1': (245, 245, 245), 'BG_COLOR2': (200, 220, 255), 'MENU_BG': (230, 240, 255), 'DISABLED_BUTTON': (180, 180, 180) }
--- Инициализация ---

pygame.init() WIDTH, HEIGHT = 480, 700 # Стартовые значения, будут изменяться screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Wordle на русском") clock = pygame.time.Clock()
Шрифты

font = pygame.font.SysFont('Arial', FONT_SIZE) small_font = pygame.font.SysFont('Arial', 32) stat_font = pygame.font.SysFont('Arial', 24)
Чтение слов из файла

def load_words(filename='russian.txt'): word_sets = {} try: with open(filename, 'r', encoding='utf-8', errors='ignore') as file: for line in file: try: word = line.strip().lower() if word and all('а' <= c <= 'я' for c in word): length = len(word) if length not in word_sets: word_sets[length] = [] word_sets[length].append(word) except UnicodeDecodeError: continue except FileNotFoundError: print(f"Файл {filename} не найден. Используется заглушка.") word_sets = { 4: ['миря', 'глаз', 'домк', 'куст'], 5: ['мирок', 'книга', 'дерби', 'груша'], 6: ['морковь', 'победа', 'прыжок'], 7: ['комната', 'заговор', 'корабль'] } return word_sets

WORD_SETS = load_words()
Глобальные переменные

difficulty = 5 secret_word = '' user_guesses = [] current_guess = 0 active_cell = 0 stats = {"win": 0, "lose": 0} custom_mode = False custom_guesses = GUESSES
--- Функции ---

def calculate_window_size(word_length, guesses): field_width = word_length * cell_size field_height = guesses * (cell_size + 10) width = max(480, field_width + 80) height = max(700, field_height + 220) return width, height

def draw_gradient_background(): for y in range(HEIGHT): color = [ COLORS['BG_COLOR1'][i] + (COLORS['BG_COLOR2'][i] - COLORS['BG_COLOR1'][i]) * y // HEIGHT for i in range(3) ] pygame.draw.line(screen, color, (0, y), (WIDTH, y))

def show_message(text, delay=500): text_surface = font.render(text, True, COLORS['BLACK']) rect = text_surface.get_rect(center=(WIDTH // 2, HEIGHT - 50)) screen.blit(text_surface, rect) pygame.display.flip() pygame.time.delay(delay)

def draw_stats(): stat_text = f"Побед: {stats['win']} Поражений: {stats['lose']}" text = stat_font.render(stat_text, True, COLORS['BLACK']) screen.blit(text, (10, 10))

def draw_board(return_to_menu_enabled=True): draw_gradient_background() draw_stats() guesses_count = custom_guesses if custom_mode else GUESSES start_x = (WIDTH - difficulty * cell_size) // 2 start_y = 100

for row in range(guesses_count):
    for col in range(difficulty):
        x = start_x + col * cell_size
        y = start_y + row * (cell_size + 10)
        letter = ''
        color = COLORS['EMPTY_BORDER']

        if row < len(user_guesses) and col < len(user_guesses[row]):
            letter = user_guesses[row][col].upper()
            if len(user_guesses[row]) == difficulty:
                if secret_word[col] == user_guesses[row][col]:
                    color = COLORS['GREEN']
                elif user_guesses[row][col] in secret_word:
                    color = COLORS['YELLOW']
                else:
                    color = COLORS['GRAY']

        if row == current_guess and col == active_cell:
            pygame.draw.rect(screen, (120, 180, 255), (x-3, y-3, cell_size+6, cell_size+6), border_radius=10)

        pygame.draw.rect(screen, color, (x, y, cell_size, cell_size), border_radius=8)
        pygame.draw.rect(screen, COLORS['BLACK'], (x, y, cell_size, cell_size), 2, border_radius=8)

        if letter:
            text = font.render(letter, True, COLORS['BLACK'])
            rect = text.get_rect(center=(x + cell_size // 2, y + cell_size // 2))
            screen.blit(text, rect)

# Кнопка "Ввод"
enter_rect = pygame.Rect(WIDTH//2 - 60, HEIGHT - 120, 120, 50)
pygame.draw.rect(screen, (180, 220, 180), enter_rect, border_radius=12)
enter_text = small_font.render("Ввод", True, COLORS['BLACK'])
screen.blit(enter_text, (enter_rect.centerx - enter_text.get_width()//2, enter_rect.centery - enter_text.get_height()//2))

# Кнопка "Вернуться в меню"
menu_rect = pygame.Rect(WIDTH//2 - 60, HEIGHT - 60, 120, 50)
menu_color = (180, 220, 180) if return_to_menu_enabled else COLORS['DISABLED_BUTTON']
pygame.draw.rect(screen, menu_color, menu_rect, border_radius=12)
menu_text = small_font.render("Меню", True, COLORS['BLACK'])
screen.blit(menu_text, (menu_rect.centerx - menu_text.get_width()//2, menu_rect.centery - menu_text.get_height()//2))

return start_x, start_y, enter_rect, menu_rect

def show_menu(): global WIDTH, HEIGHT, screen WIDTH, HEIGHT = 480, 700 screen = pygame.display.set_mode((WIDTH, HEIGHT)) screen.fill(COLORS['MENU_BG']) title = font.render("Выберите сложность", True, COLORS['BLACK']) screen.blit(title, (WIDTH // 2 - title.get_width() // 2, 100))

buttons = []
for i, length in enumerate(range(4, 8)):
    btn_text = f"{length} букв"
    txt = small_font.render(btn_text, True, COLORS['BLACK'])
    rect = pygame.Rect(WIDTH // 2 - 75, 200 + i * 80, 150, 50)
    pygame.draw.rect(screen, COLORS['GRAY'], rect, border_radius=12)
    screen.blit(txt, (rect.centerx - txt.get_width() // 2, rect.centery - txt.get_height() // 2))
    buttons.append((rect, length))

# Кнопка для пользовательской сложности
custom_btn_text = "Своя сложность"
custom_txt = pygame.font.SysFont('Arial', 28).render(custom_btn_text, True, COLORS['BLACK'])
custom_rect = pygame.Rect(WIDTH // 2 - 100, 200 + 4 * 80, 200, 50)
pygame.draw.rect(screen, COLORS['GRAY'], custom_rect, border_radius=12)
screen.blit(custom_txt, (custom_rect.centerx - custom_txt.get_width() // 2, custom_rect.centery - custom_txt.get_height() // 2))
buttons.append((custom_rect, 'custom'))

pygame.display.flip()

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        elif event.type == pygame.MOUSEBUTTONDOWN:
            for rect, length in buttons:
                if rect.collidepoint(event.pos):
                    return length

def get_custom_difficulty(): global custom_mode, custom_guesses, difficulty, WIDTH, HEIGHT, screen custom_mode = True input_active = True word_length_input = '' guesses_input = '' current_input = 'length'

# Определяем размеры и позиции полей ввода
input_rect_length = pygame.Rect(WIDTH // 2 - 100, 240, 200, 50)
input_rect_guesses = pygame.Rect(WIDTH // 2 - 100, 340, 200, 50)

while input_active:
    screen.fill(COLORS['MENU_BG'])
    title = font.render("Введите параметры", True, COLORS['BLACK'])
    screen.blit(title, (WIDTH // 2 - title.get_width() // 2, 100))

    # Отрисовка полей ввода с рамками
    length_prompt = small_font.render("Длина слова:", True, COLORS['BLACK'])
    screen.blit(length_prompt, (WIDTH // 2 - length_prompt.get_width() // 2, 200))

    # Рамка для длины слова
    pygame.draw.rect(screen, COLORS['BLACK'], input_rect_length, 2, border_radius=8)
    if current_input == 'length':
        pygame.draw.rect(screen, (220, 230, 255), input_rect_length, 0, border_radius=8)
    length_text = small_font.render(word_length_input + ('|' if current_input == 'length' else ''), True, COLORS['BLACK'])
    screen.blit(length_text, (input_rect_length.centerx - length_text.get_width() // 2, input_rect_length.centery - length_text.get_height() // 2))

    guesses_prompt = small_font.render("Количество попыток:", True, COLORS['BLACK'])
    screen.blit(guesses_prompt, (WIDTH // 2 - guesses_prompt.get_width() // 2, 300))

    # Рамка для количества попыток
    pygame.draw.rect(screen, COLORS['BLACK'], input_rect_guesses, 2, border_radius=8)
    if current_input == 'guesses':
        pygame.draw.rect(screen, (220, 230, 255), input_rect_guesses, 0, border_radius=8)
    guesses_text = small_font.render(guesses_input + ('|' if current_input == 'guesses' else ''), True, COLORS['BLACK'])
    screen.blit(guesses_text, (input_rect_guesses.centerx - guesses_text.get_width() // 2, input_rect_guesses.centery - guesses_text.get_height() // 2))

    # Показываем текущие параметры
    if word_length_input:
        info = f"Длина слова: {word_length_input}"
        info_text = stat_font.render(info, True, COLORS['BLACK'])
        screen.blit(info_text, (WIDTH // 2 - info_text.get_width() // 2, 460))
    if guesses_input:
        info = f"Попыток: {guesses_input}"
        info_text = stat_font.render(info, True, COLORS['BLACK'])
        screen.blit(info_text, (WIDTH // 2 - info_text.get_width() // 2, 490))

    # Кнопка "Начать"
    start_btn_text = "Начать"
    start_txt = small_font.render(start_btn_text, True, COLORS['BLACK'])
    start_rect = pygame.Rect(WIDTH // 2 - 75, 400, 150, 50)
    pygame.draw.rect(screen, COLORS['GRAY'], start_rect, border_radius=12)
    screen.blit(start_txt, (start_rect.centerx - start_txt.get_width() // 2, start_rect.centery - start_txt.get_height() // 2))

    pygame.display.flip()

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        elif event.type == pygame.MOUSEBUTTONDOWN:
            # Переключение между полями ввода при клике
            if input_rect_length.collidepoint(event.pos):
                current_input = 'length'
            elif input_rect_guesses.collidepoint(event.pos):
                current_input = 'guesses'
            elif start_rect.collidepoint(event.pos) and word_length_input and guesses_input:
                try:
                    difficulty = int(word_length_input)
                    custom_guesses = int(guesses_input)
                    if difficulty in WORD_SETS and WORD_SETS[difficulty]:
                        input_active = False
                    else:
                        show_message("Нет слов такой длины!", 1000)
                        word_length_input = ''
                        guesses_input = ''
                        current_input = 'length'
                except:
                    show_message("Ошибка ввода!", 1000)
                    word_length_input = ''
                    guesses_input = ''
                    current_input = 'length'
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_TAB:
                # Переключение между полями по Tab
                current_input = 'guesses' if current_input == 'length' else 'length'
            elif event.key == pygame.K_BACKSPACE:
                if current_input == 'length' and word_length_input:
                    word_length_input = word_length_input[:-1]
                elif current_input == 'guesses' and guesses_input:
                    guesses_input = guesses_input[:-1]
            elif event.key == pygame.K_RETURN:
                if current_input == 'length' and word_length_input:
                    current_input = 'guesses'
                elif current_input == 'guesses' and guesses_input:
                    try:
                        difficulty = int(word_length_input)
                        custom_guesses = int(guesses_input)
                        if difficulty in WORD_SETS and WORD_SETS[difficulty]:
                            input_active = False
                        else:
                            show_message("Нет слов такой длины!", 1000)
                            word_length_input = ''
                            guesses_input = ''
                            current_input = 'length'
                    except:
                        show_message("Ошибка ввода!", 1000)
                        word_length_input = ''
                        guesses_input = ''
                        current_input = 'length'
            elif event.unicode.isdigit():
                if current_input == 'length':
                    word_length_input += event.unicode
                elif current_input == 'guesses':
                    guesses_input += event.unicode

WIDTH, HEIGHT = calculate_window_size(difficulty, custom_guesses)
screen = pygame.display.set_mode((WIDTH, HEIGHT))
return difficulty

def start_game(length): global difficulty, secret_word, user_guesses, current_guess, active_cell, custom_mode, custom_guesses, screen, WIDTH, HEIGHT if length == 'custom': difficulty = get_custom_difficulty() else: difficulty = length custom_mode = False custom_guesses = GUESSES WIDTH, HEIGHT = calculate_window_size(difficulty, custom_guesses if custom_mode else GUESSES) screen = pygame.display.set_mode((WIDTH, HEIGHT)) secret_word = random.choice(WORD_SETS[difficulty]) user_guesses = ['' for _ in range(custom_guesses if custom_mode else GUESSES)] current_guess = 0 active_cell = 0

def run_game(): global current_guess, active_cell running = True finished = False return_to_menu_enabled = True

while running:
    clock.tick(FPS)
    start_x, start_y, enter_rect, menu_rect = draw_board(return_to_menu_enabled)
    pygame.display.flip()

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN and not finished:
            if event.key == pygame.K_BACKSPACE:
                if user_guesses[current_guess]:
                    user_guesses[current_guess] = user_guesses[current_guess][:-1]
                    active_cell = max(0, len(user_guesses[current_guess]))
            else:
                char = event.unicode.lower()
                if char.isalpha() and 'а' <= char <= 'я':
                    if len(user_guesses[current_guess]) < difficulty:
                        user_guesses[current_guess] += char
                        active_cell = len(user_guesses[current_guess])
                        return_to_menu_enabled = False
                        if len(user_guesses[current_guess]) == difficulty:
                            pygame.time.delay(20)
                            guess = user_guesses[current_guess]
                            if guess == secret_word:
                                draw_board(return_to_menu_enabled)
                                show_message("Вы угадали!")
                                stats["win"] += 1
                                finished = True
                            else:
                                current_guess += 1
                                active_cell = 0
                                if current_guess >= (custom_guesses if custom_mode else GUESSES):
                                    draw_board(return_to_menu_enabled)
                                    show_message(f"Вы проиграли! Слово: {secret_word}")
                                    stats["lose"] += 1
                                    finished = True
        elif event.type == pygame.MOUSEBUTTONDOWN and not finished:
            mx, my = event.pos
            for row in range(custom_guesses if custom_mode else GUESSES):
                for col in range(difficulty):
                    x = start_x + col * cell_size
                    y = start_y + row * (cell_size + 10)
                    rect = pygame.Rect(x, y, cell_size, cell_size)
                    if rect.collidepoint(mx, my) and row == current_guess:
                        active_cell = col
            if enter_rect.collidepoint(mx, my):
                guess = user_guesses[current_guess]
                if len(guess) == difficulty:
                    if guess == secret_word:
                        draw_board(return_to_menu_enabled)
                        show_message("Вы угадали!")
                        stats["win"] += 1
                        finished = True
                    else:
                        current_guess += 1
                        active_cell = 0
                        if current_guess >= (custom_guesses if custom_mode else GUESSES):
                            draw_board(return_to_menu_enabled)
                            show_message(f"Вы проиграли! Слово: {secret_word}")
                            stats["lose"] += 1
                            finished = True
                else:
                    show_message("Слово слишком короткое!", 800)
            if menu_rect.collidepoint(mx, my) and return_to_menu_enabled:
                return

    if finished:
        pygame.time.delay(1000)
        return

def main(): while True: selected = show_menu() start_game(selected) run_game()

if name == "main": main() pygame.quit() sys.exit()

После проигрыша/выигрыша текст выходит за рамки окна, вместо этого сделайте отдельное окно после конца игры с информацией о раунде, добавьте туда таймер. В меню укажите количество слов в базе, добавьте таймер во время игры