I don't see how this can work. For example, do you include checks in the q-search or not? Some do, some do not. How many plies of checks? What about escaping check? All moves or is just one good enough? What about alpha/beta? Do you examine all captures, or do you toss out losing captures? Do you toss out even exchanges after some depth limit?zd3nik wrote:The usual perft search is very handy for validating your standard move generator (and also handy for performance tuning).
But most engines spend roughly half of their time (or more) in quiescence search. So it would be just as handy to have a way of validating check/promo/capture/check-evasion move generation.
In my last two engines I added a qperft command which is similar to perft, except it does 2 additional plies of search: one with quiescence move generation at depth 0 and one at depth -1.
I know this won't work across the board because not all engines perform the same kind of move generation in quiescence search. I typically make my engines generate all captures, ALL promotions, and all checks (including discovered checks) at depth 0 and only generate captures and queen promotions at depth < 0. And at any depth ALL moves are generated when the side to move is in check (which is typically done by a separate GetCheckEvasions function). The qperft command as I've implemented it also returns total number of nodes, not just leaf nodes.
So here's what I'm asking:
1. Is there already some form of quiescence move generation validation that people are using?
2. I know this one is a long shot, but if anyone out there has an engine that does quiescence move generation identical to what I described above, would you be interested in implementing a qperft function and comparing node counts? I've already done parity checks using the 2 engines I've written which have qperft commands. But more implementations would mean more confidence in the accuracy of the results - it's quite possible my 2 different implementations both suffer from similar bugs and therefore return the same incorrect results.
For an example, here's the output of qperft depth 5 from startpos:
This does 5 plies of regular move generation plus qsearch(depth=0) movegen [ply 6] and qsearch(depth=-1) movegen [ply 7].Code: Select all
qperft depth 5 info string a2a3 581905 info string a2a4 591155 info string b1a3 545544 info string b1c3 547598 info string b2b3 552189 info string b2b4 635496 info string c2c3 545209 info string c2c4 725709 info string d2d3 1267879 info string d2d4 1702483 info string e2e3 1156100 info string e2e4 1403687 info string f2f3 572572 info string f2f4 681977 info string g1f3 602979 info string g1h3 558843 info string g2g3 554457 info string g2g4 682667 info string h2h3 564391 info string h2h4 654755 info string Total 15127595 info string Snodes 5072212, Qnodes 10055383 (66.4705%)
Snodes = total number of normal search nodes. Qnodes = total nodes in quiescence search (depth 0 and -1 combined).
STC
Perft has no options like those.