If you are willing to touch some JavaScript (or maybe you already know some coding basics) you'll be suprised how easy it is to "hack" most popular chess websites.
Before we proceed, little disclaimer: this showcase is for learning purposes. We don't want to act like assholes, ruining other people's fun, right? Please don't use it in online games because most likely you'll get banned.
Agreed? Great! Now let's make some experiments playing chess.com bots!
1. First steps.
For this tutorial you can use any browser with DevTools. I'll be using Google Chrome.
Go to https://www.chess.com/play/computer and pick up some bot to start a game.
Hit F12 to open DevTools.
2. Investigation. Let's see what we've got and what we need.
First of all, we need to check out current pieces position on the board. If you dive into HTML source, you'll see that every move we make sits inside
.vertical-move-list
element.Move your pawn and after typing following line in the console:
document.querySelector('.vertical-move-list').innerHTML
... you'll see something like this:
'<div class="move" data-whole-move-number="1">1.<div data-ply="1" class="white node">d4</div><div data-ply="2" class="black node selected">e6</div></div>'
Okay. So we need - somehow - to pass this information to the chess engine and let it figure out what is the next best move.
3. Coding time.
To achieve that, we can use free services like chess-api.com (which is basicaly just online Stockfish service with a handy REST API).
And following code is just copy-paste from their docs:
// Function for sending requests: async function postChessApi(data = {}) { const response = await fetch("https://chess-api.com/v1", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data), }); return response.json(); }
Paste that code into DevTools console and we are half way there.
In our case next step is just a no-brainer because we pass whole HTML as "input" parameter. Let's create a function:
function giveMeBestMove() { postChessApi({ input: document.querySelector('.vertical-move-list').outerHTML }).then((data) => { console.log(data); }); }
Now let's run it:
giveMeBestMove();
If we didn't screw anything up, you should see something like this:
{text: 'Move b1 → c3 (Nc3): [0.67]. White is winning. Depth 12.', captured: false, promotion: false, isCapture: false, isPromotion: false, …}
Congratulations!
You just made your own chess hack - a basic chess bot able to find best move for current position on chess.com.
4. Extra improvements.
You can try to improve it by binding function to some key or even display it on the page.
Create improved function:
function giveMeBestMoveAndDisplayItInBubble() { postChessApi({ input: document.querySelector('.vertical-move-list').outerHTML }).then((data) => { var bubble = document.querySelector('#bubble'); if (!bubble) { bubble = document.createElement('div'); bubble.id = "bubble"; bubble.style = "position: fixed; bottom: 0; right: 0; background: yellow;"; document.body.prepend(bubble); } bubble.innerText = data.text; }); }
Add keyup
event listener so the function runs after you hit CTRL
+ Q
buttons.
window.addEventListener('keyup', function (e) {
if (e.key == 'q' && e.ctrlKey) {
e.preventDefault();
giveMeBestMoveAndDisplayItInBubble();
}
});
5. Complete code to copy-paste and conclusion.
Ok, at this point we can get together whole working code. You can copy-paste this code into console to se it in action:
// 1. Function for sending requests:
async function postChessApi(data = {}) {
const response = await fetch("https://chess-api.com/v1", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data),
});
return response.json();
}
// 2. Function which shows the best move:
function giveMeBestMoveAndDisplayItInBubble() {
postChessApi({ input: document.querySelector('.vertical-move-list').outerHTML }).then((data) => {
var bubble = document.querySelector('#bubble');
if (!bubble) {
bubble = document.createElement('div');
bubble.id = "bubble";
bubble.style = "position: fixed; bottom: 0; right: 0; background: yellow; font-size: 2rem;";
document.body.prepend(bubble);
}
bubble.innerText = data.text;
});
}
// 3. Key binding:
window.addEventListener('keyup', function (e) {
if (e.key == 'q' && e.ctrlKey) {
e.preventDefault();
giveMeBestMoveAndDisplayItInBubble();
}
});
If you want you can go really crazy with it. Like use WebSockets, draw arrows and who the hell knows what's more.
Hope you enjoyed this tutorial! Good luck!
Dr. Edward Vil.