Move generator advice

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

User avatar
RedBedHed
Posts: 84
Joined: Wed Aug 04, 2021 12:42 am
Full name: Ellie Moore

Move generator advice

Post by RedBedHed »

(I originally posted this in the "general topics" forum by mistake.)

Hi! My name is Ellie. I am an undergrad student at ASU (software engineering). I am currently writing a stockfish and lc0 derived chess engine that I plan to use in a school project. Although my favorite language will always be Java, I decided to use C++ and Python for this project. (I am honestly starting to fall in love with C++. It is such a tsundere lol.)

Anyways, after about three months of reading and pulling my hair out, I finally have a working move generator that produces strictly legal moves! I've tested it on all of the chessprogramming.org positions, and I am so excited to be able to share it with ya'll! I am really hoping to obtain some feedback on how I can improve it. I know that it is a little ugly and still pretty far from optimal in places. (For example, my king moves are currently verified as they are generated.)

Here is the github link:
https://github.com/RedBedHed/Charon

And here are my bulk-counted perft numbers (from the initial position, i5 processor, 1.6 ghz):
perft(1) - 0.000 seconds - 20 nodes visited.
perft(2) - 0.000 seconds - 400 nodes visited.
perft(3) - 0.000 seconds - 8902 nodes visited.
perft(4) - 0.000 seconds - 197281 nodes visited.
perft(5) - 0.031 seconds - 4865609 nodes visited.
perft(6) - 0.656 seconds - 119060324 nodes visited.

I hope everyone is having a great summer! :)
>> Move Generator: Charon
>> Engine: Homura
void life() { playCapitalism(); return; live(); }
User avatar
algerbrex
Posts: 596
Joined: Sun May 30, 2021 5:03 am
Location: United States
Full name: Christian Dean

Re: Move generator advice

Post by algerbrex »

RedBedHed wrote: Sun Aug 08, 2021 11:48 am (I originally posted this in the "general topics" forum by mistake.)

Hi! My name is Ellie. I am an undergrad student at ASU (software engineering). I am currently writing a stockfish and lc0 derived chess engine that I plan to use in a school project. Although my favorite language will always be Java, I decided to use C++ and Python for this project. (I am honestly starting to fall in love with C++. It is such a tsundere lol.)

Anyways, after about three months of reading and pulling my hair out, I finally have a working move generator that produces strictly legal moves! I've tested it on all of the chessprogramming.org positions, and I am so excited to be able to share it with ya'll! I am really hoping to obtain some feedback on how I can improve it. I know that it is a little ugly and still pretty far from optimal in places. (For example, my king moves are currently verified as they are generated.)

Here is the github link:
https://github.com/RedBedHed/Charon

And here are my bulk-counted perft numbers (from the initial position, i5 processor, 1.6 ghz):
perft(1) - 0.000 seconds - 20 nodes visited.
perft(2) - 0.000 seconds - 400 nodes visited.
perft(3) - 0.000 seconds - 8902 nodes visited.
perft(4) - 0.000 seconds - 197281 nodes visited.
perft(5) - 0.031 seconds - 4865609 nodes visited.
perft(6) - 0.656 seconds - 119060324 nodes visited.

I hope everyone is having a great summer! :)
Hi Ellie, welcome to TalkChess! And congratulations on your hard work so far :D

It's good that you're starting to test your move generator. However, I recommend testing more than just the 6-7 positions given on the Chess Programming Wiki. While they are good at catching some bugs, there are many other bugs that might be hiding in more unique positions. Look around for some more extensive perft testing suites with a variety of positions (opening, middle, and endgames) that other engines use (to see what I mean, you can take a peek at the suite that I'm using for my own engine: https://github.com/algerbrex/blunder/bl ... tsuite.txt).

As far as code goes, taking a quick look through your codebase, I didn't see any glaring bugs or other oddities with regards to the bitboard techniques or algorithms you're using, and at the cursory glance I took, you're code was pretty readable.

A word of advice I would give, while your engine is still in the early stages, is to consider using a pseudo-legal move generator instead of a legal one. Of course, a legal or pseudo-legal move generator can provide a strong foundation for a chess engine, but once you reach the search phase, it'll generally be less work to just generate pseudo-legal moves and verify that each one is legal. This is because once you implement decent move ordering in your engine, the first several moves it looks at will hopefully be the bests, and so it won't waste time looking at all the other moves, and won't spend the extra work of calculating if they're legal. But with a fully legal move generator, the time is spent verifying every move is legal regardless of if you actually have to.

Now I'm not saying scrap the work you have so far, because as anyone here can attest to, making a working move generator can be the difficult first step and is nothing to sniff at, but I think it's something you should definitely consider.

One more piece of advice I would give is to be careful not to get too caught up in the perft speed side quest. While having a blazing fast move generator is a very nice perk and, I think, something to be proud of, you'll find as you write the search and evaluation phases of your engine that move generation is such a small part of the general search time that it's really not worth worrying about until at the very least you implement and experiment with some different basic search optimizations (alpha-beta pruning, move ordering, quiescence search, transposition table, killer moves, history heuristic, null-move pruning et al.) Focusing on those kinds of improvements will give you much bigger ELO boosts than trying to squeeze every last drop of performance out of your move generator.
JVMerlino
Posts: 1357
Joined: Wed Mar 08, 2006 10:15 pm
Location: San Francisco, California

Re: Move generator advice

Post by JVMerlino »

Hello Ellie,

Congratulations on completing your move generator! It is definitely an accomplishment and your perft speed is more than adequate. So, as algerbrex said, don't bother trying to improve it at this stage. The perft speed for my engine, Myrddin, appears to be as much as 6x slower than yours! But the engine is still rated about 2550 CCRL.

To continue to agree with algerbrex, I have several positions that I use to confirm that my perft hasn't broken. Here they are:
r3k2r/8/8/8/3pPp2/8/8/R3K1RR b KQkq e3 0 1 // perft(6) = 485,647,607
r3k2r/Pppp1ppp/1b3nbN/nP6/BBP1P3/q4N2/Pp1P2PP/R2Q1RK1 w kq - 0 1 // perft(6) = 706,045,033
8/7p/p5pb/4k3/P1pPn3/8/P5PP/1rB2RK1 b - d3 0 28 // perft(6) = 38,633,283
8/3K4/2p5/p2b2r1/5k2/8/8/1q6 b - - 1 67 // perft(7) = 493,407,574
rnbqkb1r/ppppp1pp/7n/4Pp2/8/8/PPPP1PPP/RNBQKBNR w KQkq f6 0 3 // perft(6) = 244,063,299
r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - // Perft(5) = 193,690,690
8/p7/8/1P6/K1k3p1/6P1/7P/8 w - - // Perft(8) = 8,103,790
n1n5/PPPk4/8/8/8/8/4Kppp/5N1N b - - // Perft(6) = 71,179,139
r3k2r/p6p/8/B7/1pp1p3/3b4/P6P/R3K2R w KQkq - // Perft(6) = 77,054,993
8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - - // Perft(7) = 178,633,661
8/5p2/8/2k3P1/p3K3/8/1P6/8 b - - // Perft(8) = 64,451,405
r3k2r/pb3p2/5npp/n2p4/1p1PPB2/6P1/P2N1PBP/R3K2R w KQkq - // Perft(5) = 29,179,893

Good Luck!
John Merlino
John Merlino - Myrddin chess engine
User avatar
RedBedHed
Posts: 84
Joined: Wed Aug 04, 2021 12:42 am
Full name: Ellie Moore

Re: Move generator advice

Post by RedBedHed »

Hi, Christian! Thank you so much for all of this advice! What you said about move ordering makes a ton of sense... especially in the context of alpha-beta. I can definitely see why it is inefficient to verify moves during generation now. (I can't wait to get started on the search! :D) Also, thank you so much for providing all of these test positions! I don't know much about the Go language, but Blunder looks amazing!

I'll keep testing and squashing bugs, and I will try verifying king moves post-generation. :)
>> Move Generator: Charon
>> Engine: Homura
void life() { playCapitalism(); return; live(); }
User avatar
RedBedHed
Posts: 84
Joined: Wed Aug 04, 2021 12:42 am
Full name: Ellie Moore

Re: Move generator advice

Post by RedBedHed »

Hi, John! Thanks so much for these positions! :)
>> Move Generator: Charon
>> Engine: Homura
void life() { playCapitalism(); return; live(); }
User avatar
algerbrex
Posts: 596
Joined: Sun May 30, 2021 5:03 am
Location: United States
Full name: Christian Dean

Re: Move generator advice

Post by algerbrex »

RedBedHed wrote: Sun Aug 08, 2021 8:52 pm Hi, Christian! Thank you so much for all of this advice! What you said about move ordering makes a ton of sense... especially in the context of alpha-beta. I can definitely see why it is inefficient to verify moves during generation now. (I can't wait to get started on the search! :D) Also, thank you so much for providing all of these test positions! I don't know much about the Go language, but Blunder looks amazing!

I'll keep testing and squashing bugs, and I will try verifying king moves post-generation. :)
Of course! And don't be too afraid of Go. I just learned it myself a couple of months ago to write Blunder :lol: it's very much in the C family of languages, so if you know Java or you're learning C++, Go code won't be too hard to understand, and hopefully it can be of help to you if need be.

Goodluck!
User avatar
RedBedHed
Posts: 84
Joined: Wed Aug 04, 2021 12:42 am
Full name: Ellie Moore

Re: Move generator advice

Post by RedBedHed »

John, I'll admit I was very nervous trying these positions. I thought I had a new bug for a second, but it turned out that my definition of the en passant square isn't quite Forsyth's definition lol. I adjusted my FEN parser, and I am very, very happy to say that the move generator passed every one of these test positions ! :D
>> Move Generator: Charon
>> Engine: Homura
void life() { playCapitalism(); return; live(); }
User avatar
RedBedHed
Posts: 84
Joined: Wed Aug 04, 2021 12:42 am
Full name: Ellie Moore

Re: Move generator advice

Post by RedBedHed »

Thanks, Christian! I'll definitely try it out when I get a chance! It's crazy how many C-derived languages are out there! I can't wait to study grammar theory and automata! (I think I'll be studying it this spring actually...)
>> Move Generator: Charon
>> Engine: Homura
void life() { playCapitalism(); return; live(); }
Henk
Posts: 7220
Joined: Mon May 27, 2013 10:31 am

Re: Move generator advice

Post by Henk »

Even when move generator is bug free it might happen that search accidentally skips some moves.
The probability of that increases when search gets more and more complicated.

But you can call it late move pruning and then it is ok.
User avatar
lithander
Posts: 881
Joined: Sun Dec 27, 2020 2:40 am
Location: Bremen, Germany
Full name: Thomas Jahn

Re: Move generator advice

Post by lithander »

Did I read that correctly? Your perft() function is 20% faster than hgm's qperft and achieves this speed without using neither bulk counting nor hashing? That's really impressive!!

Edit: I did not read correctly and it does use bulk-counting. But still impressive! :D
Minimal Chess (simple, open source, C#) - Youtube & Github
Leorik (competitive, in active development, C#) - Github & Lichess