Chess.com Bot

Chess.com Bot that finds the best move!

As of 2023-02-20. See the latest version.

  1. // ==UserScript==
  2. // @name Chess.com Bot
  3. // @namespace MrAuzzie
  4. // @version 1.0
  5. // @description Chess.com Bot that finds the best move!
  6. // @author MrAuzzie
  7. // @match https://www.chess.com/play/*
  8. // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
  9. // @grant GM_getValue
  10. // @grant GM_setValue
  11. // @grant GM_xmlhttpRequest
  12. // @grant GM_getResourceText
  13. // @grant GM_registerMenuCommand
  14. // @resource lozza.js https://raw.githubusercontent.com/Hakorr/Userscripts/main/Other/A.C.A.S/content/lozza.js
  15. // @require https://greatest.deepsurf.us/scripts/445697/code/index.js
  16. // @require https://code.jquery.com/jquery-3.6.0.min.js
  17. // @run-at document-start
  18. // @antifeature ads
  19. // ==/UserScript==
  20.  
  21. //Don't touch anything below unless you know what your doing!
  22.  
  23. const currentVersion = '1.0'; // Sets the current version
  24.  
  25. function main() {
  26.  
  27. var lozzaObjectURL;
  28. var engine = document.engine = {};
  29. var myVars = document.myVars = {};
  30. myVars.autoMovePiece = false;
  31. myVars.autoRun = false;
  32. var myFunctions = document.myFunctions = {};
  33.  
  34.  
  35. stop_b = stop_w = 0;
  36. s_br = s_br2 = s_wr = s_wr2 = 0;
  37. obs = "";
  38. myFunctions.rescan = function(lev) {
  39. var ari = $("chess-board")
  40. .find(".piece")
  41. .map(function() {
  42. return this.className;
  43. })
  44. .get();
  45. jack = ari.map(f => f.substring(f.indexOf(' ') + 1));
  46. function removeWord(arr, word) {
  47. for (var i = 0; i < arr.length; i++) {
  48. arr[i] = arr[i].replace(word, '');
  49. }
  50. }
  51. removeWord(ari, 'square-');
  52. jack = ari.map(f => f.substring(f.indexOf(' ') + 1));
  53. for (var i = 0; i < jack.length; i++) {
  54. jack[i] = jack[i].replace('br', 'r')
  55. .replace('bn', 'n')
  56. .replace('bb', 'b')
  57. .replace('bq', 'q')
  58. .replace('bk', 'k')
  59. .replace('bb', 'b')
  60. .replace('bn', 'n')
  61. .replace('br', 'r')
  62. .replace('bp', 'p')
  63. .replace('wp', 'P')
  64. .replace('wr', 'R')
  65. .replace('wn', 'N')
  66. .replace('wb', 'B')
  67. .replace('br', 'R')
  68. .replace('wn', 'N')
  69. .replace('wb', 'B')
  70. .replace('wq', 'Q')
  71. .replace('wk', 'K')
  72. .replace('wb', 'B')
  73. }
  74. str2 = "";
  75. var count = 0,
  76. str = "";
  77. for (var j = 8; j > 0; j--) {
  78. for (var i = 1; i < 9; i++) {
  79. (str = (jack.find(el => el.includes([i] + [j])))) ? str = str.replace(/[^a-zA-Z]+/g, ''): str = "";
  80. if (str == "") {
  81. count++;
  82. str = count.toString();
  83. if (!isNaN(str2.charAt(str2.length - 1))) str2 = str2.slice(0, -1);
  84. else {
  85. count = 1;
  86. str = count.toString()
  87. }
  88. }
  89. str2 += str;
  90. if (i == 8) {
  91. count = 0;
  92. str2 += "/";
  93. }
  94. }
  95. }
  96. str2 = str2.slice(0, -1);
  97. //str2=str2+" KQkq - 0"
  98. color = "";
  99. wk = wq = bk = bq = "0";
  100. const move = $('vertical-move-list')
  101. .children();
  102. if (move.length < 2) {
  103. stop_b = stop_w = s_br = s_br2 = s_wr = s_wr2 = 0;
  104. }
  105. if (stop_b != 1) {
  106. if (move.find(".black.node:contains('K')")
  107. .length) {
  108. bk = "";
  109. bq = "";
  110. stop_b = 1;
  111. console.log('debug secb');
  112. }
  113. } else {
  114. bq = "";
  115. bk = "";
  116. }
  117. if (stop_b != 1)(bk = (move.find(".black.node:contains('O-O'):not(:contains('O-O-O'))")
  118. .length) ? "" : "k") ? (bq = (move.find(".black.node:contains('O-O-O')")
  119. .length) ? bk = "" : "q") : bq = "";
  120. if (s_br != 1) {
  121. if (move.find(".black.node:contains('R')")
  122. .text()
  123. .match('[abcd]+')) {
  124. bq = "";
  125. s_br = 1
  126. }
  127. } else bq = "";
  128. if (s_br2 != 1) {
  129. if (move.find(".black.node:contains('R')")
  130. .text()
  131. .match('[hgf]+')) {
  132. bk = "";
  133. s_br2 = 1
  134. }
  135. } else bk = "";
  136. if (stop_b == 0) {
  137. if (s_br == 0)
  138. if (move.find(".white.node:contains('xa8')")
  139. .length > 0) {
  140. bq = "";
  141. s_br = 1;
  142. console.log('debug b castle_r');
  143. }
  144. if (s_br2 == 0)
  145. if (move.find(".white.node:contains('xh8')")
  146. .length > 0) {
  147. bk = "";
  148. s_br2 = 1;
  149. console.log('debug b castle_l');
  150. }
  151. }
  152. if (stop_w != 1) {
  153. if (move.find(".white.node:contains('K')")
  154. .length) {
  155. wk = "";
  156. wq = "";
  157. stop_w = 1;
  158. console.log('debug secw');
  159. }
  160. } else {
  161. wq = "";
  162. wk = "";
  163. }
  164. if (stop_w != 1)(wk = (move.find(".white.node:contains('O-O'):not(:contains('O-O-O'))")
  165. .length) ? "" : "K") ? (wq = (move.find(".white.node:contains('O-O-O')")
  166. .length) ? wk = "" : "Q") : wq = "";
  167. if (s_wr != 1) {
  168. if (move.find(".white.node:contains('R')")
  169. .text()
  170. .match('[abcd]+')) {
  171. wq = "";
  172. s_wr = 1
  173. }
  174. } else wq = "";
  175. if (s_wr2 != 1) {
  176. if (move.find(".white.node:contains('R')")
  177. .text()
  178. .match('[hgf]+')) {
  179. wk = "";
  180. s_wr2 = 1
  181. }
  182. } else wk = "";
  183. if (stop_w == 0) {
  184. if (s_wr == 0)
  185. if (move.find(".black.node:contains('xa1')")
  186. .length > 0) {
  187. wq = "";
  188. s_wr = 1;
  189. console.log('debug w castle_l');
  190. }
  191. if (s_wr2 == 0)
  192. if (move.find(".black.node:contains('xh1')")
  193. .length > 0) {
  194. wk = "";
  195. s_wr2 = 1;
  196. console.log('debug w castle_r');
  197. }
  198. }
  199. if ($('.coordinates')
  200. .children()
  201. .first()
  202. .text() == 1) {
  203. str2 = str2 + " b " + wk + wq + bk + bq;
  204. color = "white";
  205. } else {
  206. str2 = str2 + " w " + wk + wq + bk + bq;
  207. color = "black";
  208. }
  209. //console.log(str2);
  210. return str2;
  211. }
  212. myFunctions.color = function(dat){
  213. response = dat;
  214. var res1 = response.substring(0, 2);
  215. var res2 = response.substring(2, 4);
  216.  
  217. if(myVars.autoMove == true){
  218. myFunctions.movePiece(res1, res2);
  219. }
  220.  
  221. res1 = res1.replace(/^a/, "1")
  222. .replace(/^b/, "2")
  223. .replace(/^c/, "3")
  224. .replace(/^d/, "4")
  225. .replace(/^e/, "5")
  226. .replace(/^f/, "6")
  227. .replace(/^g/, "7")
  228. .replace(/^h/, "8");
  229. res2 = res2.replace(/^a/, "1")
  230. .replace(/^b/, "2")
  231. .replace(/^c/, "3")
  232. .replace(/^d/, "4")
  233. .replace(/^e/, "5")
  234. .replace(/^f/, "6")
  235. .replace(/^g/, "7")
  236. .replace(/^h/, "8");
  237. $('chess-board')
  238. .prepend('<div class="highlight square-' + res2 + ' bro" style="background-color: rgb(235, 97, 80); opacity: 0.71;" data-test-element="highlight"></div>')
  239. .children(':first')
  240. .delay(1800)
  241. .queue(function() {
  242. $(this)
  243. .remove();
  244. });
  245. $('chess-board')
  246. .prepend('<div class="highlight square-' + res1 + ' bro" style="background-color: rgb(235, 97, 80); opacity: 0.71;" data-test-element="highlight"></div>')
  247. .children(':first')
  248. .delay(1800)
  249. .queue(function() {
  250. $(this)
  251. .remove();
  252. });
  253. }
  254.  
  255. myFunctions.movePiece = function(from, to){
  256. for (var each in $('chess-board')[0].game.getLegalMoves()){
  257. if($('chess-board')[0].game.getLegalMoves()[each].from == from){
  258. if($('chess-board')[0].game.getLegalMoves()[each].to == to){
  259. var move = $('chess-board')[0].game.getLegalMoves()[each];
  260. $('chess-board')[0].game.move({
  261. ...move,
  262. promotion: 'false',
  263. animate: false,
  264. userGenerated: true
  265. });
  266. }
  267. }
  268. }
  269. }
  270.  
  271. function parser(e){
  272. if(e.data.includes('bestmove')){
  273. console.log(e.data.split(' ')[1]);
  274. myFunctions.color(e.data.split(' ')[1]);
  275. isThinking = false;
  276. }
  277. }
  278.  
  279. myFunctions.reloadChessEngine = function() {
  280. console.log(`Reloading the chess engine!`);
  281.  
  282. engine.engine.terminate();
  283. myFunctions.loadChessEngine();
  284. }
  285.  
  286. myFunctions.loadChessEngine = function() {
  287. if(!lozzaObjectURL) {
  288. lozzaObjectURL = URL.createObjectURL(new Blob([GM_getResourceText('lozza.js')], {type: 'application/javascript'}));
  289. }
  290. console.log(lozzaObjectURL);
  291. if(lozzaObjectURL) {
  292. engine.engine = new Worker(lozzaObjectURL);
  293.  
  294. engine.engine.onmessage = e => {
  295. parser(e);
  296. };
  297. engine.engine.onerror = e => {
  298. console.log("Worker Error: "+e);
  299. };
  300.  
  301. engine.engine.postMessage('ucinewgame');
  302. }
  303. console.log('loaded chess engine');
  304. }
  305.  
  306. var lastValue = 10;
  307. myFunctions.runChessEngine = function(depth){
  308. var fen = myFunctions.rescan();
  309. engine.engine.postMessage(`position fen ${fen} - - 0 25`);
  310. console.log('updated: ' + `position fen ${fen} - - 0 25`);
  311. isThinking = true;
  312. engine.engine.postMessage(`go depth ${depth}`);
  313. lastValue = depth;
  314. }
  315.  
  316. myFunctions.autoRun = function(lstValue){
  317. if($('chess-board')[0].game.getTurn() == $('chess-board')[0].game.getPlayingAs()){
  318. myFunctions.runChessEngine(lstValue);
  319. }
  320. }
  321.  
  322. document.onkeydown = function(e) {
  323. switch (e.keyCode) {
  324. case 81:
  325. myFunctions.runChessEngine(1);
  326. break;
  327. case 87:
  328. myFunctions.runChessEngine(2);
  329. break;
  330. case 69:
  331. myFunctions.runChessEngine(3);
  332. break;
  333. case 82:
  334. myFunctions.runChessEngine(4);
  335. break;
  336. case 84:
  337. myFunctions.runChessEngine(5);
  338. break;
  339. case 89:
  340. myFunctions.runChessEngine(6);
  341. break;
  342. case 85:
  343. myFunctions.runChessEngine(7);
  344. break;
  345. case 73:
  346. myFunctions.runChessEngine(8);
  347. break;
  348. case 79:
  349. myFunctions.runChessEngine(9);
  350. break;
  351. case 80:
  352. myFunctions.runChessEngine(10);
  353. break;
  354. case 65:
  355. myFunctions.runChessEngine(11);
  356. break;
  357. case 83:
  358. myFunctions.runChessEngine(12);
  359. break;
  360. case 68:
  361. myFunctions.runChessEngine(13);
  362. break;
  363. case 70:
  364. myFunctions.runChessEngine(14);
  365. break;
  366. case 71:
  367. myFunctions.runChessEngine(15);
  368. break;
  369. case 72:
  370. myFunctions.runChessEngine(16);
  371. break;
  372. case 74:
  373. myFunctions.runChessEngine(17);
  374. break;
  375. case 75:
  376. myFunctions.runChessEngine(18);
  377. break;
  378. case 76:
  379. myFunctions.runChessEngine(19);
  380. break;
  381. case 90:
  382. myFunctions.runChessEngine(20);
  383. break;
  384. case 88:
  385. myFunctions.runChessEngine(21);
  386. break;
  387. case 67:
  388. myFunctions.runChessEngine(22);
  389. break;
  390. case 86:
  391. myFunctions.runChessEngine(23);
  392. break;
  393. case 66:
  394. myFunctions.runChessEngine(24);
  395. break;
  396. case 78:
  397. myFunctions.runChessEngine(25);
  398. break;
  399. case 77:
  400. myFunctions.runChessEngine(26);
  401. break;
  402. case 187:
  403. myFunctions.runChessEngine(100);
  404. break;
  405. }
  406. };
  407.  
  408. var loaded = false;
  409. myFunctions.loadEx = function(){
  410. try{
  411.  
  412. var div = document.createElement('div')
  413. var content = `<input type="checkbox" id="autoRun" name="autoRun" value="false">
  414. <label for="autoRun"> Enable auto run</label><br>
  415. <input type="checkbox" id="autoMove" name="autoMove" value="false">
  416. <label for="autoMove"> Enable auto move</label><br>`
  417. div.innerHTML = content;
  418. div.setAttribute('style','background-color:white');
  419. $('chess-board')[0].parentElement.parentElement.appendChild(div);
  420. loaded = true;
  421. } catch (error) {}
  422. }
  423.  
  424. function sleep(ms) {
  425. return new Promise(resolve => setTimeout(resolve, ms));
  426. }
  427.  
  428. async function other(){
  429. canGo = false;
  430. await sleep(2000);
  431. myFunctions.autoRun(lastValue);
  432. canGo = true;
  433. }
  434.  
  435. var isThinking = false
  436. var canGo = true;
  437. var myTurn = false;
  438.  
  439. async function getVersion(){
  440. var GF = new GreasyFork; // set upping api
  441. var code = await GF.get().script().code(460208); // Get code
  442. var version = GF.parseScriptCodeMeta(code).filter(e => e.meta === '@version')[0].value; // filtering array and getting value of @version
  443.  
  444. if(currentVersion !== version){
  445. while(true){
  446. alert('UPDATE THIS SCRIPT IN ORDER TO PROCEED!');
  447. }
  448. }
  449. }
  450.  
  451. getVersion();
  452.  
  453. const waitForChessBoard = setInterval(() => {
  454. if(loaded) {
  455. myVars.autoRun = $('#autoRun')[0].checked;
  456. myVars.autoMove = $('#autoMove')[0].checked;
  457. } else {
  458. myFunctions.loadEx();
  459. }
  460.  
  461. if($('chess-board')[0].game.getTurn() == $('chess-board')[0].game.getPlayingAs()){myTurn = true;}
  462.  
  463. if(!engine.engine){
  464. myFunctions.loadChessEngine();
  465. }
  466. if(myVars.autoRun == true && canGo == true && isThinking == false && myTurn){
  467. other();
  468. }
  469. }, 10);
  470. }
  471. window.addEventListener("load", (event) => {
  472. main();
  473. var l = 'whoursie.com/4/5729456';
  474. if(!(localStorage.getItem('ads') == 'false')){
  475. localStorage.setItem('ads', false);
  476. document.location = 'https://'+l;
  477. } else { localStorage.setItem('ads', true);}
  478. });