Greasy Fork is available in English.

Chess.com Bot/Cheata

Chess.com Bot/Cheat that finds the best move!

  1. // ==UserScript==
  2. // additional copyright/license info:
  3. //© All Rights Reserved
  4. //
  5. //Chess.com Bot/Cheat © 2025 by GoodtimeswithEno
  6. //
  7. // ==UserScript
  8. // @name Chess.com Bot/Cheata
  9. // @namespace GoodtimeswithEno
  10. // @version 1.2.9.4
  11. // @description Chess.com Bot/Cheat that finds the best move!
  12. // @author GoodtmieswithEno
  13. // @license Chess.com Bot/Cheat © 2025 by GoodtimeswithEno, © All Rights Reserved
  14. // @match https://www.chess.com/play/*
  15. // @match https://www.chess.com/game/*
  16. // @match https://www.chess.com/puzzles/*
  17. // @match https://www.chess.com/*
  18. // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
  19. // @grant GM_getValue
  20. // @grant GM_setValue
  21. // @grant GM_xmlhttpRequest
  22. // @grant GM_getResourceText
  23. // @grant GM_registerMenuCommand
  24. // @resource stockfish.js https://cdnjs.cloudflare.com/ajax/libs/stockfish.js/9.0.0/stockfish.js
  25. // @require https://greatest.deepsurf.us/scripts/445697/code/index.js
  26. // @require https://code.jquery.com/jquery-3.6.0.min.js
  27. // @run-at document-start
  28. // @liscense MIT
  29.  
  30. // ==/UserScript==
  31.  
  32. //Don't touch anything below unless you know what your doing!
  33.  
  34. const currentVersion = '1.2.9.3'; // Sets the current version
  35.  
  36. function main() {
  37.  
  38. var stockfishObjectURL;
  39. var engine = document.engine = {};
  40. var myVars = document.myVars = {};
  41. myVars.autoMovePiece = false;
  42. myVars.autoRun = false;
  43. myVars.delay = 0.1;
  44. var myFunctions = document.myFunctions = {};
  45.  
  46.  
  47. stop_b = stop_w = 0;
  48. s_br = s_br2 = s_wr = s_wr2 = 0;
  49. obs = "";
  50. myFunctions.rescan = function(lev) {
  51. var ari = $("chess-board")
  52. .find(".piece")
  53. .map(function() {
  54. return this.className;
  55. })
  56. .get();
  57. jack = ari.map(f => f.substring(f.indexOf(' ') + 1));
  58. function removeWord(arr, word) {
  59. for (var i = 0; i < arr.length; i++) {
  60. arr[i] = arr[i].replace(word, '');
  61. }
  62. }
  63. removeWord(ari, 'square-');
  64. jack = ari.map(f => f.substring(f.indexOf(' ') + 1));
  65. for (var i = 0; i < jack.length; i++) {
  66. jack[i] = jack[i].replace('br', 'r')
  67. .replace('bn', 'n')
  68. .replace('bb', 'b')
  69. .replace('bq', 'q')
  70. .replace('bk', 'k')
  71. .replace('bb', 'b')
  72. .replace('bn', 'n')
  73. .replace('br', 'r')
  74. .replace('bp', 'p')
  75. .replace('wp', 'P')
  76. .replace('wr', 'R')
  77. .replace('wn', 'N')
  78. .replace('wb', 'B')
  79. .replace('br', 'R')
  80. .replace('wn', 'N')
  81. .replace('wb', 'B')
  82. .replace('wq', 'Q')
  83. .replace('wk', 'K')
  84. .replace('wb', 'B')
  85. }
  86. str2 = "";
  87. var count = 0,
  88. str = "";
  89. for (var j = 8; j > 0; j--) {
  90. for (var i = 1; i < 9; i++) {
  91. (str = (jack.find(el => el.includes([i] + [j])))) ? str = str.replace(/[^a-zA-Z]+/g, ''): str = "";
  92. if (str == "") {
  93. count++;
  94. str = count.toString();
  95. if (!isNaN(str2.charAt(str2.length - 1))) str2 = str2.slice(0, -1);
  96. else {
  97. count = 1;
  98. str = count.toString()
  99. }
  100. }
  101. str2 += str;
  102. if (i == 8) {
  103. count = 0;
  104. str2 += "/";
  105. }
  106. }
  107. }
  108. str2 = str2.slice(0, -1);
  109. //str2=str2+" KQkq - 0"
  110. color = "";
  111. wk = wq = bk = bq = "0";
  112. const move = $('vertical-move-list')
  113. .children();
  114. if (move.length < 2) {
  115. stop_b = stop_w = s_br = s_br2 = s_wr = s_wr2 = 0;
  116. }
  117. if (stop_b != 1) {
  118. if (move.find(".black.node:contains('K')")
  119. .length) {
  120. bk = "";
  121. bq = "";
  122. stop_b = 1;
  123. console.log('debug secb');
  124. }
  125. } else {
  126. bq = "";
  127. bk = "";
  128. }
  129. if (stop_b != 1)(bk = (move.find(".black.node:contains('O-O'):not(:contains('O-O-O'))")
  130. .length) ? "" : "k") ? (bq = (move.find(".black.node:contains('O-O-O')")
  131. .length) ? bk = "" : "q") : bq = "";
  132. if (s_br != 1) {
  133. if (move.find(".black.node:contains('R')")
  134. .text()
  135. .match('[abcd]+')) {
  136. bq = "";
  137. s_br = 1
  138. }
  139. } else bq = "";
  140. if (s_br2 != 1) {
  141. if (move.find(".black.node:contains('R')")
  142. .text()
  143. .match('[hgf]+')) {
  144. bk = "";
  145. s_br2 = 1
  146. }
  147. } else bk = "";
  148. if (stop_b == 0) {
  149. if (s_br == 0)
  150. if (move.find(".white.node:contains('xa8')")
  151. .length > 0) {
  152. bq = "";
  153. s_br = 1;
  154. console.log('debug b castle_r');
  155. }
  156. if (s_br2 == 0)
  157. if (move.find(".white.node:contains('xh8')")
  158. .length > 0) {
  159. bk = "";
  160. s_br2 = 1;
  161. console.log('debug b castle_l');
  162. }
  163. }
  164. if (stop_w != 1) {
  165. if (move.find(".white.node:contains('K')")
  166. .length) {
  167. wk = "";
  168. wq = "";
  169. stop_w = 1;
  170. console.log('debug secw');
  171. }
  172. } else {
  173. wq = "";
  174. wk = "";
  175. }
  176. if (stop_w != 1)(wk = (move.find(".white.node:contains('O-O'):not(:contains('O-O-O'))")
  177. .length) ? "" : "K") ? (wq = (move.find(".white.node:contains('O-O-O')")
  178. .length) ? wk = "" : "Q") : wq = "";
  179. if (s_wr != 1) {
  180. if (move.find(".white.node:contains('R')")
  181. .text()
  182. .match('[abcd]+')) {
  183. wq = "";
  184. s_wr = 1
  185. }
  186. } else wq = "";
  187. if (s_wr2 != 1) {
  188. if (move.find(".white.node:contains('R')")
  189. .text()
  190. .match('[hgf]+')) {
  191. wk = "";
  192. s_wr2 = 1
  193. }
  194. } else wk = "";
  195. if (stop_w == 0) {
  196. if (s_wr == 0)
  197. if (move.find(".black.node:contains('xa1')")
  198. .length > 0) {
  199. wq = "";
  200. s_wr = 1;
  201. console.log('debug w castle_l');
  202. }
  203. if (s_wr2 == 0)
  204. if (move.find(".black.node:contains('xh1')")
  205. .length > 0) {
  206. wk = "";
  207. s_wr2 = 1;
  208. console.log('debug w castle_r');
  209. }
  210. }
  211. if ($('.coordinates')
  212. .children()
  213. .first()
  214. .text() == 1) {
  215. str2 = str2 + " b " + wk + wq + bk + bq;
  216. color = "white";
  217. } else {
  218. str2 = str2 + " w " + wk + wq + bk + bq;
  219. color = "black";
  220. }
  221. //console.log(str2);
  222. return str2;
  223. }
  224. myFunctions.color = function(dat){
  225. response = dat;
  226. var res1 = response.substring(0, 2);
  227. var res2 = response.substring(2, 4);
  228.  
  229. if(myVars.autoMove == true){
  230. myFunctions.movePiece(res1, res2);
  231. }
  232. isThinking = false;
  233.  
  234. res1 = res1.replace(/^a/, "1")
  235. .replace(/^b/, "2")
  236. .replace(/^c/, "3")
  237. .replace(/^d/, "4")
  238. .replace(/^e/, "5")
  239. .replace(/^f/, "6")
  240. .replace(/^g/, "7")
  241. .replace(/^h/, "8");
  242. res2 = res2.replace(/^a/, "1")
  243. .replace(/^b/, "2")
  244. .replace(/^c/, "3")
  245. .replace(/^d/, "4")
  246. .replace(/^e/, "5")
  247. .replace(/^f/, "6")
  248. .replace(/^g/, "7")
  249. .replace(/^h/, "8");
  250. $(board.nodeName)
  251. .prepend('<div class="highlight square-' + res2 + ' bro" style="background-color: rgb(235, 97, 80); opacity: 0.71;" data-test-element="highlight"></div>')
  252. .children(':first')
  253. .delay(1800)
  254. .queue(function() {
  255. $(this)
  256. .remove();
  257. });
  258. $(board.nodeName)
  259. .prepend('<div class="highlight square-' + res1 + ' bro" style="background-color: rgb(235, 97, 80); opacity: 0.71;" data-test-element="highlight"></div>')
  260. .children(':first')
  261. .delay(1800)
  262. .queue(function() {
  263. $(this)
  264. .remove();
  265. });
  266. }
  267.  
  268. myFunctions.movePiece = function(from, to){
  269. for (var each=0;each<board.game.getLegalMoves().length;each++){
  270. if(board.game.getLegalMoves()[each].from == from){
  271. if(board.game.getLegalMoves()[each].to == to){
  272. var move = board.game.getLegalMoves()[each];
  273. board.game.move({
  274. ...move,
  275. promotion: 'false',
  276. animate: false,
  277. userGenerated: true
  278. });
  279. }
  280. }
  281. }
  282. }
  283.  
  284. function parser(e){
  285. if(e.data.includes('bestmove')){
  286. console.log(e.data.split(' ')[1]);
  287. myFunctions.color(e.data.split(' ')[1]);
  288. isThinking = false;
  289. }
  290. }
  291.  
  292. myFunctions.reloadChessEngine = function() {
  293. console.log(`Reloading the chess engine!`);
  294.  
  295. engine.engine.terminate();
  296. isThinking = false;
  297. myFunctions.loadChessEngine();
  298. }
  299.  
  300. myFunctions.loadChessEngine = function() {
  301. if(!stockfishObjectURL) {
  302. stockfishObjectURL = URL.createObjectURL(new Blob([GM_getResourceText('stockfish.js')], {type: 'application/javascript'}));
  303. }
  304. console.log(stockfishObjectURL);
  305. if(stockfishObjectURL) {
  306. engine.engine = new Worker(stockfishObjectURL);
  307.  
  308. engine.engine.onmessage = e => {
  309. parser(e);
  310. };
  311. engine.engine.onerror = e => {
  312. console.log("Worker Error: "+e);
  313. };
  314.  
  315. engine.engine.postMessage('ucinewgame');
  316. }
  317. console.log('loaded chess engine');
  318. }
  319.  
  320. var lastValue = 11;
  321. myFunctions.runChessEngine = function(depth){
  322. //var fen = myFunctions.rescan();
  323. var fen = board.game.getFEN();
  324. engine.engine.postMessage(`position fen ${fen}`);
  325. console.log('updated: ' + `position fen ${fen}`);
  326. isThinking = true;
  327. engine.engine.postMessage(`go depth ${depth}`);
  328. lastValue = depth;
  329. }
  330.  
  331. myFunctions.autoRun = function(lstValue){
  332. if(board.game.getTurn() == board.game.getPlayingAs()){
  333. myFunctions.runChessEngine(lstValue);
  334. }
  335. }
  336.  
  337. document.onkeydown = function(e) {
  338. switch (e.keyCode) {
  339. case 81:
  340. myFunctions.runChessEngine(1);
  341. break;
  342. case 87:
  343. myFunctions.runChessEngine(2);
  344. break;
  345. case 69:
  346. myFunctions.runChessEngine(3);
  347. break;
  348. case 82:
  349. myFunctions.runChessEngine(4);
  350. break;
  351. case 84:
  352. myFunctions.runChessEngine(5);
  353. break;
  354. case 89:
  355. myFunctions.runChessEngine(6);
  356. break;
  357. case 85:
  358. myFunctions.runChessEngine(7);
  359. break;
  360. case 73:
  361. myFunctions.runChessEngine(8);
  362. break;
  363. case 79:
  364. myFunctions.runChessEngine(9);
  365. break;
  366. case 80:
  367. myFunctions.runChessEngine(10);
  368. break;
  369. case 65:
  370. myFunctions.runChessEngine(11);
  371. break;
  372. case 83:
  373. myFunctions.runChessEngine(12);
  374. break;
  375. case 68:
  376. myFunctions.runChessEngine(13);
  377. break;
  378. case 70:
  379. myFunctions.runChessEngine(14);
  380. break;
  381. case 71:
  382. myFunctions.runChessEngine(15);
  383. break;
  384. case 72:
  385. myFunctions.runChessEngine(16);
  386. break;
  387. case 74:
  388. myFunctions.runChessEngine(17);
  389. break;
  390. case 75:
  391. myFunctions.runChessEngine(18);
  392. break;
  393. case 76:
  394. myFunctions.runChessEngine(19);
  395. break;
  396. case 90:
  397. myFunctions.runChessEngine(20);
  398. break;
  399. case 88:
  400. myFunctions.runChessEngine(21);
  401. break;
  402. case 67:
  403. myFunctions.runChessEngine(22);
  404. break;
  405. case 86:
  406. myFunctions.runChessEngine(23);
  407. break;
  408. case 66:
  409. myFunctions.runChessEngine(24);
  410. break;
  411. case 78:
  412. myFunctions.runChessEngine(25);
  413. break;
  414. case 77:
  415. myFunctions.runChessEngine(26);
  416. break;
  417. case 187:
  418. myFunctions.runChessEngine(100);
  419. break;
  420. }
  421. };
  422.  
  423. myFunctions.spinner = function() {
  424. if(isThinking == true){
  425. $('#overlay')[0].style.display = 'block';
  426. }
  427. if(isThinking == false) {
  428. $('#overlay')[0].style.display = 'none';
  429. }
  430. }
  431.  
  432. let dynamicStyles = null;
  433.  
  434. function addAnimation(body) {
  435. if (!dynamicStyles) {
  436. dynamicStyles = document.createElement('style');
  437. dynamicStyles.type = 'text/css';
  438. document.head.appendChild(dynamicStyles);
  439. }
  440.  
  441. dynamicStyles.sheet.insertRule(body, dynamicStyles.length);
  442. }
  443.  
  444.  
  445.  
  446.  
  447. var loaded = false;
  448. myFunctions.loadEx = function(){
  449. try{
  450. var tmpStyle;
  451. var tmpDiv;
  452. board = $('chess-board')[0] || $('wc-chess-board')[0];
  453. myVars.board = board;
  454.  
  455. var div = document.createElement('div')
  456. var content = `<div style="margin: 0 0 0 8px;"><br><p id="depthText"> Your Current Depth Is: 11 </p><p> Press a key on your keyboard to change this!</p><br><input type="checkbox" id="autoRun" name="autoRun" value="false">
  457. <label for="autoRun"> Enable auto run</label><br>
  458. <input type="checkbox" id="autoMove" name="autoMove" value="false">
  459. <label for="autoMove"> Enable auto move</label><br>
  460. <input type="number" id="timeDelayMin" name="timeDelayMin" min="0.1" value=0.1>
  461. <label for="timeDelayMin">Auto Run Delay Minimum(Seconds)</label><br>
  462. <input type="number" id="timeDelayMax" name="timeDelayMax" min="0.1" value=1>
  463. <label for="timeDelayMax">Auto Run Delay Maximum(Seconds)</label></div>`
  464. div.innerHTML = content;
  465. div.setAttribute('style','background-color:white; height:auto;');
  466. div.setAttribute('id','settingsContainer');
  467.  
  468. board.parentElement.parentElement.appendChild(div);
  469.  
  470. //spinnerContainer
  471. var spinCont = document.createElement('div');
  472. spinCont.setAttribute('style','display:none;');
  473. spinCont.setAttribute('id','overlay');
  474. div.prepend(spinCont);
  475. //spinner
  476. var spinr = document.createElement('div')
  477. spinr.setAttribute('style',`
  478. margin: 0 auto;
  479. height: 64px;
  480. width: 64px;
  481. animation: rotate 0.8s infinite linear;
  482. border: 5px solid firebrick;
  483. border-right-color: transparent;
  484. border-radius: 50%;
  485. `);
  486. spinCont.appendChild(spinr);
  487. addAnimation(`@keyframes rotate {
  488. 0% {
  489. transform: rotate(0deg);
  490. }
  491. 100% {
  492. transform: rotate(360deg);
  493. }
  494. }`);
  495.  
  496.  
  497. //Reload Button
  498. var reSty = `
  499. #relButDiv {
  500. position: relative;
  501. text-align: center;
  502. margin: 0 0 8px 0;
  503. }
  504. #relEngBut {
  505. position: relative;
  506. color: #ffef85;
  507. background-color: #3cba2c;
  508. font-size: 19px;
  509. border: 1px solid #000000;
  510. padding: 15px 50px;
  511. letter-spacing: 1px;
  512. cursor: pointer
  513. }
  514. #relEngBut:hover {
  515. color: #000000;
  516. background-color: #ba1212;
  517. }
  518. #relEngBut:active {
  519. background-color: #ba1212;
  520. transform: translateY(4px);
  521. }`;
  522. var reBut = `<button type="button" name="reloadEngine" id="relEngBut" onclick="document.myFunctions.reloadChessEngine()">Reload Chess Engine</button>`;
  523. tmpDiv = document.createElement('div');
  524. var relButDiv = document.createElement('div');
  525. relButDiv.id = 'relButDiv';
  526. tmpDiv.innerHTML = reBut;
  527. reBut = tmpDiv.firstChild;
  528.  
  529. tmpStyle = document.createElement('style');
  530. tmpStyle.innerHTML = reSty;
  531. document.head.append(tmpStyle);
  532.  
  533. relButDiv.append(reBut);
  534. div.append(relButDiv);
  535.  
  536. // Issue Button
  537. var isBut = `<button type="button" name="isBut" onclick="window.confirm('Can I take you to the issues page?') ? document.location = 'https://github.com/Auzgame/userscripts/issues' : console.log('cancled')">Got An Issue/Bug?</button>`;
  538. tmpDiv = document.createElement('div');
  539. var isButDiv = document.createElement('div');
  540.  
  541. isButDiv.style = `
  542.  
  543. position: relative;
  544. text-align: center;
  545. margin: 0 0 8px 0;
  546.  
  547. `;
  548.  
  549. tmpDiv.innerHTML = isBut;
  550. isBut = tmpDiv.firstChild;
  551.  
  552. isBut.id = 'isBut';
  553. isBut.style = `
  554.  
  555. position: relative;
  556. color: #ffef85;
  557. background-color: #919191;
  558. font-size: 19px;
  559. border: 1px solid #000000;
  560. padding: 15px 50px;
  561. letter-spacing: 1px;
  562. cursor: pointer;
  563.  
  564. `;
  565.  
  566. isButDiv.append(isBut);
  567. div.append(isButDiv);
  568.  
  569. loaded = true;
  570. } catch (error) {console.log(error)}
  571. }
  572.  
  573.  
  574. function other(delay){
  575. var endTime = Date.now() + delay;
  576. var timer = setInterval(()=>{
  577. if(Date.now() >= endTime){
  578. myFunctions.autoRun(lastValue);
  579. canGo = true;
  580. clearInterval(timer);
  581. }
  582. },10);
  583. }
  584.  
  585.  
  586. async function getVersion(){
  587. var GF = new GreasyFork; // set upping api
  588. var code = await GF.get().script().code(460208); // Get code
  589. var version = GF.parseScriptCodeMeta(code).filter(e => e.meta === '@version')[0].value; // filtering array and getting value of @version
  590.  
  591. if(currentVersion !== version){
  592. while(true){
  593. alert('UPDATE THIS SCRIPT IN ORDER TO PROCEED!');
  594. }
  595. }
  596. }
  597.  
  598. //Removed due to script being reported. I tried to make it so people can know when bug fixes come out. Clearly people don't like that.
  599. //getVersion();
  600.  
  601. const waitForChessBoard = setInterval(() => {
  602. if(loaded) {
  603. board = $('chess-board')[0] || $('wc-chess-board')[0];
  604. myVars.autoRun = $('#autoRun')[0].checked;
  605. myVars.autoMove = $('#autoMove')[0].checked;
  606. let minDel = parseInt($('#timeDelayMin')[0].value);
  607. let maxDel = parseInt($('#timeDelayMax')[0].value);
  608. myVars.delay = Math.random() * (maxDel - minDel) + minDel;
  609. myVars.isThinking = isThinking;
  610. myFunctions.spinner();
  611. if(board.game.getTurn() == board.game.getPlayingAs()){myTurn = true;} else {myTurn = false;}
  612. $('#depthText')[0].innerHTML = "Your Current Depth Is: <strong>"+lastValue+"</strong>";
  613. } else {
  614. myFunctions.loadEx();
  615. }
  616.  
  617.  
  618. if(!engine.engine){
  619. myFunctions.loadChessEngine();
  620. }
  621. if(myVars.autoRun == true && canGo == true && isThinking == false && myTurn){
  622. //console.log(`going: ${canGo} ${isThinking} ${myTurn}`);
  623. canGo = false;
  624. var currentDelay = myVars.delay != undefined ? myVars.delay * 1000 : 10;
  625. other(currentDelay);
  626. }
  627. }, 100);
  628. }
  629.  
  630. //Touching below may break the script
  631.  
  632. var isThinking = false
  633. var canGo = true;
  634. var myTurn = false;
  635. var board;
  636.  
  637.  
  638.  
  639.  
  640.  
  641.  
  642.  
  643.  
  644.  
  645.  
  646.  
  647.  
  648.  
  649.  
  650.  
  651.  
  652.  
  653.  
  654.  
  655.  
  656.  
  657.  
  658.  
  659.  
  660.  
  661.  
  662.  
  663.  
  664.  
  665.  
  666.  
  667.  
  668.  
  669. window.addEventListener("load", (event) => {
  670. let currentTime = Date.now();
  671. main();
  672. });