vittyvirus wrote:This is my move generator code for black. Its insanely buggy, please help me find those bugs. I've fixed parts of white move generator code, but Black's movegen code is still buggy. So just not to confuse you guys, I've only posted White movegen code.
If your move generator works for one color but not for the other then why don't you store both functions GenWhiteMoves() and GenBlackMoves() in separate temporary files and use a graphical "diff" tool to compare them and watch out for unwanted differences? Look at each single difference and answer the question: is this the correct way of generating black moves instead of white moves?
As to your code: a lot has already been said about it, I suggest to follow those advices of course. I would especially follow the advice to do isolated tests before testing all at once. Get perft(1) working perfectly for a couple of test positions before moving on to perft(N) for N>1. Get move generation for kings (without castling) and knights perfect, then move on to rooks, bishops, queens, then trivial pawn moves (single push + capture), then special pawn moves (double push, promotion, ep), finally castling. Always use test positions that are appropriate for the current phase of testing by not including piece types or move types that are not supported yet. While testing this way, comment out (#if 0 - #endif) the move generation code that has not been tested before AND is not needed in the current test step, and uncomment step by step.
Now watch out for legality issues as well. You can have a 100% perfect pseudo-legal move generator but your perft(1) tests can already fail miserably - why?
1) When in check, only certain check evasions are legal.
2) When not in check, only those moves are legal that do not put the own king into check (king moves, moves of pinned pieces, ep capture are candidates for illegal moves).
So your own perft() function must somehow take this into account, by counting legal move paths only. I'd assume you have done this already.
But just in case you haven't done so yet: a typical approach is to write a legal move generation function on top of the pseudo-legal move generator, and only use the legal generator inside perft() which would become a very simple function of only few lines. The first, dumb implementation of the legal move generator would be very slow and ineffective, by making/unmaking each pseudo-legal move on the board and testing inbetween whether it leaves the own king in check. A better implementation would restrict this make/unmake test to only few types of moves (see above): check evasions, king moves, moves of pinned pieces, and ep captures, while all other pseudo-legal moves are intrinsically legal. I'd suggest to start with the slow way to catch all bugs, and optimize it later (testing again).
Just a note: an efficient legal move generator may be useful for tree search as well, not only for perft, so the effort for writing it now might pay off later. There are certainly different opinions about that, some prefer a pseudo-legal move generator for tree search and some don't.