mvanthoor wrote: ↑Fri Feb 26, 2021 12:48 am
Is it a bitboard engine? Sorry, I forgot. At this point it doesn't matter too much, because both our evaluations are small, but a bitboard engine has a measurable advantage in speed with bigger evaluation functions (and they're easier to write). That counts, because the evaluation is one of the most called function in the program.
No. Up to my first functional min/max version I hadn't discovered this forums yet. I didn't know that I'd eventually have to pit it against Rustic Alpha and so I didn't worry about how others were doing it. In other words I hadn't fallen into this rabbit hole called 'chess programming' yet. I think I didn't even know the words "bitboard" and "mailbox" and just reinvented the wheel because it didn't seem so hard that you'd need to read books or look at other implementations. I still like the resulting move generator code. I think it's pretty, because it's simple. When I forced my wife to watch my making-of videos she understood
my explanation of how the move gen works just so. As she's not a programmer I doubt that would have been the case with bitboards!
mvanthoor wrote: ↑Fri Feb 26, 2021 12:48 am
So 188 points for adding the PST (in my case, that was 520), 294 points for adding the QSearch, and 822 points for adding both (!). However, I tested at the normal 1m+0.6s time controls, not by fixed depth. I'd be quite surprised if you add PST's and QSearch, and your engine would storm to around 1870 Elo. Then I want to know what sort of magic keyboard you have for typing your code.
IS this PST + Q-search version available as a binary already? I'd like to test it, because it's exactly on par with my own engine (assuming it has MVV-LVA, king check extension in alpha/beta, and no other optimizations or hash tables).
I don't think you can add and subtract ELO points like that. Otherwise, just play against a random mover and win all games and you get infinity ELO and you've solved Chess!
Don't you worry! You're completely safe at this point.
Code: Select all
Score of MinimalChess 0.2.4 PST+Q vs Rustic: 13 - 49 - 13 [0.260]
... MinimalChess 0.2.4 PST+Q playing White: 7 - 25 - 6 [0.263] 38
... MinimalChess 0.2.4 PST+Q playing Black: 6 - 24 - 7 [0.257] 37
... White vs Black: 31 - 31 - 13 [0.500] 75
Elo difference: -181.7 +/- 81.2, LOS: 0.0 %, DrawRatio: 17.3 %
75 of 100 games finished.
...but it's doing good against Sargon 1978 (1249 Elo on CCRL)
Code: Select all
Score of Sargon 1978 vs MinimalChess 0.2.4 PST+Q: 8 - 46 - 10 [0.203]
... Sargon 1978 playing White: 3 - 24 - 5 [0.172] 32
... Sargon 1978 playing Black: 5 - 22 - 5 [0.234] 32
... White vs Black: 25 - 29 - 10 [0.469] 64
Elo difference: -237.5 +/- 97.0, LOS: 0.0 %, DrawRatio: 15.6 %
64 of 100 games finished.
So, I'd estimate MMC with QSearch and PST in it's current form to be at 1400-1500 ELO.
If you really want it I can send you the binary via PM. But I would prefer to take my time to make sure everything these new features are implemented to the best of my ability before I release a version with PSTs and QSearch. C# makes it easy to rapidly prototype stuff before you optimize it. For example the SortMvvLva is only a few lines of code currently and took me 10 minutes to write. I love C# making that possible. But then I've spend hours looking for a bug that probably is just a performance problem. So, as I've just painfully learned, you can implement a perfectly good optimization like qsearch so inefficiently that it negates it's effect entirely under certain conditions (e.g. too simplistic eval, depth > 7plys).
I wouldn't be surprised if the move ordering that looks up pieces in the board array and recomputes the score
each time whatever sort-algorithm C# uses behind the scene needs to compare two elements. I know of course how this could be implemented faster but "premature optimization is the root of all evil"... well in this case Donald Knuth's aphorism was misleading me.
Code: Select all
public static void SortMvvLva(List<Move> moves, Board context)
{
int Score(Move move)
{
Piece victim = context[move.ToIndex];
Piece attacker = context[move.FromIndex];
//Rating: 100 * Victims value first, offset by the attackers value
return (victim == Piece.None) ? 0 : ((100 * (int)victim) - (int)attacker);
}
moves.Sort((a, b) => Score(b).CompareTo(Score(a)));
}