[html]
<div class="game-frame" id="gameRoot" data-words="Виски, Водка, Бар, Пивас, Коньяк, Абсент">
    <div class="game-header">
        <div class="word-bank">
            <ul class="word-list" id="wordsContainer"></ul>
        </div>
    </div>

    <div class="grid-wrapper">
        <div class="wordsearch-grid" id="gridContainer"></div>
    </div>

    <div class="info-bar">
        <div class="status" id="statusMsg">Найди все слова</div>
        <div class="button-group">
            <button class="btn" id="resetBtn">Новая игра</button>
        </div>
    </div>
    <div class="legend">
        ВЫДЕЛЯЙ ТОЛЬКО СЛЕВА НАПРАВО (→) ИЛИ СВЕРХУ ВНИЗ (↓) — игра определит слово автоматически
    </div>
</div>

<script>
    // Ждём 1 секунду, чтобы обойти сломанный jQuery форума
    setTimeout(function() {
        (function() {
            var container = document.getElementById('gameRoot');
            if (!container) return;

            var TARGET_WORDS = [];
            function fetchWords() {
                var attr = container.getAttribute('data-words');
                if (attr && attr.trim()) {
                    var raw = attr.split(',').map(function(w) { return w.trim().toUpperCase(); }).filter(function(w) { return w.length >= 2; });
                    TARGET_WORDS = [];
                    var seen = {};
                    for (var i = 0; i < raw.length; i++) {
                        if (!seen[raw[i]]) {
                            seen[raw[i]] = true;
                            TARGET_WORDS.push(raw[i]);
                        }
                    }
                }
                if (TARGET_WORDS.length === 0) TARGET_WORDS = ["ЗАМОК", "КОКУЁЙ", "КОРОНА"];
            }

            var ROWS = 14;
            var COLS = 14;

            var gridData = [];
            var placedWords = [];
            var foundSet = {};
            var foundMask = [];
            var isSelecting = false;
            var selectedOrder = [];
            var selectedSet = {};
            var startCell = null;

            var gridEl = document.getElementById("gridContainer");
            var wordsListEl = document.getElementById("wordsContainer");
            var statusSpan = document.getElementById("statusMsg");
            var resetBtn = document.getElementById("resetBtn");

            function randomRussian() {
                var letters = "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ";
                return letters[Math.floor(Math.random() * letters.length)];
            }

            var RIGHT = [0, 1];
            var DOWN  = [1, 0];
            var PLACEMENT_DIRS = [RIGHT, DOWN];

            function tryPlaceWord(word, grid, rows, cols) {
                var len = word.length;
                var dirs = PLACEMENT_DIRS.slice();
                for (var i = dirs.length - 1; i > 0; i--) {
                    var j = Math.floor(Math.random() * (i + 1));
                    var temp = dirs[i]; dirs[i] = dirs[j]; dirs[j] = temp;
                }
                for (var d = 0; d < dirs.length; d++) {
                    var dir = dirs[d];
                    var dr = dir[0], dc = dir[1];
                    var startPositions = [];
                    for (var r = 0; r < rows; r++) {
                        for (var c = 0; c < cols; c++) {
                            var endRow = r + dr * (len - 1);
                            var endCol = c + dc * (len - 1);
                            if (endRow >= 0 && endRow < rows && endCol >= 0 && endCol < cols) {
                                var conflict = false;
                                for (var k = 0; k < len; k++) {
                                    var nr = r + dr * k;
                                    var nc = c + dc * k;
                                    if (grid[nr][nc] !== '' && grid[nr][nc] !== word[k]) {
                                        conflict = true;
                                        break;
                                    }
                                }
                                if (!conflict) {
                                    startPositions.push([r, c]);
                                }
                            }
                        }
                    }
                    if (startPositions.length > 0) {
                        var randPos = startPositions[Math.floor(Math.random() * startPositions.length)];
                        var startRow = randPos[0], startCol = randPos[1];
                        var positions = [];
                        for (var k = 0; k < len; k++) {
                            var nr = startRow + dr * k;
                            var nc = startCol + dc * k;
                            grid[nr][nc] = word[k];
                            positions.push([nr, nc]);
                        }
                        return { word: word, positions: positions };
                    }
                }
                return null;
            }

            function buildFreshGrid() {
                var fresh = [];
                for (var i = 0; i < ROWS; i++) {
                    fresh.push(new Array(COLS).fill(''));
                }
                var shuffledWords = TARGET_WORDS.slice();
                for (var i = shuffledWords.length - 1; i > 0; i--) {
                    var j = Math.floor(Math.random() * (i + 1));
                    var temp = shuffledWords[i]; shuffledWords[i] = shuffledWords[j]; shuffledWords[j] = temp;
                }
                var placedList = [];
                for (var w = 0; w < shuffledWords.length; w++) {
                    var word = shuffledWords[w];
                    var placedObj = tryPlaceWord(word, fresh, ROWS, COLS);
                    if (!placedObj) {
                        for (var attempt = 0; attempt < 35; attempt++) {
                            var copyGrid = fresh.map(function(row) { return row.slice(); });
                            var retry = tryPlaceWord(word, copyGrid, ROWS, COLS);
                            if (retry) {
                                for (var p = 0; p < retry.positions.length; p++) {
                                    fresh[retry.positions[p][0]][retry.positions[p][1]] = retry.word;
                                }
                                placedList.push(retry);
                                break;
                            }
                            if (attempt === 34) {
                                var forced = false;
                                for (var r = 0; r < ROWS && !forced; r++) {
                                    for (var c = 0; c <= COLS - word.length; c++) {
                                        var ok = true;
                                        for (var q = 0; q < word.length; q++) {
                                            if (fresh[r][c+q] !== '' && fresh[r][c+q] !== word[q]) { ok = false; break; }
                                        }
                                        if (ok) {
                                            var pos = [];
                                            for (var q = 0; q < word.length; q++) {
                                                fresh[r][c+q] = word[q];
                                                pos.push([r, c+q]);
                                            }
                                            placedList.push({ word: word, positions: pos });
                                            forced = true;
                                            break;
                                        }
                                    }
                                }
                                if (!forced) {
                                    for (var c = 0; c < COLS && !forced; c++) {
                                        for (var r = 0; r <= ROWS - word.length; r++) {
                                            var ok = true;
                                            for (var q = 0; q < word.length; q++) {
                                                if (fresh[r+q][c] !== '' && fresh[r+q][c] !== word[q]) { ok = false; break; }
                                            }
                                            if (ok) {
                                                var pos = [];
                                                for (var q = 0; q < word.length; q++) {
                                                    fresh[r+q][c] = word[q];
                                                    pos.push([r+q, c]);
                                                }
                                                placedList.push({ word: word, positions: pos });
                                                forced = true;
                                                break;
                                            }
                                        }
                                    }
                                }
                                if (!forced) {
                                    placedList.push({ word: word, positions: [] });
                                }
                            }
                        }
                    } else {
                        placedList.push(placedObj);
                    }
                }
                for (var i = 0; i < ROWS; i++) {
                    for (var j = 0; j < COLS; j++) {
                        if (fresh[i][j] === '') {
                            fresh[i][j] = randomRussian();
                        }
                    }
                }
                return { grid: fresh, placedWords: placedList };
            }

            function updateMask() {
                var mask = [];
                for (var i = 0; i < ROWS; i++) {
                    mask.push(new Array(COLS).fill(false));
                }
                for (var p = 0; p < placedWords.length; p++) {
                    if (foundSet[placedWords[p].word]) {
                        for (var pos = 0; pos < placedWords[p].positions.length; pos++) {
                            var r = placedWords[p].positions[pos][0];
                            var c = placedWords[p].positions[pos][1];
                            if (r >= 0 && r < ROWS && c >= 0 && c < COLS) mask[r][c] = true;
                        }
                    }
                }
                foundMask = mask;
            }

            function isValidSelection(order) {
                if (order.length <= 1) return true;
                var first = order[0].split(',').map(Number);
                var last = order[order.length-1].split(',').map(Number);
                var dr = last[0] - first[0];
                var dc = last[1] - first[1];
               
                if (dr !== 0 && dc !== 0) return false;
                if (dr === 0 && dc <= 0) return false;
                if (dc === 0 && dr <= 0) return false;
               
                for (var i = 1; i < order.length; i++) {
                    var prev = order[i-1].split(',').map(Number);
                    var curr = order[i].split(',').map(Number);
                    var stepR = curr[0] - prev[0];
                    var stepC = curr[1] - prev[1];
                    if (stepR !== 0 && stepC !== 0) return false;
                    if (dr === 0 && stepC !== 1) return false;
                    if (dc === 0 && stepR !== 1) return false;
                }
                return true;
            }

            function render() {
                if (!gridEl) return;
                gridEl.style.display = "inline-grid";
                gridEl.style.gridTemplateColumns = "repeat(" + COLS + ", minmax(0, auto))";
                gridEl.innerHTML = '';
                for (var i = 0; i < ROWS; i++) {
                    for (var j = 0; j < COLS; j++) {
                        var cell = document.createElement('div');
                        cell.className = 'cell';
                        if (foundMask[i][j]) cell.classList.add('cell--found');
                        var key = i + "," + j;
                        if (selectedSet[key]) cell.classList.add('cell--selected');
                        cell.textContent = gridData[i][j];
                        cell.setAttribute('data-row', i);
                        cell.setAttribute('data-col', j);
                       
                        cell.addEventListener('mousedown', (function(i, j) {
                            return function(e) {
                                e.preventDefault();
                                startSelection(i, j);
                            };
                        })(i, j));
                        cell.addEventListener('mouseenter', (function(i, j) {
                            return function() {
                                if (isSelecting && startCell) addToSelection(i, j);
                            };
                        })(i, j));
                        cell.addEventListener('mouseup', endSelection);
                       
                        cell.addEventListener('touchstart', (function(i, j) {
                            return function(e) {
                                e.preventDefault();
                                startSelection(i, j);
                            };
                        })(i, j));
                        cell.addEventListener('touchmove', function(e) {
                            e.preventDefault();
                            if (!isSelecting) return;
                            var touch = e.touches[0];
                            var elem = document.elementFromPoint(touch.clientX, touch.clientY);
                            if (elem && elem.classList && elem.classList.contains('cell')) {
                                var r = parseInt(elem.getAttribute('data-row'));
                                var c = parseInt(elem.getAttribute('data-col'));
                                if (!isNaN(r)) addToSelection(r, c);
                            }
                        });
                        cell.addEventListener('touchend', function(e) {
                            e.preventDefault();
                            endSelection();
                        });
                       
                        gridEl.appendChild(cell);
                    }
                }
            }

            function startSelection(row, col) {
                isSelecting = true;
                selectedOrder = [];
                selectedSet = {};
                startCell = [row, col];
                addCell(row, col);
                render();
            }

            function addToSelection(row, col) {
                if (!startCell) return;
                var newKey = row + "," + col;
                if (selectedSet[newKey]) return;
               
                if (selectedOrder.length === 0) {
                    addCell(row, col);
                    render();
                    return;
                }
               
                var sR = startCell[0], sC = startCell[1];
                var drCandidate = Math.sign(row - sR);
                var dcCandidate = Math.sign(col - sC);
               
                if (!(drCandidate === 0 && dcCandidate === 1) && !(drCandidate === 1 && dcCandidate === 0)) {
                    return;
                }
               
                var lastKey = selectedOrder[selectedOrder.length - 1];
                var parts = lastKey.split(',');
                var lR = parseInt(parts[0]), lC = parseInt(parts[1]);
                var expectedRow = lR + drCandidate;
                var expectedCol = lC + dcCandidate;
               
                if (expectedRow === row && expectedCol === col) {
                    addCell(row, col);
                    render();
                    return;
                }
               
                var backRow = lR - drCandidate;
                var backCol = lC - dcCandidate;
                if (backRow === row && backCol === col && selectedOrder.length > 1) {
                    var removed = selectedOrder.pop();
                    delete selectedSet[removed];
                    render();
                    return;
                }
            }
           
            function addCell(row, col) {
                var key = row + "," + col;
                if (!selectedSet[key]) {
                    selectedOrder.push(key);
                    selectedSet[key] = true;
                }
            }

            function endSelection() {
                if (!isSelecting) return;
                isSelecting = false;
               
                if (selectedOrder.length === 0) {
                    startCell = null;
                    return;
                }
               
                if (!isValidSelection(selectedOrder)) {
                    statusSpan.innerText = "Разрешено выделять только вправо (→) или вниз (↓)";
                    setTimeout(function() { updateStatusMsg(); }, 1300);
                    clearVisual();
                    startCell = null;
                    return;
                }
               
                var selectedWord = getSelectedWord();
                if (selectedWord && !foundSet[selectedWord] && TARGET_WORDS.indexOf(selectedWord) !== -1) {
                    foundSet[selectedWord] = true;
                    updateMask();
                    render();
                    updateWordListUI();
                    updateStatusMsg();
                    statusSpan.innerText = "Найдено: " + selectedWord;
                    setTimeout(function() { updateStatusMsg(); }, 1500);
                    clearVisual();
                }
                else if (selectedWord && TARGET_WORDS.indexOf(selectedWord) !== -1 && foundSet[selectedWord]) {
                    statusSpan.innerText = " \"" + selectedWord + "\" уже найдено";
                    setTimeout(function() { updateStatusMsg(); }, 1000);
                    clearVisual();
                }
                else if (selectedWord && TARGET_WORDS.indexOf(selectedWord) === -1) {
                    statusSpan.innerText = "\"" + selectedWord + "\" нет в списке";
                    setTimeout(function() { updateStatusMsg(); }, 1200);
                    clearVisual();
                }
                else {
                    clearVisual();
                }
                startCell = null;
            }
           
            function getSelectedWord() {
                if (selectedOrder.length === 0) return null;
                if (selectedOrder.length === 1) {
                    var parts = selectedOrder[0].split(',');
                    var r = parseInt(parts[0]), c = parseInt(parts[1]);
                    return gridData[r][c];
                }
                return selectedOrder.map(function(key) {
                    var parts = key.split(',');
                    var r = parseInt(parts[0]), c = parseInt(parts[1]);
                    return gridData[r][c];
                }).join('');
            }
           
            function clearVisual() {
                selectedOrder = [];
                selectedSet = {};
                startCell = null;
                render();
            }
           
            function updateWordListUI() {
                wordsListEl.innerHTML = '';
                for (var i = 0; i < TARGET_WORDS.length; i++) {
                    var w = TARGET_WORDS[i];
                    var li = document.createElement('li');
                    li.className = 'word-badge';
                    if (foundSet[w]) li.classList.add('word-badge--found');
                    li.textContent = w;
                    wordsListEl.appendChild(li);
                }
            }
           
            function updateStatusMsg() {
                var total = TARGET_WORDS.length;
                var foundCount = 0;
                for (var w in foundSet) {
                    if (foundSet.hasOwnProperty(w)) foundCount++;
                }
                if (foundCount === total) statusSpan.innerText = "Победа! Все слова найдены!";
                else statusSpan.innerText = "Найдено: " + foundCount + " / " + total;
            }
           
            function resetGame() {
                var fresh = buildFreshGrid();
                gridData = fresh.grid;
                placedWords = fresh.placedWords;
                foundSet = {};
                updateMask();
                clearVisual();
                updateWordListUI();
                updateStatusMsg();
            }
           
            function init() {
                fetchWords();
                if (TARGET_WORDS.length === 0) TARGET_WORDS = ["ЗАМОК", "КОКУЁЙ", "КОРОНА"];
                resetGame();
                resetBtn.addEventListener('click', resetGame);
                window.addEventListener('mouseup', function() {
                    if (isSelecting) endSelection();
                });
            }
           
            init();
        })();
    }, 1000); // Задержка 1 секунда
</script>

[/html]