Chess.com Stockfish UI + Auto-Move

Enhance Chess.com with Stockfish analysis and optional auto-move functionality with a UI to control it.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey, Greasemonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Userscripts.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een gebruikersscriptbeheerder nodig.

(Ik heb al een user script manager, laat me het downloaden!)

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

(Ik heb al een beheerder - laat me doorgaan met de installatie!)

// ==UserScript==
// @name         Chess.com Stockfish UI + Auto-Move
// @namespace    http://tampermonkey.net/
// @version      0.2
// @description  Enhance Chess.com with Stockfish analysis and optional auto-move functionality with a UI to control it.
// @author       YourName
// @match        *://www.chess.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=chess.com
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    // URL for Stockfish WASM (WebAssembly) binary
    const stockfishURL = "https://cdn.jsdelivr.net/gh/nmrugg/stockfish.wasm/stockfish.wasm";

    // Create Stockfish Worker
    let stockfish = new Worker(stockfishURL);
    let isAutoMoveEnabled = false;
    let lastAnalyzedPosition = "";

    // Add a basic user interface (UI)
    const uiContainer = document.createElement("div");
    uiContainer.id = "stockfish-ui";
    uiContainer.style.position = "fixed";
    uiContainer.style.bottom = "20px";
    uiContainer.style.right = "20px";
    uiContainer.style.backgroundColor = "white";
    uiContainer.style.border = "1px solid black";
    uiContainer.style.borderRadius = "8px";
    uiContainer.style.padding = "10px";
    uiContainer.style.zIndex = "9999";
    uiContainer.style.boxShadow = "0 4px 6px rgba(0, 0, 0, 0.1)";
    uiContainer.innerHTML = `
        <h4>Stockfish UI</h4>
        <button id="analyze-btn">Analyze Position</button><br><br>
        <label>
            <input type="checkbox" id="auto-move-toggle">
            Enable Auto-Move
        </label>
        <p id="best-move-display" style="margin-top: 10px;">Best Move: (pending)</p>
    `;
    document.body.appendChild(uiContainer);

    // Get UI elements
    const analyzeButton = document.getElementById("analyze-btn");
    const autoMoveToggle = document.getElementById("auto-move-toggle");
    const bestMoveDisplay = document.getElementById("best-move-display");

    // Setup Stockfish interaction
    stockfish.onmessage = function (event) {
        const message = event.data;

        if (message.startsWith("bestmove")) {
            const move = message.split(" ")[1];
            console.log("Best move:", move);

            // Display the best move in the UI
            bestMoveDisplay.textContent = `Best Move: ${move}`;

            // If auto-move is enabled, execute the move
            if (isAutoMoveEnabled) {
                automove(move);
            }
        }
    };

    // Analyze the current board position
    function analyzePosition() {
        const fen = getFEN();
        if (!fen) {
            alert("Could not detect the board state (FEN). Ensure you're on an active game!");
            return;
        }

        if (fen === lastAnalyzedPosition) {
            console.log("Position has not changed, skipping analysis.");
            return;
        }

        lastAnalyzedPosition = fen;
        console.log(`Analyzing FEN: ${fen}`);

        stockfish.postMessage(`position fen ${fen}`);
        stockfish.postMessage("go depth 20");
    }

    // Fetch the current FEN (board position) from Chess.com
    function getFEN() {
        // Locate the FEN element from the HTML structure
        const fenContainer = document.querySelector('chess-board');
        const fen = fenContainer ? fenContainer.getAttribute('data-fen') : null;
        return fen;
    }

    // Simulate the move on the chessboard in Chess.com
    function automove(move) {
        console.log(`Attempting to auto-move: ${move}`);
        const fromSquare = move.slice(0, 2); // e.g., "e2"
        const toSquare = move.slice(2, 4); // e.g., "e4"

        const fromElement = document.querySelector(`[data-square='${fromSquare}']`);
        const toElement = document.querySelector(`[data-square='${toSquare}']`);

        if (fromElement && toElement) {
            console.log("Executing move:", fromSquare, toSquare);
            fromElement.click(); // Select the piece
            toElement.click(); // Move it to the target square
        } else {
            console.error("Could not find squares for auto-move.");
        }
    }

    // Event listeners for the UI
    analyzeButton.addEventListener("click", () => {
        analyzePosition();
    });

    autoMoveToggle.addEventListener("change", (event) => {
        isAutoMoveEnabled = event.target.checked;
        console.log("Auto-Move Enabled:", isAutoMoveEnabled);
    });

    console.log("Stockfish Auto-Move UI script loaded!");
})();