Thank you for the answer and permission!hgm wrote: ↑Wed Nov 11, 2020 10:20 amNearly all my engines have a move generator like that. Sometimes the outer loop does not scan the board, but a piece list. Sometimes the table of start indexes in the array of board steps is not only indexed by piece type but also by from-square (making it a pise-square table for moves, rather than scores, to have location-dependent moving, as in Xiangqi).maksimKorzh wrote: ↑Wed Nov 11, 2020 1:51 amThe move generator code reminds me microMax:
1. 0x88 board representation (but PST are separate instead of being on the right part of unused board squares)
2. Three nested loops in movegen
3. Faking captures for non-sliding pieces
Indeed, that is the double-push code, which undoes the kludge of faking a victim for leapers if the Pawn is still on 3rd rank. This is in the move generator. Castling and e.p. capture are only implemented for input moves; they are not in the move generator, and N.E.G. would never play them byitself. In the code for handling the "usermove" command the castling is done through:But what I can't figure out is whether it supports castling, in microMax there was a rocket science level line that was handling
double pawn push and castling (for you've explained that the nature of these two actions is same in essence). Here in NEG I can see line:It seems to my code monkey's eyes to be responsible for double pawn push and castling but castling part is much simpler compared to microMax.Code: Select all
if(!(to - from & 7) && type < 3 && (type == 1 ? to > 79 : to < 48)) victim--;
I assume that happens because here king capture is not allowed (hence InCheck function)This just recognizes sideway double steps by the King, and then moves the corresponding Rook in addition to the normal move performance.Code: Select all
if((board[from] & 7) == 3 && to - from == 2) board[from + 1] = board[to + 1], board[to + 1] = 0; // K-side castling if((board[from] & 7) == 3 && from - to == 2) board[from - 1] = board[to - 2], board[to - 2] = 0; // Q-side castling
The move generator isn't; it doesn't generate castling or e.p. capture. To generate castlings according to the rules you would have to keep track of piece virginity. Micro-Max does this through an extra bit in the piece encodings on the board, but you could also keep track of a castling rights word (containing 1 bit per type of castling), and a board-size array that for each square tabulates which castling rights are destroyed when that square is used as from- or to-square. (Actually you only have to keep track of whether it is used as to-square, but then you would have to test whether it is non-empty to test if the corresponding castling is allowed.)So the question is - is it full FIDE rules (apart from promotions and probably 50 rule/3 fold repetitions)?
Of course you can; N.E.G. can be considered public domain. There are also some unusual things in the N.E.G. move generator, though: it also generates 'pseudo-captures', i.e. capture of friendly pieces. So the 'consumer' of the moves (the callback) has to test whether it actually gets a pseudo-legal move, or just a 'protection', depending on what it wants to do (select a move for playing, or just count attackers and protectors).Also I would like to ask for your permission:
Can I make a tutorial series on NEG's movegen? (MicroMax is too complicated because of movegen is embedded into a search, beta cutoffs on king capture and other unusual stuff like remembering best from square to order first in the next iteration of IID)
Perhaps the move generator of KingSlayer / simple (line 841-932 in the latest commit) would be more suitable for your purpose. It also uses the three nested loops, similar to micro-Max, but is decoupled from search, and just puts the generated moves in a list. It also contains a few quirks (such as marking pieces protected by 'pseudo-captures' on a separate board, and a way to abort move generation when an 'off-scale' capture (such as that of a King) is found, and remember piece mobility, but you could easily delete the corresponding code sections from it without compromising the overall structure.
I'm also now playing with MCTS algorithm and looking for some light weight movegen for this purpose (my bitboard based BBC is huge and I just don't want to use it for that purpose), so can I please use your NEG's movegen in my project?
THANKS IN ADVANCE!
P.S. You can't ever imagine how happy I am with obtaining this source code! It's a GOLD for me! Thank you HGM!
I'm just curious did you invent these nested loops in movegen and piece encoding with 8th bit to encode color and 32th bit for virginity?
and another question - aren't you interested to try alpha zero type of engine?
Is it possible to avoid deep learning and use only a couple of hidden layers to output policies and value like in leela's net?
It would be nice to have such a minimalist net written in pure C