Загрузка данных


(function() {
    console.log("Запуск Ультимативного Бота (Анализ + Бронебойность)...");

    const DELAY = 150; // Скорость ходов
    
    // Матрица весов: заставляем большие числа ползти в нижний правый угол
    const weights = [
        [2, 4, 8, 16],
        [32, 64, 128, 256],
        [512, 1024, 2048, 4096],
        [8192, 16384, 32768, 65536]
    ];

    // Бронебойный сбор данных: ищем все цифры на поле
    function getGrid() {
        let grid = Array(4).fill(0).map(() => Array(4).fill(0));
        const allDivs = Array.from(document.querySelectorAll('div'));
        
        // Фильтруем только те элементы, где есть число и нет вложенных элементов (чистый текст)
        const tiles = allDivs.filter(el => {
            const val = el.innerText.replace(/[^0-9]/g, '');
            return val.length > 0 && el.children.length === 0;
        });

        tiles.forEach((tile, i) => {
            if (i < 16) {
                const val = parseInt(tile.innerText.replace(/[^0-9]/g, '')) || 0;
                const r = Math.floor(i / 4);
                const c = i % 4;
                grid[r][c] = val;
            }
        });
        return grid;
    }

    // Оценка текущего состояния поля
    function evaluate(grid) {
        let score = 0;
        for (let r = 0; r < 4; r++) {
            for (let c = 0; c < 4; c++) {
                if (grid[r][c] !== 0) {
                    // Оцениваем через логарифм (важна степень двойки) умноженный на вес клетки
                    score += Math.log2(grid[r][c]) * weights[r][c];
                }
            }
        }
        return score;
    }

    // Посылка команды нажатия
    function sendKey(dir) {
        const codes = { 'U': 38, 'R': 39, 'D': 40, 'L': 37 };
        const k = 'Arrow' + (dir==='U'?'Up':dir==='R'?'Right':dir==='D'?'Down':'Left');
        const opts = { key: k, code: k, keyCode: codes[dir], which: codes[dir], bubbles: true };
        const ev = new KeyboardEvent('keydown', opts);
        window.dispatchEvent(ev);
        document.dispatchEvent(ev);
        if(document.activeElement) document.activeElement.dispatchEvent(ev);
    }

    const gameLoop = setInterval(() => {
        if (document.body.innerText.includes("Game Over")) {
            console.log("Игра окончена. Бот сделал всё, что мог.");
            return clearInterval(gameLoop);
        }

        const grid = getGrid();
        
        // Анализ: считаем баллы для основных направлений
        // Мы отдаем приоритет ВНИЗ и ВПРАВО
        const scoreDown = evaluate(grid) * 1.5;
        const scoreRight = evaluate(grid) * 1.4;
        const scoreLeft = evaluate(grid) * 0.4; // Штраф за движение влево
        
        // Считаем пустые клетки для выживаемости
        const emptyCells = grid.flat().filter(v => v === 0).length;

        if (emptyCells > 2) {
            // Если место есть — строго прижимаем к углу
            if (scoreDown >= scoreRight) sendKey('D');
            else sendKey('R');
        } else {
            // Если места мало — ищем любой выход, кроме ВВЕРХ
            const moves = ['D', 'R', 'L'];
            sendKey(moves[Math.floor(Math.random() * 3)]);
        }

    }, DELAY);

    console.log("Бот-стратег в работе. Удачи!");
})();