You might be wondering, how one creates an Chess AI? or how bad is Daniel at Chess exactly?
For those two questions, two short answers:
It's easy
Very bad
Let's elaborate on the how
First of all, we need an GUI. I chose Javascript since there are many chess libraries available to choose from. That's very convenient since I didn't want to re-invent the wheel.
I'm not a chess expert. I took these values from the incredible chess engine Sunfish
Evaluate
Chess is a zero-sum game. (One player's advantage is equivalent to the other player's loss). There are various existing algorithms that solve ‘zero-sum' problems. Like: Negamax or Minimax
No matter the algorithm we chose, we need an evaluation function that calculates the board's positions and returns a score.
We will use this score to let the AI know which positions are good or bad.
// Idea behind evaluation function
function evaluateBoard(game: Chess) {
const board = game.board();
let totalEvaluation = 0;
for (let row = 0; row < 8; row++) {
for (let col = 0; col < 8; col++) {
totalEvaluation += getPieceValue(board[row][col], row, col);
}
}
return totalEvaluation;
}
I chose to implement the Minimax algorithm with Alpha-beta prunning. What do those fancy words mean?
Minimax algorithm:
A minimax algorithm[5] is a recursive algorithm for choosing the next move in an n-player game, usually a two-player game. A value is associated with each position or state of the game. This value is computed by means of a position evaluation function and it indicates how good it would be for a player to reach that position. The player then makes the move that maximizes the minimum value of the position resulting from the opponent's possible following moves.
Wow, that is awesome! but I didn't understand a single word!
I recommend watching John Levine's awesome video explaining how the Minimax algorithm with Alpha Prunning works: Minimax Explanation
In simple words: Minimax recursevily evaluates the possible moves and alpha-prunning makes it go fast*
/**Alpha = best value for MAXBeta = best value for MINDepth = depth of searchmaximizingPlayer = AI**/type AlphaBetaReturn = [bestScore:number, bestMove: Move |null];type AlphaBeta = { game: Chess; alpha:number; beta:number; depth:number; maximizingPlayer:boolean;};functionminimax({ game, alpha, beta, depth, maximizingPlayer,}: AlphaBeta): AlphaBetaReturn { movesAnalised++; let bestMove: Move |null= null;if (depth ===0) { return [evaluateBoard(game), null]; } const possibleMoves = game.moves({ verbose: true }) as Move[];// Sort randomly to avoid same moves being chosen every time possibleMoves.sort(() =>0.5-Math.random()); let maxValue =Number.NEGATIVE_INFINITY; let minValue =Number.POSITIVE_INFINITY;for (const move of possibleMoves) { game.move(move); const [childValue, _] =minimax({ game, alpha, beta, depth: depth -1, maximizingPlayer:!maximizingPlayer, }); game.undo();if (maximizingPlayer) {if (childValue > maxValue) { maxValue = childValue; bestMove = move; }if (childValue > alpha) { alpha = childValue; } } else {if (childValue < minValue) { minValue = childValue; bestMove = move; }if (childValue < beta) { beta = childValue; } }if (alpha >= beta) { break; } } return maximizingPlayer ? [maxValue, bestMove] : [minValue, bestMove];}functioncalculateBestMove(depthLvl:number): [Move,number] { movesAnalised =0; let alpha =Number.NEGATIVE_INFINITY; let beta =Number.POSITIVE_INFINITY; let move = chess.moves({ verbose: true })[0] as Move; const [bestScore, bestMove] =minimax({ game: chess, alpha, beta, depth: depthLvl, maximizingPlayer: true, }); return bestMove === null ? [move, bestScore] : [bestMove, bestScore];}
Good to know:
There is a thing called The horizon effect, which is caused by limited depth of the search algorithm. You can further reduce it by adding quiescence search.
More humane AI 🔊
To soft things off, I added some voice audios to the AI, to make the ass whooping more fun!
Chess AI
2022 Dec 05 See all postsI built an AI that plays chess and it kicked my ass
Play a game
Source code
What does it do?
How?
You might be wondering, how one creates an Chess AI? or how bad is Daniel at Chess exactly?
For those two questions, two short answers:
Let's elaborate on the how
First of all, we need an GUI. I chose Javascript since there are many chess libraries available to choose from. That's very convenient since I didn't want to re-invent the wheel.
I used:
Once we got the board and input validation going, things start to get interesting...
AI 🤖
We don't want an AI that just plays random moves, so we need to give it data to evaluate which moves are better.
First, each piece needs a value:
Each piece's position in the board needs a value too
Get the whole table scores here: Board scores
I'm not a chess expert. I took these values from the incredible chess engine Sunfish
Evaluate
Chess is a zero-sum game. (One player's advantage is equivalent to the other player's loss). There are various existing algorithms that solve ‘zero-sum' problems. Like: Negamax or Minimax
No matter the algorithm we chose, we need an evaluation function that calculates the board's positions and returns a score.
We will use this score to let the AI know which positions are good or bad.
Get the whole function: Evaluation function
Think AI, think! 🧠
I chose to implement the Minimax algorithm with Alpha-beta prunning. What do those fancy words mean?
Minimax algorithm:
Alpha-prunning:
Wow, that is awesome! but I didn't understand a single word!
I recommend watching John Levine's awesome video explaining how the Minimax algorithm with Alpha Prunning works: Minimax Explanation
In simple words: Minimax recursevily evaluates the possible moves and alpha-prunning makes it go fast*
Good to know:
There is a thing called The horizon effect, which is caused by limited depth of the search algorithm. You can further reduce it by adding quiescence search.
More humane AI 🔊
To soft things off, I added some voice audios to the AI, to make the ass whooping more fun!
Audio data schema and rest of functionality available here: source code
Outro
I encorage you to try it out and play a game here 👌❤️: Play a game
Hope you have a fun time!
UI Design:
Daniel Ratmiroff © - site made with: blogmaker - credit to Vitalik Buterin