Гид по технологиям

Как создать клон Wordle на JavaScript

7 min read JavaScript Обновлено 19 Dec 2025
Клон Wordle на JavaScript — руководство
Клон Wordle на JavaScript — руководство

Короткое описание и цель

Wordle — простая словесная игра, где игрок отгадывает секретное пятибуквенное слово за шесть попыток. Цель этого материала — помочь начинающим JavaScript-разработчикам понять механику игры и реализовать рабочую версию с понятной архитектурой, тест-кейсами и рекомендациями по улучшению.

Важно: этот материал сосредоточен на учебной реализации. Он не копирует оригинальный сайт Wordle, а объясняет принцип и даёт практический пример реализации.

Основные идеи игры

  • Секретное слово состоит из пяти букв. Игроку даётся шесть попыток.
  • После каждой попытки буквы получают цветовую подсветку: зелёный — буква на правильной позиции, жёлтый — буква есть в слове, но в другой позиции, серый — буквы нет в слове.
  • В интерфейсе есть виртуальная клавиатура, кнопки перезапуска и показа ответа, уведомления для пользователя.

Что вам потребуется

  • Node.js (рекомендуется актуальная стабильная версия)
  • Yarn установлен локально (можно заменить на npm с соответствующими командами)
  • Редактор кода (VS Code или другой)
  • Доступ в Интернет для загрузки слов с внешнего API (в примере используется Random Word API)

Женщина за компьютером с наложенной иллюстрацией Wordle

Быстрый старт: настройка проекта

  1. Создайте проект через Vite (в терминале):
yarn create vite

Выберите framework: Vanilla, вариант: JavaScript.

  1. Установите зависимости:
yarn
  1. Запустите dev-сервер:
yarn dev

Если вы предпочитаете npm, используйте аналогичные команды npm init vite, npm install и npm run dev.

Структура проекта и начальная разметка

Откройте проект в редакторе, очистите файл main.js и убедитесь, что структура папок похожа на изображение ниже.

Пояснение к правилам Wordle

Замените содержимое index.html на этот шаблон:





  
  
  
  JS Wordle



  

Wordle Clone

Please wait. The Game is loading...

Стили возьмите из репозитория проекта: скопируйте файл style.css и поместите его в корень проекта.

Установите Toastify для уведомлений:

yarn add toastify -S

Подключите стили и Toastify в main.js:

import "./style.css"
import Toastify from 'toastify-js'

Инициализация DOM-элементов и переменных

Определите переменные для упрощённого доступа к элементам DOM и клавишам:

let board = document.querySelector("#board");
let message = document.querySelector("#message");
let keys = "QWERTYUIOPASDFGHJKLZXCVBNM".split("");
let restartBtn = document.querySelector("#restart-btn");
let showBtn = document.querySelector("#show-btn");
showBtn.setAttribute("disabled", "true");
keys.push("Backspace");
let keyboard = document.querySelector(".keyboard");

Локализуйте метки интерфейса, если необходимо (например, заменить “Replay” на “Перезапустить”).

Подготовка игрового поля

Определите структуру данных для поля — массив из шести строк по пять ячеек и индексы текущей строки и ячейки:

let boardContent = [
    [0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0],
];
let currentRow = 0;
let currentBox = 0;
let secretWord;

Отрисуйте DOM-структуру для игрового поля (6 строк по 5 ячеек):

for (let i = 0; i <= 5; i++) {
    let row = document.createElement('div')
    for (let y = 0; y <= 4; y++) {
        let box = document.createElement('span');
        row.appendChild(box);
        row.className = `row-${i + 1}`
    }
    board.appendChild(row);
}

Создание виртуальной клавиатуры и событие клика

Генерация кнопок клавиатуры и привязка обработчиков:

keys.forEach(entry => {
    let key = document.createElement("button");
    if (entry === "*") {
        key.innerText = "Backspace";
    } else {
        key.innerText = entry;
    }
    key.className = "key";
    key.setAttribute("data-key", entry.toUpperCase());
    key.addEventListener("click", () => {
        insertKey(entry.toUpperCase())
        setTimeout(() => {
            document.querySelector(`button[data-key=${entry.toUpperCase()}]`).blur();
        }, 250)
    })
    keyboard.append(key);
})

Совет: при создании кнопок можно заменить текст кнопки Backspace на иконку, но тогда лучше сохранить data-key=”Backspace” для совместимости с логикой.

Получение случайного слова через API

При загрузке игры нужно получить новое пятибуквенное слово и сохранить его в secretWord:

function getNewWord() {
    async function fetchWord() {
        try {
            const response = await fetch("https://random-word-api.herokuapp.com/word?length=5");
            if (response.ok) {
                const data = await response.json();
                return data;
            } else {
                throw new Error("Something went wrong!")
            }
        } catch (error) {
            message.innerText = `Something went wrong. \n${error}\nCheck your internet connection.`;
        }
    }
    fetchWord().then(data => {
        secretWord = data[0].toUpperCase();
        main();
    })

}

Опции улучшения: вместо публичного API можно хранить локальный список слов и выбирать из него — это удобно для оффлайн-режима и для контроля над словарём.

Главная функция и подготовка интерфейса

Создайте функцию main, которая подготовит список всех ячеек и добавит обработчики событий:

function main(){

}

Примеры шагов внутри main:

  • собрать список rows и boxes
  • добавить класс empty всем ячейкам
  • скрыть сообщение о загрузке
  • добавить слушатель keyup на window для обработки аппаратной клавиатуры
  • привязать клики к showBtn и restartBtn

Фрагмент кода для инициализации ячеек и скрытия сообщения:

    rows.forEach(row => [...row.children].forEach(child => boxes.push(child)))
    boxes.forEach((box) => {
        box.classList.add("empty");
    })
    message.style.display = "none";

Добавьте обработчик аппаратной клавиатуры, который симулирует клик по соответствующей кнопке виртуальной клавиатуры:

    window.addEventListener('keyup', (e) => {
        if (isValidCharacter(e.key)) {
            document.querySelector(`button[data-key=${e.key.toUpperCase()}]`).focus();
            document.querySelector(`button[data-key=${e.key.toUpperCase()}]`).click();
            setTimeout(() => {
                document.querySelector(`button[data-key=${e.key.toUpperCase()}]`).blur();
            }, 250)
        }
    })

Обработчики кнопок:

    showBtn.addEventListener('click', () => {
        Toastify({
            text: `Alright fine! the answer is ${secretWord}`,
            duration: 2500,
            className: "alert",
        }).showToast();
    })

    restartBtn.addEventListener('click', () => {
        location.reload();
    })
    function isValidCharacter(val) {
        return (val.match(/^[a-zA-Z]+$/) && (val.length === 1 || val === "Backspace"))
    }

Отрисовка содержимого ячейки

Функция renderBox оформляет букву в указанной ячейке:

function renderBox(row, box, data) {
    [...document.querySelector(`.row-${row}`).children][box].innerText = data;
}

Обработка ввода с клавиатуры

Функция insertKey отвечает за удаление и добавление букв, переход между строками и запуск оценки строки:

function insertKey(key) {
    if (key === "Backspace".toUpperCase() && currentRow < boardContent.length) {
        boardContent[currentRow][currentBox] = 0;
        if (currentBox !== 0) {
            currentBox--;
            renderBox(currentRow + 1, currentBox, "");
        }
    } else {
        if (currentRow < boardContent.length) {
            boardContent[currentRow][currentBox] = key;
            renderBox(currentRow + 1, currentBox, key);
            currentBox++;
        }
        if (currentRow < boardContent.length && boardContent[currentRow][currentBox] !== 0) {
            evaluate(currentRow, key);
            currentBox = 0;
            currentRow++;
        }
    }
}

Совет: можно улучшить логику так, чтобы оценка запускалась только при нажатии Enter и только если строка заполнена, а Backspace работал обычным образом.

Оценка попытки игрока

Создайте функцию evaluate, которая принимает номер строки и вычисляет цвета для каждой буквы:

function evaluate(row){

}

Показ кнопки Show Answer после четырёх попыток:

if (currentRow === 4) {
    showBtn.removeAttribute('disabled')
}

Подготовка guess и answer:

let guess = boardContent[row].join('').toUpperCase();
let answer = secretWord.split("");

Алгоритм подсветки с учётом повторяющихся букв:

let colors = guess
    .split("")
    .map((letter, idx) => letter == answer[idx] ? (answer[idx] = false) : letter)
    .map((letter, idx) =>
        letter
            ? (idx = answer.indexOf(letter)) < 0
                ? "grey"
                : (answer[idx] = "yellow")
            : "green"
);

Затем примените цвета к буквам на клавиатуре и плиткам:

function setColor(colors) {
        colors.forEach((color, index) => {
            document.querySelector(`button[data-key=${guess[index].toUpperCase()}]`).style.backgroundColor = color;
            document.querySelector(`button[data-key=${guess[index].toUpperCase()}]`).style.color= "black";
            [...document.querySelector(`.row-${row + 1}`).children][index].style.backgroundColor = color;
        })
}

После того как игрок отгадал слово или исчерпаны попытки, можно показать финальное сообщение и предложить перезапустить игру.

Финальная инициализация

Запустите загрузку нового слова:

getNewWord();

Поздравляем — базовая версия готова.

Изображение готовой игры

Альтернативные подходы и улучшения

  • Локальный словарь вместо внешнего API — надёжнее и даёт контроль над валидными словами.
  • Хранение словаря в виде JSON и выбор слов с учётом частоты употребления.
  • Поддержка многоязычности: загрузка словаря под регион (ru, en, es).
  • Добавление таймера и статистики (количество побед, среднее число ходов).
  • Анимации при подсветке плиток для улучшения UX (CSS transitions).

Когда этот подход не подходит

  • Если вам нужна масштабируемая онлайн-версия с мультиплеером — потребуется серверная часть и управление пользователями.
  • Для поддержки мобильных приложений лучше использовать гибридные или нативные решения.
  • Когда нужен строгий контроль словаря (например, для тестирования знаний) — публичное API может возвращать редкие или неподходящие слова.

Ментальные модели и эвристики

  • Модель «проверка позиций → проверка наличия»: сначала помечаем точные соответствия, затем помечаем оставшиеся совпадения, чтобы корректно обрабатывать повторяющиеся буквы.
  • Отделяйте представление (DOM) от состояния (boardContent). Все изменения сначала обновляют состояние, затем DOM.

Критерии приёмки

  • Игрок может ввести буквы и удалять их клавишей Backspace.
  • После заполнения строки запускается оценка и применяются цвета.
  • Кнопка Show Answer активируется после четырёх ходов.
  • При повторном запуске состояние сбрасывается.

Тест-кейсы и сценарии приёмки

  1. Ввод непечатного символа (например, цифры) — система игнорирует ввод.
  2. Неполная строка и Enter — оценка не запускается.
  3. Полная строка и Enter — отображаются цвета и клавиша Show Answer активируется после 4 попыток.
  4. Повторы букв в слове — подсветка учитывает количество вхождений.
  5. Клик по Show Answer — показывается верное слово в тосте.

Чек-лист для ролей

Разработчик:

  • Инициализация проекта и dev-сервер.
  • Реализация логики ввода и оценки.
  • Юнит-тесты для функции evaluate.

Тестировщик:

  • Выполнить тест-кейсы из предыдущего раздела.
  • Проверить поведение при отсутствии сети.

Дизайнер:

  • Проверить читаемость цветов на разных экранах.
  • Убедиться, что кнопки доступны для касания на мобильных устройствах.

Шаблон структуры проекта

  • index.html
  • main.js
  • style.css
  • /assets — изображения
  • /data — (опционально) локальный словарь words.json

Отладочные советы

  • Для проверки secretWord временно логируйте его в консоль или активируйте кнопку Show Answer сразу.
  • Если API недоступен, поддержите fallback на локальный список слов.
  • Используйте DevTools для отслеживания классов и стилей плиток.

Совместимость и миграция

  • Vite + Yarn подходят для быстрой разработки. При миграции на npm замените команды yarn на npm и убедитесь в корректности package.json.
  • Для продакшн-сборки используйте vite build и размещайте статические файлы на CDN или в статическом хостинге.

Безопасность и приватность

  • Игра не обрабатывает чувствительные данные. Если вы добавляете статистику или авторизацию, используйте HTTPS и защищённое хранение токенов.

Короткое объявление для соцсетей

Создал простой клон Wordle на чистом JavaScript с Vite и Toastify. Пошаговое руководство: от структуры проекта до алгоритма подсветки и тестов. Идеально для начинающих.

Социальный предпросмотр (OG)

Предлагаемые заголовок и описание для превью:

  • OG заголовок: Клон Wordle на JavaScript — пошагово
  • OG описание: Учебная реализация Wordle: установка, логика подсветки, обработка клавиатуры и тесты.

Короткая глоссарий в одну строку

  • boardContent — состояние игрового поля (6×5).
  • currentRow/currentBox — указатели текущей строки и ячейки.
  • secretWord — загаданное слово.
  • Toastify — библиотека для тост-уведомлений.

Резюме

  • Реализовать клон Wordle можно на чистом JavaScript с небольшим набором зависимостей.
  • Ключевые части: состояние поля, отрисовка DOM, обработка ввода, алгоритм подсветки с учётом повторяющихся букв.
  • Для продакшн-версии рекомендуется локальный словарь, аналитика и адаптация под мобильные устройства.

Ключевые выводы:

  • Простая версия Wordle помогает понять работу со state и DOM.
  • Алгоритм подсветки требует двух проходов для корректной обработки повторяющихся букв.
  • Рекомендуется предусмотреть fallback для API и тестовый словарь.
Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Разгон GPU в Windows 10 с ASUS GPU Tweak II
Аппаратное обеспечение

Разгон GPU в Windows 10 с ASUS GPU Tweak II

Вход в Xbox через microsoft.com/link — быстрое руководство
Руководство

Вход в Xbox через microsoft.com/link — быстрое руководство

Как скачать игры с Xbox Game Pass
Игры

Как скачать игры с Xbox Game Pass

Browser-in-the-Browser: как защититься
Безопасность

Browser-in-the-Browser: как защититься

Как получить Fortnite CourageJD Icon Skin бесплатно
Игры

Как получить Fortnite CourageJD Icon Skin бесплатно

Как отменить подписку Xbox Game Pass
Гайды

Как отменить подписку Xbox Game Pass