// ==UserScript== // additional copyright/license info: //© All Rights Reserved // //Chess.com Enhanced Experience © 2024 by Akashdeep // // ==UserScript // @name Chess.com UltraX bot with Panel // @namespace Akashdeep // @version 1.0.1.1 // @description Enhances your Chess.com experience with move suggestions, UI enhancements, and customizable features. Credits to GoodtimeswithEno for the initial move highlighting and basic chess engine implementation. // @author Akashdeep // @license Chess.com Enhanced Experience © 2024 by Akashdeep, © All Rights Reserved // @match https://www.chess.com/play/* // @match https://www.chess.com/game/* // @match https://www.chess.com/puzzles/* // @match https://www.chess.com/* // @icon data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== // @grant GM_getValue // @grant GM_setValue // @grant GM_xmlhttpRequest // @grant GM_getResourceText // @grant GM_registerMenuCommand // @resource stockfish.js https://cdnjs.cloudflare.com/ajax/libs/stockfish.js/10.0.2/stockfish.js // @require https://code.jquery.com/jquery-3.6.0.min.js // @run-at document-start // @liscense MIT // @downloadURL // @updateURL // @downloadURL https://update.greasyfork.icu/scripts/531100/Chesscom%20UltraX%20bot%20with%20Panel.user.js // @updateURL https://update.greasyfork.icu/scripts/531100/Chesscom%20UltraX%20bot%20with%20Panel.meta.js // ==/UserScript== (() => { // config.js var currentVersion = "1.0.1.1"; function getRandomTacticalStrength() { const strengths = [ "fork", "pin", "skewer", "discovery", "zwischenzug", "removing-defender", "attraction" ]; return strengths[Math.floor(Math.random() * strengths.length)]; } function getRandomTacticalWeakness() { const weaknesses = [ "long-calculation", "quiet-moves", "backward-moves", "zugzwang", "prophylaxis", "piece-coordination" ]; return weaknesses[Math.floor(Math.random() * weaknesses.length)]; } // variables.js function initializeVariables() { const myVars = { autoMovePiece: false, autoRun: false, delay: 0.1, loaded: false, lastValue: 11, playStyle: { aggressive: Math.random() * 0.5 + 0.3, // 0.3-0.8 tendency for aggressive moves defensive: Math.random() * 0.5 + 0.3, // 0.3-0.8 tendency for defensive moves tactical: Math.random() * 0.6 + 0.2, // 0.2-0.8 tendency for tactical moves positional: Math.random() * 0.6 + 0.2 // 0.2-0.8 tendency for positional moves }, preferredOpenings: [ "e4", "d4", "c4", "Nf3" // Just examples, could be expanded ].sort(() => Math.random() - 0.5), // Randomize the order playerFingerprint: GM_getValue("playerFingerprint", { favoredPieces: Math.random() < 0.5 ? "knights" : "bishops", openingTempo: Math.random() * 0.5 + 0.5, // 0.5-1.0 opening move speed tacticalAwareness: Math.random() * 0.4 + 0.6, // 0.6-1.0 tactical vision exchangeThreshold: Math.random() * 0.3 + 0.1, // When to accept exchanges attackingStyle: ["kingside", "queenside", "central"][Math.floor(Math.random() * 3)] }), tacticalProfile: GM_getValue("tacticalProfile", { strengths: [ getRandomTacticalStrength(), getRandomTacticalStrength() ], weaknesses: [ getRandomTacticalWeakness(), getRandomTacticalWeakness() ] }), psychologicalState: { confidence: 0.7 + Math.random() * 0.3, // 0.7-1.0 tiltFactor: 0, // 0-1, increases with blunders focus: 0.8 + Math.random() * 0.2, // 0.8-1.0, decreases with time playTime: 0 // tracks continuous play time } }; if (!GM_getValue("playerFingerprint")) { GM_setValue("playerFingerprint", myVars.playerFingerprint); } if (!GM_getValue("tacticalProfile")) { GM_setValue("tacticalProfile", myVars.tacticalProfile); } return myVars; } // engine.js function setupEngine(myVars, myFunctions) { const engine = { engine: null }; myFunctions.loadChessEngine = function() { if (!engine.stockfishObjectURL) { engine.stockfishObjectURL = URL.createObjectURL(new Blob([GM_getResourceText("stockfish.js")], { type: "application/javascript" })); } console.log(engine.stockfishObjectURL); if (engine.stockfishObjectURL) { engine.engine = new Worker(engine.stockfishObjectURL); engine.engine.onmessage = (e) => { myFunctions.parser(e); }; engine.engine.onerror = (e) => { console.log("Worker Error: " + e); }; engine.engine.postMessage("ucinewgame"); } console.log("loaded chess engine"); }; myFunctions.reloadChessEngine = function() { console.log(`Reloading the chess engine!`); engine.engine.terminate(); window.isThinking = false; myFunctions.loadChessEngine(); }; myFunctions.runChessEngine = function(depth) { var adjustedDepth = myFunctions.getAdjustedDepth(); var fen = window.board.game.getFEN(); var positionType = myFunctions.analyzePositionType(fen); console.log(`Original depth: ${depth}, Adjusted for time/position: ${adjustedDepth}`); engine.engine.postMessage(`position fen ${fen}`); console.log(`updated: position fen ${fen}`); window.isThinking = true; if (depth >= 15) { engine.engine.postMessage(`setoption name MultiPV value 5`); } else { engine.engine.postMessage(`setoption name MultiPV value 1`); } engine.engine.postMessage(`go depth ${adjustedDepth}`); myVars.lastValue = depth; }; myFunctions.autoRun = function(lstValue) { if (window.board.game.getTurn() == window.board.game.getPlayingAs()) { myFunctions.runChessEngine(lstValue); } }; return engine; } // ui/html.js var mainTemplate = `

Panel Pro By @akashdeep

Current Depth: 11

Press a key (Q-Z) to change depth

11

Playing Style Settings

5
5
5
5
2

Advanced Settings

`; var advancedSettingsTemplate = `
7
`; var spinnerTemplate = ` `; // ui/styles.js var mainStyles = ` @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap'); #settingsContainer { background-color: #1e1e2e; color: #cdd6f4; border-radius: 12px; padding: 20px; margin-top: 15px; box-shadow: 0 8px 24px rgba(0,0,0,0.3); font-family: 'Roboto', sans-serif; max-width: 400px; margin-left: auto; margin-right: auto; border: 1px solid #313244; } .chess-bot-container { display: flex; flex-direction: column; gap: 16px; } .bot-header { display: flex; align-items: center; justify-content: center; gap: 10px; margin-bottom: 5px; position: relative; } .bot-logo { display: flex; align-items: center; justify-content: center; color: #89b4fa; } .bot-title { margin: 0; color: #89b4fa; font-size: 20px; font-weight: 500; letter-spacing: 0.5px; } .thinking-indicator { position: absolute; right: 0; display: none; align-items: center; } .thinking-indicator.active { display: flex; } .dot { width: 8px; height: 8px; margin: 0 2px; background-color: #89b4fa; border-radius: 50%; opacity: 0.6; } .dot1 { animation: pulse 1.5s infinite; } .dot2 { animation: pulse 1.5s infinite 0.3s; } .dot3 { animation: pulse 1.5s infinite 0.6s; } @keyframes pulse { 0%, 100% { transform: scale(1); opacity: 0.6; } 50% { transform: scale(1.3); opacity: 1; } } .bot-tabs { display: flex; gap: 2px; margin-bottom: -15px; } .tab-button { background-color: #313244; color: #a6adc8; border: none; border-radius: 8px 8px 0 0; padding: 8px 16px; cursor: pointer; font-size: 14px; font-weight: 500; transition: all 0.2s; flex: 1; text-align: center; } .tab-button:hover { background-color: #45475a; color: #cdd6f4; } .tab-button.active { background-color: #45475a; color: #cdd6f4; } .bot-tabs-content { background-color: #45475a; border-radius: 0 8px 8px 8px; padding: 16px; } .tab-content { display: none; } .tab-content.active { display: block; } .settings-section-title { margin-top: 0; margin-bottom: 12px; color: #89b4fa; font-size: 16px; font-weight: 500; text-align: center; } .bot-info { display: flex; justify-content: center; margin-bottom: 5px; } .depth-card { background-color: #313244; border-radius: 8px; padding: 12px 16px; text-align: center; width: 100%; border: 1px solid #45475a; } .depth-display { font-size: 16px; margin: 0 0 5px 0; font-weight: 400; } .depth-display strong { color: #89b4fa; font-weight: 600; } .key-hint { font-size: 12px; color: #a6adc8; margin: 0; font-weight: 300; } .bot-controls { display: flex; flex-direction: column; gap: 16px; } .control-group { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; } .control-item { display: flex; flex-direction: column; gap: 6px; } .toggle-container { position: relative; } .toggle-input { opacity: 0; width: 0; height: 0; position: absolute; } .toggle-label { display: flex; align-items: center; gap: 10px; cursor: pointer; } .toggle-button { position: relative; display: inline-block; width: 40px; height: 20px; background-color: #45475a; border-radius: 20px; transition: all 0.3s; } .toggle-button:before { content: ''; position: absolute; width: 16px; height: 16px; border-radius: 50%; background-color: #cdd6f4; top: 2px; left: 2px; transition: all 0.3s; } .toggle-input:checked + .toggle-label .toggle-button { background-color: #89b4fa; } .toggle-input:checked + .toggle-label .toggle-button:before { transform: translateX(20px); } .toggle-text { font-size: 14px; } .slider-container { display: flex; flex-direction: column; gap: 6px; } .slider-container label { font-size: 13px; color: #a6adc8; } .number-input { width: 100%; background: #313244; border: 1px solid #45475a; border-radius: 6px; color: #cdd6f4; padding: 8px 10px; font-size: 14px; transition: border-color 0.3s; } .number-input:focus { outline: none; border-color: #89b4fa; } .bot-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 5px; } .action-button { display: flex; align-items: center; justify-content: center; gap: 8px; border: none; border-radius: 8px; padding: 10px 16px; font-size: 14px; font-weight: 500; cursor: pointer; transition: all 0.2s; } .primary-button { background-color: #89b4fa; color: #1e1e2e; } .primary-button:hover { background-color: #b4befe; transform: translateY(-2px); box-shadow: 0 4px 8px rgba(137, 180, 250, 0.3); } .secondary-button { background-color: #45475a; color: #cdd6f4; } .secondary-button:hover { background-color: #585b70; transform: translateY(-2px); box-shadow: 0 4px 8px rgba(69, 71, 90, 0.3); } .action-button:active { transform: translateY(0); } .depth-control { margin-top: 12px; display: flex; flex-direction: column; gap: 8px; } .depth-control label { font-size: 13px; color: #a6adc8; } .slider-controls { display: flex; align-items: center; gap: 8px; } .depth-slider { flex: 1; height: 6px; -webkit-appearance: none; appearance: none; background: #45475a; border-radius: 3px; outline: none; } .depth-slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 16px; height: 16px; border-radius: 50%; background: #89b4fa; cursor: pointer; } .depth-slider::-moz-range-thumb { width: 16px; height: 16px; border-radius: 50%; background: #89b4fa; cursor: pointer; } .depth-button { width: 24px; height: 24px; border-radius: 50%; background: #45475a; color: #cdd6f4; border: none; display: flex; align-items: center; justify-content: center; cursor: pointer; font-size: 16px; font-weight: bold; transition: background-color 0.2s; } .depth-button:hover { background: #585b70; } #depthValue { font-size: 14px; font-weight: 500; color: #89b4fa; text-align: center; } @keyframes rotate { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } `; var advancedStyles = ` .advanced-section { margin-top: 15px; padding-top: 15px; border-top: 1px solid #313244; } .profile-selection { margin-top: 15px; } .playStyle-controls, .advanced-controls { display: flex; flex-direction: column; gap: 12px; } .style-slider-container { display: flex; align-items: center; gap: 10px; } .style-slider-container label { font-size: 13px; color: #cdd6f4; width: 120px; } .style-slider { flex: 1; height: 6px; -webkit-appearance: none; appearance: none; background: #313244; border-radius: 3px; outline: none; } .style-slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 14px; height: 14px; border-radius: 50%; background: #89b4fa; cursor: pointer; } .style-slider-container span { font-size: 14px; font-weight: 500; color: #89b4fa; width: 20px; text-align: center; } .highlight-color-picker { display: flex; align-items: center; gap: 10px; margin-top: 10px; } .highlight-color-picker label { font-size: 13px; color: #cdd6f4; } .color-input { -webkit-appearance: none; width: 30px; height: 30px; border: none; border-radius: 50%; background: none; cursor: pointer; } .color-input::-webkit-color-swatch { border: none; border-radius: 50%; box-shadow: 0 0 0 2px #45475a; } .opening-selection { display: flex; align-items: center; gap: 10px; margin-top: 10px; } .opening-selection label { font-size: 13px; color: #cdd6f4; } .select-input { flex: 1; background: #313244; border: 1px solid #45475a; border-radius: 6px; color: #cdd6f4; padding: 8px 10px; font-size: 14px; transition: border-color 0.3s; } .select-input:focus { outline: none; border-color: #89b4fa; } `; // ui.js function setupUI(myVars, myFunctions) { let dynamicStyles = null; function addAnimation(body) { if (!dynamicStyles) { dynamicStyles = document.createElement("style"); dynamicStyles.type = "text/css"; document.head.appendChild(dynamicStyles); } dynamicStyles.sheet.insertRule(body, dynamicStyles.length); } myFunctions.spinner = function() { if (window.isThinking == true) { $("#thinking-indicator").addClass("active"); } if (window.isThinking == false) { $("#thinking-indicator").removeClass("active"); } }; myFunctions.loadEx = function() { try { window.board = $("chess-board")[0] || $("wc-chess-board")[0]; myVars.board = window.board; var div = document.createElement("div"); div.setAttribute("id", "settingsContainer"); div.innerHTML = mainTemplate; div.prepend($(spinnerTemplate)[0]); window.board.parentElement.parentElement.appendChild(div); var botStyles = document.createElement("style"); botStyles.innerHTML = mainStyles + advancedStyles; document.head.appendChild(botStyles); addAnimation(`@keyframes rotate { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }`); $("#advanced-settings .advanced-controls").append(advancedSettingsTemplate); myFunctions.loadSettings(); applySettingsToUI(myVars); myVars.loaded = true; } catch (error) { console.log(error); } }; function applySettingsToUI(myVars2) { $("#autoRun").prop("checked", myVars2.autoRun); $("#autoMove").prop("checked", myVars2.autoMove); $("#adaptToRating").prop("checked", myVars2.adaptToRating !== void 0 ? myVars2.adaptToRating : true); $("#useOpeningBook").prop("checked", myVars2.useOpeningBook !== void 0 ? myVars2.useOpeningBook : true); $("#enableHotkeys").prop("checked", myVars2.enableHotkeys !== void 0 ? myVars2.enableHotkeys : true); $("#randomizeTiming").prop("checked", myVars2.randomizeTiming !== void 0 ? myVars2.randomizeTiming : true); $("#depthSlider").val(myVars2.lastValue); $("#depthValue").text(myVars2.lastValue); $("#depthText").html("Current Depth: " + myVars2.lastValue + ""); $("#timeDelayMin").val(GM_getValue("timeDelayMin", 0.1)); $("#timeDelayMax").val(GM_getValue("timeDelayMax", 1)); if (myVars2.highlightColor) { $("#highlightColor").val(myVars2.highlightColor); } if (myVars2.playStyle) { const aggressiveValue = Math.round((myVars2.playStyle.aggressive - 0.3) / 0.5 * 10); $("#aggressiveSlider").val(aggressiveValue); $("#aggressiveValue").text(aggressiveValue); const defensiveValue = Math.round((myVars2.playStyle.defensive - 0.3) / 0.5 * 10); $("#defensiveSlider").val(defensiveValue); $("#defensiveValue").text(defensiveValue); const tacticalValue = Math.round((myVars2.playStyle.tactical - 0.2) / 0.6 * 10); $("#tacticalSlider").val(tacticalValue); $("#tacticalValue").text(tacticalValue); const positionalValue = Math.round((myVars2.playStyle.positional - 0.2) / 0.6 * 10); $("#positionalSlider").val(positionalValue); $("#positionalValue").text(positionalValue); } if (myVars2.blunderRate !== void 0) { const blunderValue = Math.round(myVars2.blunderRate * 10); $("#blunderRateSlider").val(blunderValue); $("#blunderRateValue").text(blunderValue); } if (myVars2.mouseMovementRealism !== void 0) { const movementValue = Math.round(myVars2.mouseMovementRealism * 10); $("#mouseMovementSlider").val(movementValue); $("#mouseMovementSliderValue").text(movementValue); } if (myVars2.preferredOpenings && myVars2.preferredOpenings.length === 1) { $("#preferredOpeningSelect").val(myVars2.preferredOpenings[0]); } console.log("Settings applied to UI"); } return myFunctions; } // events/ui-events.js function setupUIEventHandlers(myVars, myFunctions) { $(document).on("input", "#depthSlider", function() { const depth = parseInt($(this).val()); $("#depthValue").text(depth); myVars.lastValue = depth; $("#depthText")[0].innerHTML = "Current Depth: " + depth + ""; myFunctions.saveSettings(); }); $(document).on("click", "#decreaseDepth", function() { const currentDepth = parseInt($("#depthSlider").val()); if (currentDepth > 1) { const newDepth = currentDepth - 1; $("#depthSlider").val(newDepth).trigger("input"); } }); $(document).on("click", "#increaseDepth", function() { const currentDepth = parseInt($("#depthSlider").val()); if (currentDepth < 26) { const newDepth = currentDepth + 1; $("#depthSlider").val(newDepth).trigger("input"); } }); $(document).on("click", ".tab-button", function() { $(".tab-button").removeClass("active"); $(this).addClass("active"); const tabId = $(this).data("tab"); $(".tab-content").removeClass("active"); $(`#${tabId}`).addClass("active"); }); } // events/style-events.js function setupStyleEventHandlers(myVars, myFunctions) { $(document).on("input", ".style-slider", function() { const value = $(this).val(); $(`#${this.id}Value`).text(value); const styleType = this.id.replace("Slider", ""); if (styleType === "blunderRate") { myVars.blunderRate = parseFloat(value) / 10; } else if (myVars.playStyle && styleType in myVars.playStyle) { if (styleType === "aggressive" || styleType === "defensive") { myVars.playStyle[styleType] = 0.3 + parseFloat(value) / 10 * 0.5; } else { myVars.playStyle[styleType] = 0.2 + parseFloat(value) / 10 * 0.6; } } myFunctions.saveSettings(); }); $(document).on("change", "#autoRun, #autoMove, #adaptToRating, #useOpeningBook, #enableHotkeys, #randomizeTiming", function() { const id = $(this).attr("id"); myVars[id] = $(this).prop("checked"); if (id === "autoMove") { console.log(`Auto move set to: ${myVars.autoMove}`); } myFunctions.saveSettings(); }); $(document).on("input", "#highlightColor", function() { myVars.highlightColor = $(this).val(); myFunctions.saveSettings(); }); } // events/advanced-events.js function setupAdvancedEventHandlers(myVars, myFunctions) { $(document).on("change", "#preferredOpeningSelect", function() { const selectedOpening = $(this).val(); if (selectedOpening === "random") { myVars.preferredOpenings = ["e4", "d4", "c4", "Nf3"].sort(() => Math.random() - 0.5); } else { myVars.preferredOpenings = [selectedOpening]; } myFunctions.saveSettings(); }); $(document).on("input", "#mouseMovementSlider", function() { const value = $(this).val(); $("#mouseMovementSliderValue").text(value); myVars.mouseMovementRealism = parseFloat(value) / 10; myFunctions.saveSettings(); }); $(document).on("change", "#playingProfileSelect", function() { const profile = $(this).val(); if (profile !== "custom") { switch (profile) { case "beginner": $("#depthSlider").val(3).trigger("input"); $("#blunderRateSlider").val(7).trigger("input"); $("#aggressiveSlider").val(Math.floor(3 + Math.random() * 5)).trigger("input"); $("#tacticalSlider").val(3).trigger("input"); break; case "intermediate": $("#depthSlider").val(6).trigger("input"); $("#blunderRateSlider").val(5).trigger("input"); $("#tacticalSlider").val(5).trigger("input"); break; case "advanced": $("#depthSlider").val(9).trigger("input"); $("#blunderRateSlider").val(3).trigger("input"); $("#tacticalSlider").val(7).trigger("input"); break; case "expert": $("#depthSlider").val(12).trigger("input"); $("#blunderRateSlider").val(2).trigger("input"); $("#tacticalSlider").val(8).trigger("input"); $("#positionalSlider").val(8).trigger("input"); break; case "master": $("#depthSlider").val(15).trigger("input"); $("#blunderRateSlider").val(1).trigger("input"); $("#tacticalSlider").val(9).trigger("input"); $("#positionalSlider").val(9).trigger("input"); break; } setTimeout(myFunctions.saveSettings, 100); } }); $(document).on("change", "#timeDelayMin, #timeDelayMax", function() { myFunctions.saveSettings(); }); } // events.js function setupEventHandlers(myVars, myFunctions, engine) { document.onkeydown = function(e) { if (!myVars.enableHotkeys) return; switch (e.keyCode) { case 81: myFunctions.runChessEngine(1); break; case 87: myFunctions.runChessEngine(2); break; case 69: myFunctions.runChessEngine(3); break; case 82: myFunctions.runChessEngine(4); break; case 84: myFunctions.runChessEngine(5); break; case 89: myFunctions.runChessEngine(6); break; case 85: myFunctions.runChessEngine(7); break; case 73: myFunctions.runChessEngine(8); break; case 79: myFunctions.runChessEngine(9); break; case 80: myFunctions.runChessEngine(10); break; case 65: myFunctions.runChessEngine(11); break; case 83: myFunctions.runChessEngine(12); break; case 68: myFunctions.runChessEngine(13); break; case 70: myFunctions.runChessEngine(14); break; case 71: myFunctions.runChessEngine(15); break; case 72: myFunctions.runChessEngine(16); break; case 74: myFunctions.runChessEngine(17); break; case 75: myFunctions.runChessEngine(18); break; case 76: myFunctions.runChessEngine(19); break; case 90: myFunctions.runChessEngine(20); break; case 88: myFunctions.runChessEngine(21); break; case 67: myFunctions.runChessEngine(22); break; case 86: myFunctions.runChessEngine(23); break; case 66: myFunctions.runChessEngine(24); break; case 78: myFunctions.runChessEngine(25); break; case 77: myFunctions.runChessEngine(26); break; case 187: myFunctions.runChessEngine(100); break; } }; $(document).ready(function() { setupUIEventHandlers(myVars, myFunctions); setupStyleEventHandlers(myVars, myFunctions); setupAdvancedEventHandlers(myVars, myFunctions); }); } // parser.js function setupParser(myVars, myFunctions) { myFunctions.parser = function(e) { if (e.data.includes("bestmove")) { const bestMove = e.data.split(" ")[1]; let alternativeMoves = [bestMove]; try { if (e.data.includes("pv")) { const lines = e.data.split("\n").filter((line) => line.includes(" pv ")).map((line) => { const pvIndex = line.indexOf(" pv "); return line.substring(pvIndex + 4).split(" ")[0]; }); if (lines.length > 1) { alternativeMoves = lines; } } } catch (error) { console.log("Error extracting alternative moves", error); } let moveToPlay = bestMove; const currentDepth = myVars.lastValue; if (currentDepth >= 15 && alternativeMoves.length > 1 && Math.random() < 0.35) { const maxIndex = Math.min(5, alternativeMoves.length); const randomIndex = Math.floor(Math.random() * (maxIndex - 1)) + 1; moveToPlay = alternativeMoves[randomIndex] || bestMove; console.log(`Using alternative move ${moveToPlay} instead of best move ${bestMove}`); } else if (Math.random() < myFunctions.getBlunderProbability()) { moveToPlay = myFunctions.generateHumanLikeMove(bestMove, e.data); console.log(`Using human-like move ${moveToPlay} instead of best move ${bestMove}`); } myFunctions.color(moveToPlay); window.isThinking = false; } }; myFunctions.getBlunderProbability = function() { const userBlunderRate = myVars.blunderRate !== void 0 ? myVars.blunderRate : 0.05; const gamePhase = myFunctions.estimateGamePhase(); const timeRemaining = myFunctions.estimateTimeRemaining(); const complexity = myFunctions.estimatePositionComplexity(); let baseProb = userBlunderRate; if (timeRemaining < 30) { baseProb += 0.1 * (1 - timeRemaining / 30); } if (complexity > 0.6) { baseProb += 0.05 * (complexity - 0.6) * 2; } if (gamePhase > 30) { baseProb += 0.03 * ((gamePhase - 30) / 10); } return Math.min(0.4, baseProb * (0.7 + Math.random() * 0.6)); }; myFunctions.generateHumanLikeMove = function(bestMove, engineData) { if (engineData.includes("pv") && Math.random() < 0.4) { try { const lines = engineData.split("\n").filter((line) => line.includes(" pv ")).map((line) => { const pvIndex = line.indexOf(" pv "); return line.substring(pvIndex + 4).split(" ")[0]; }); if (lines.length > 1) { const moveIndex = Math.floor(Math.pow(Math.random(), 2.5) * Math.min(lines.length, 4)); return lines[moveIndex] || bestMove; } } catch (e) { console.log("Error extracting alternative moves", e); } } if (Math.random() < 0.15) { const fromSquare = bestMove.substring(0, 2); const toSquare = bestMove.substring(2, 4); if (Math.random() < 0.7) { const files = "abcdefgh"; const ranks = "12345678"; const fromFile = fromSquare.charAt(0); const fromRank = fromSquare.charAt(1); const toFile = toSquare.charAt(0); const toRank = toSquare.charAt(1); const fileDiff = files.indexOf(toFile) - files.indexOf(fromFile); const rankDiff = ranks.indexOf(toRank) - ranks.indexOf(fromRank); if (Math.abs(fileDiff) > 1 || Math.abs(rankDiff) > 1) { const newToFile = files[files.indexOf(fromFile) + (fileDiff > 0 ? Math.max(1, fileDiff - 1) : Math.min(-1, fileDiff + 1))]; const newToRank = ranks[ranks.indexOf(fromRank) + (rankDiff > 0 ? Math.max(1, rankDiff - 1) : Math.min(-1, rankDiff + 1))]; if (newToFile && newToRank) { const alternativeMove = fromSquare + newToFile + newToRank; for (let each = 0; each < window.board.game.getLegalMoves().length; each++) { if (window.board.game.getLegalMoves()[each].from === fromSquare && window.board.game.getLegalMoves()[each].to === newToFile + newToRank) { return alternativeMove; } } } } } } return bestMove; }; } // utilities.js function setupUtilities(myVars) { const myFunctions = {}; let stop_b = stop_w = 0; let s_br = s_br2 = s_wr = s_wr2 = 0; let obs = ""; setupParser(myVars, myFunctions); myFunctions.rescan = function(lev) { var ari = $("chess-board").find(".piece").map(function() { return this.className; }).get(); jack = ari.map((f) => f.substring(f.indexOf(" ") + 1)); function removeWord(arr, word) { for (var i2 = 0; i2 < arr.length; i2++) { arr[i2] = arr[i2].replace(word, ""); } } removeWord(ari, "square-"); jack = ari.map((f) => f.substring(f.indexOf(" ") + 1)); for (var i = 0; i < jack.length; i++) { jack[i] = jack[i].replace("br", "r").replace("bn", "n").replace("bb", "b").replace("bq", "q").replace("bk", "k").replace("bb", "b").replace("bn", "n").replace("br", "r").replace("bp", "p").replace("wp", "P").replace("wr", "R").replace("wn", "N").replace("wb", "B").replace("br", "R").replace("wn", "N").replace("wb", "B").replace("wq", "Q").replace("wk", "K").replace("wb", "B"); } str2 = ""; var count = 0, str = ""; for (var j = 8; j > 0; j--) { for (var i = 1; i < 9; i++) { (str = jack.find((el) => el.includes([i] + [j]))) ? str = str.replace(/[^a-zA-Z]+/g, "") : str = ""; if (str == "") { count++; str = count.toString(); if (!isNaN(str2.charAt(str2.length - 1))) str2 = str2.slice(0, -1); else { count = 1; str = count.toString(); } } str2 += str; if (i == 8) { count = 0; str2 += "/"; } } } str2 = str2.slice(0, -1); color = ""; wk = wq = bk = bq = "0"; const move = $("vertical-move-list").children(); if (move.length < 2) { stop_b = stop_w = s_br = s_br2 = s_wr = s_wr2 = 0; } if (stop_b != 1) { if (move.find(".black.node:contains('K')").length) { bk = ""; bq = ""; stop_b = 1; console.log("debug secb"); } } else { bq = ""; bk = ""; } if (stop_b != 1) (bk = move.find(".black.node:contains('O-O'):not(:contains('O-O-O'))").length ? "" : "k") ? bq = move.find(".black.node:contains('O-O-O')").length ? bk = "" : "q" : bq = ""; if (s_br != 1) { if (move.find(".black.node:contains('R')").text().match("[abcd]+")) { bq = ""; s_br = 1; } } else bq = ""; if (s_br2 != 1) { if (move.find(".black.node:contains('R')").text().match("[hgf]+")) { bk = ""; s_br2 = 1; } } else bk = ""; if (stop_b == 0) { if (s_br == 0) { if (move.find(".white.node:contains('xa8')").length > 0) { bq = ""; s_br = 1; console.log("debug b castle_r"); } } if (s_br2 == 0) { if (move.find(".white.node:contains('xh8')").length > 0) { bk = ""; s_br2 = 1; console.log("debug b castle_l"); } } } if (stop_w != 1) { if (move.find(".white.node:contains('K')").length) { wk = ""; wq = ""; stop_w = 1; console.log("debug secw"); } } else { wq = ""; wk = ""; } if (stop_w != 1) (wk = move.find(".white.node:contains('O-O'):not(:contains('O-O-O'))").length ? "" : "K") ? wq = move.find(".white.node:contains('O-O-O')").length ? wk = "" : "Q" : wq = ""; if (s_wr != 1) { if (move.find(".white.node:contains('R')").text().match("[abcd]+")) { wq = ""; s_wr = 1; } } else wq = ""; if (s_wr2 != 1) { if (move.find(".white.node:contains('R')").text().match("[hgf]+")) { wk = ""; s_wr2 = 1; } } else wk = ""; if (stop_w == 0) { if (s_wr == 0) { if (move.find(".black.node:contains('xa1')").length > 0) { wq = ""; s_wr = 1; console.log("debug w castle_l"); } } if (s_wr2 == 0) { if (move.find(".black.node:contains('xh1')").length > 0) { wk = ""; s_wr2 = 1; console.log("debug w castle_r"); } } } if ($(".coordinates").children().first().text() == 1) { str2 = str2 + " b " + wk + wq + bk + bq; color = "white"; } else { str2 = str2 + " w " + wk + wq + bk + bq; color = "black"; } return str2; }; myFunctions.color = function(dat) { response = dat; var res1 = response.substring(0, 2); var res2 = response.substring(2, 4); if (myVars.autoMove === true) { console.log(`Auto move enabled, moving from ${res1} to ${res2}`); myFunctions.movePiece(res1, res2); } else { console.log(`Auto move disabled, highlighting ${res1} to ${res2}`); } window.isThinking = false; res1 = res1.replace(/^a/, "1").replace(/^b/, "2").replace(/^c/, "3").replace(/^d/, "4").replace(/^e/, "5").replace(/^f/, "6").replace(/^g/, "7").replace(/^h/, "8"); res2 = res2.replace(/^a/, "1").replace(/^b/, "2").replace(/^c/, "3").replace(/^d/, "4").replace(/^e/, "5").replace(/^f/, "6").replace(/^g/, "7").replace(/^h/, "8"); const highlightColor = myVars.highlightColor || "rgb(235, 97, 80)"; $(window.board.nodeName).prepend(`
`).children(":first").delay(1800).queue(function() { $(this).remove(); }); $(window.board.nodeName).prepend(`
`).children(":first").delay(1800).queue(function() { $(this).remove(); }); }; myFunctions.movePiece = function(from, to) { let isLegalMove = false; let moveObject = null; for (let each = 0; each < window.board.game.getLegalMoves().length; each++) { if (window.board.game.getLegalMoves()[each].from === from && window.board.game.getLegalMoves()[each].to === to) { isLegalMove = true; moveObject = window.board.game.getLegalMoves()[each]; break; } } if (!isLegalMove) { console.log(`Attempted illegal move: ${from} to ${to}`); return; } setTimeout(() => { try { window.board.game.move({ ...moveObject, promotion: moveObject.promotion || "q", // Default to queen for simplicity animate: true, userGenerated: true }); console.log(`Successfully moved from ${from} to ${to}`); } catch (error) { console.error("Error making move:", error); } }, 100 + Math.random() * 300); }; myFunctions.other = function(delay) { const gamePhase = myFunctions.estimateGamePhase(); const positionComplexity = myFunctions.estimatePositionComplexity(); let naturalDelay = delay; if (gamePhase < 10) { naturalDelay *= 0.6 + Math.random() * 0.4; } if (positionComplexity > 0.7) { naturalDelay *= 1 + Math.random() * 1.5; } naturalDelay *= 0.85 + Math.random() * 0.3; var endTime = Date.now() + naturalDelay; var timer = setInterval(() => { if (Date.now() >= endTime) { myFunctions.autoRun(myFunctions.getAdjustedDepth()); window.canGo = true; clearInterval(timer); } }, 10); }; myFunctions.getAdjustedDepth = function() { const timeRemaining = myFunctions.estimateTimeRemaining(); const gamePhase = myFunctions.estimateGamePhase(); const positionType = myFunctions.analyzePositionType(window.board.game.getFEN()); const isPositionCritical = myFunctions.isPositionCriticalNow(); let baseDepth = myVars.lastValue; if (timeRemaining < 10) { return Math.floor(Math.random() * 3) + 1; } else if (timeRemaining < 30) { return Math.floor(Math.random() * 4) + 4; } else if (timeRemaining < 60) { return Math.floor(Math.random() * 7) + 6; } else if (timeRemaining < 120) { return Math.floor(Math.random() * 7) + 9; } else { if (!isPositionCritical && Math.random() < 0.07) { return Math.floor(Math.random() * 4) + 2; } return Math.floor(Math.random() * 9) + 11; } }; myFunctions.analyzePositionType = function(fen) { const piecesCount = fen.split(" ")[0].match(/[pnbrqkPNBRQK]/g).length; if (piecesCount > 25) return "opening"; if (piecesCount < 12) return "endgame"; return "middlegame"; }; myFunctions.isPositionCriticalNow = function() { try { const inCheck = window.board.game.inCheck(); const fen = window.board.game.getFEN(); const whiteMaterial = myFunctions.countMaterial(fen, true); const blackMaterial = myFunctions.countMaterial(fen, false); const materialDifference = Math.abs(whiteMaterial - blackMaterial); return inCheck || materialDifference < 2; } catch (e) { return false; } }; myFunctions.countMaterial = function(fen, isWhite) { const position = fen.split(" ")[0]; let material = 0; const pieces = isWhite ? "PNBRQK" : "pnbrqk"; const values = { "P": 1, "N": 3, "B": 3, "R": 5, "Q": 9, "K": 0, "p": 1, "n": 3, "b": 3, "r": 5, "q": 9, "k": 0 }; for (let char of position) { if (pieces.includes(char)) { material += values[char]; } } return material; }; myFunctions.estimateGamePhase = function() { try { const moveList = $("vertical-move-list").children().length; return moveList / 2; } catch (e) { return 15; } }; myFunctions.estimateTimeRemaining = function() { let remainingTime = 600; try { const clockEl = document.querySelector(".clock-component.clock-bottom"); if (clockEl) { const timeText = clockEl.textContent; if (timeText.includes(":")) { const parts = timeText.split(":"); if (parts.length === 2) { const minutes = parseInt(parts[0]); const seconds = parseInt(parts[1]); if (!isNaN(minutes) && !isNaN(seconds)) { remainingTime = minutes * 60 + seconds; } else { console.log("Error parsing time:", timeText); } } } else { const seconds = parseInt(timeText); if (!isNaN(seconds)) { remainingTime = seconds; } else { console.log("Error parsing time:", timeText); } } } else { console.log("Clock element not found with selector '.clock-component.clock-bottom'"); } } catch (e) { console.log("Error getting time remaining:", e); } console.log("Remaining time:", remainingTime); return remainingTime; }; myFunctions.estimatePositionComplexity = function() { return Math.random() * 0.8 + 0.2; }; myFunctions.saveSettings = function() { try { GM_setValue("autoRun", myVars.autoRun); GM_setValue("autoMove", myVars.autoMove); GM_setValue("timeDelayMin", $("#timeDelayMin").val()); GM_setValue("timeDelayMax", $("#timeDelayMax").val()); GM_setValue("depthValue", myVars.lastValue); GM_setValue("highlightColor", myVars.highlightColor); GM_setValue("playStyle", myVars.playStyle); GM_setValue("blunderRate", myVars.blunderRate); GM_setValue("adaptToRating", myVars.adaptToRating); GM_setValue("useOpeningBook", myVars.useOpeningBook); GM_setValue("preferredOpenings", myVars.preferredOpenings); GM_setValue("enableHotkeys", myVars.enableHotkeys); GM_setValue("randomizeTiming", myVars.randomizeTiming); GM_setValue("mouseMovementRealism", myVars.mouseMovementRealism); console.log("Settings saved successfully"); } catch (error) { console.error("Error saving settings:", error); } }; myFunctions.loadSettings = function() { try { myVars.autoRun = GM_getValue("autoRun", false); myVars.autoMove = GM_getValue("autoMove", false); myVars.lastValue = GM_getValue("depthValue", 11); myVars.highlightColor = GM_getValue("highlightColor", "rgb(235, 97, 80)"); myVars.blunderRate = GM_getValue("blunderRate", 0.05); myVars.adaptToRating = GM_getValue("adaptToRating", true); myVars.useOpeningBook = GM_getValue("useOpeningBook", true); myVars.preferredOpenings = GM_getValue("preferredOpenings", ["e4", "d4", "c4", "Nf3"]); myVars.enableHotkeys = GM_getValue("enableHotkeys", true); myVars.randomizeTiming = GM_getValue("randomizeTiming", true); myVars.mouseMovementRealism = GM_getValue("mouseMovementRealism", 0.7); const savedPlayStyle = GM_getValue("playStyle", null); if (savedPlayStyle) { myVars.playStyle = savedPlayStyle; } console.log("Settings loaded successfully"); } catch (error) { console.error("Error loading settings:", error); } }; return myFunctions; } // main.js window.isThinking = false; window.canGo = true; window.myTurn = false; window.board = null; function main() { const myVars = initializeVariables(); const myFunctions = setupUtilities(myVars); myFunctions.loadSettings(); const engine = setupEngine(myVars, myFunctions); document.engine = engine; document.myVars = myVars; document.myFunctions = myFunctions; setupUI(myVars, myFunctions, engine); setupEventHandlers(myVars, myFunctions, engine); console.log("Chess.com UltraX bot initialized with version:", currentVersion); } window.addEventListener("load", (event) => { main(); }); var waitForChessBoard = setInterval(() => { if (!document.myVars || !document.myFunctions) return; const myVars = document.myVars; const myFunctions = document.myFunctions; if (myVars.loaded) { window.board = $("chess-board")[0] || $("wc-chess-board")[0]; myVars.autoRun = $("#autoRun")[0].checked; myVars.autoMove = $("#autoMove")[0].checked; let minDel = parseFloat($("#timeDelayMin")[0].value); let maxDel = parseFloat($("#timeDelayMax")[0].value); myVars.delay = Math.random() * (maxDel - minDel) + minDel; myVars.isThinking = window.isThinking; myFunctions.spinner(); if (window.board.game.getTurn() == window.board.game.getPlayingAs()) { window.myTurn = true; } else { window.myTurn = false; } $("#depthText")[0].innerHTML = "Current Depth: " + myVars.lastValue + ""; } else { myFunctions.loadEx(); } if (!document.engine.engine) { myFunctions.loadChessEngine(); } if (myVars.autoRun == true && window.canGo == true && window.isThinking == false && window.myTurn) { window.canGo = false; var currentDelay = myVars.delay != void 0 ? myVars.delay * 1e3 : 10; myFunctions.other(currentDelay); } }, 100); })();