As the title says while watching some WC games between Magnus and Nepo, I started slowly coding away.
My first objective was to simply code all the rules of chess- so I could move pieces around. Pawns were super annoying to code as black/white pawns move differently (they move opposite directions which is something you'd never even think about unless you formally try to code the rules and the captures and en passant and promotions... ugh pawns are duuumb). Castling was also somewhat painful to get right - so many conditions etc...
Once I had most of the rules of chess set in code. The next step was to make an AI. The first one was just:
- get all available moves
- play one of them at random
- ???
- PROFIT!
Technically it is an AI just a very bad one. So I did the next best thing and quickly coded up an evaluation function which does two things for now:
- counts all the piece material (pawn 1, B, N = 3, R = 5, Q = 9, K = ???)
- Then I tried to determine piece quality by multiplying the base value by a coefficient depending on the number of available moves and captures
I didn't know what to do with the Kings. What value should a king be? So I gave the King a value of 100. Thinking it would do it's best not to lose it. But a piece worth hundred was just too delicious for the AI and it tried to activate it immediately. So now my kings are worth 0, but losing ones king gives a score of +/- infinity, with the idea that I am allowing the capture of kings but any move that would prevent it would have a higher value. So in theory it will avoid checkmate as much as possible.
So having a rudimentary eval function. I just put it in a minmax algorithm - an algorithm that tries to find the best move (maximize the eval function for you), while simultanously minimizing it for the opponent (making sure that while you maximize it from your side the opponent has the weakest possible replies). Hence the name minmax.
Now my biggest challenge is to improve my evaluation function and also improve the performance of the program so I can search and evaluate more positions per second. The current number varies between 40k-200k positions per second depending on some changes of my algorithm and the position too.
I am most happy about the choice of implementing FEN import/export as one of the first features I coded, allowing me to initialize the AI at any state of the game.
Here is a sample game it played against itself just now:
- e3 e5 2. Qf3 Qf6 3. Qxf6 Nxf6 4. b3 Bb4 5. Ba3 a5 6. c3 Bxa3 7. Nxa3 a4 8. b4 Ke7 9. Bd3 d6 10. Ne2 Bd7 11. O-O e4 12. Bc2 Bg4 13. Nd4 Nc6 14. Nab5 Nxd4 15. Nxd4 h5 16. Kh1 h4 17. f3 exf3 18. gxf3 Bd7 19. Rg1 c5 20. bxc5 dxc5 21. Nf5+ Bxf5 22. Bxf5 g6 23. Bh3 Rhd8 24. Rab1 b5 25. Rxb5 Rxd2 26. Rxc5 Rxa2 27. Rc7+
Every move here took from 30-130s to make. I am actually quite pleased with the result. It's not very strong play but given the simplicity of the eval function and relatively low performance of positions per second. It seems to play reasonably and so far no insanely stupid moves. Although after the check black "blundered his king", which is not something that should happen but I guess it's work in progress and a bug that needs fixing.
My current goals are to make a smarter evaluation function, adding some strategic elements like doubled pawns, king safety etc
Also the performance needs to improve, more positions per second allows deeper search.
Has anyone of you guys ever attempted to make a chess AI? I actually found it to be relatively easy and I am thinking of keeping updates to this thread with my progress, problems I encounter funny bugs etc
As the title says while watching some WC games between Magnus and Nepo, I started slowly coding away.
My first objective was to simply code all the rules of chess- so I could move pieces around. Pawns were super annoying to code as black/white pawns move differently (they move opposite directions which is something you'd never even think about unless you formally try to code the rules and the captures and en passant and promotions... ugh pawns are duuumb). Castling was also somewhat painful to get right - so many conditions etc...
Once I had most of the rules of chess set in code. The next step was to make an AI. The first one was just:
1. get all available moves
2. play one of them at random
3. ???
4. PROFIT!
Technically it is an AI just a very bad one. So I did the next best thing and quickly coded up an evaluation function which does two things for now:
1. counts all the piece material (pawn 1, B, N = 3, R = 5, Q = 9, K = ???)
2. Then I tried to determine piece quality by multiplying the base value by a coefficient depending on the number of available moves and captures
I didn't know what to do with the Kings. What value should a king be? So I gave the King a value of 100. Thinking it would do it's best not to lose it. But a piece worth hundred was just too delicious for the AI and it tried to activate it immediately. So now my kings are worth 0, but losing ones king gives a score of +/- infinity, with the idea that I am allowing the capture of kings but any move that would prevent it would have a higher value. So in theory it will avoid checkmate as much as possible.
So having a rudimentary eval function. I just put it in a minmax algorithm - an algorithm that tries to find the best move (maximize the eval function for you), while simultanously minimizing it for the opponent (making sure that while you maximize it from your side the opponent has the weakest possible replies). Hence the name minmax.
Now my biggest challenge is to improve my evaluation function and also improve the performance of the program so I can search and evaluate more positions per second. The current number varies between 40k-200k positions per second depending on some changes of my algorithm and the position too.
I am most happy about the choice of implementing FEN import/export as one of the first features I coded, allowing me to initialize the AI at any state of the game.
Here is a sample game it played against itself just now:
1. e3 e5 2. Qf3 Qf6 3. Qxf6 Nxf6 4. b3 Bb4 5. Ba3 a5 6. c3 Bxa3 7. Nxa3 a4 8. b4 Ke7 9. Bd3 d6 10. Ne2 Bd7 11. O-O e4 12. Bc2 Bg4 13. Nd4 Nc6 14. Nab5 Nxd4 15. Nxd4 h5 16. Kh1 h4 17. f3 exf3 18. gxf3 Bd7 19. Rg1 c5 20. bxc5 dxc5 21. Nf5+ Bxf5 22. Bxf5 g6 23. Bh3 Rhd8 24. Rab1 b5 25. Rxb5 Rxd2 26. Rxc5 Rxa2 27. Rc7+
Every move here took from 30-130s to make. I am actually quite pleased with the result. It's not very strong play but given the simplicity of the eval function and relatively low performance of positions per second. It seems to play reasonably and so far no insanely stupid moves. Although after the check black "blundered his king", which is not something that should happen but I guess it's work in progress and a bug that needs fixing.
My current goals are to make a smarter evaluation function, adding some strategic elements like doubled pawns, king safety etc
Also the performance needs to improve, more positions per second allows deeper search.
Has anyone of you guys ever attempted to make a chess AI? I actually found it to be relatively easy and I am thinking of keeping updates to this thread with my progress, problems I encounter funny bugs etc