H. G. Muller wrote on Sun, Sep 27, 2015 09:36 AM UTC:
There is no need to already give up. As you remarked in the description, Latte Chess is basically normal Chess with a bit more crowded initial position, and many normal Chess engines can play it. Except for the fancy castling methods described in the notes. Which are so novel that no existing configurable engine would support them anyway, and you would have to rely on program modification.
So there isn't really any need to start from a configurable multi-variant engine like Sjaak. Any normal Chess engine would do. You just hack in the Luft or double castling, modify the initial position, and you are done. You can pick an engine that is simple to understand and modify.
As it happens I was just writing such an engine. It is in my on-line source repository at http://hgm.nubati.net/cgi-bin/gitweb.cgi , the project 'simple.git'. (I intended to call it Simple, but it turns out that name was already taken.) The code for generating castlings in the move generator there is just
for(i=0; i<2; i++) { // try for i = 0 (Q-side) and 1 (K-side)
static char cTab[] = { 1, 4, 0, 7, -1, 1, 0, 0, // table with flag-test bit, corner and direction (all 2x)
2, 8, 0x70, 0x77, -1, 1, 0, 0, }; // same for black
if(!(cTab[stm+i] & rights)) { // the castling right exists
int corner = cTab[stm+i+2], dir = cTab[stm+i+4]; // get applicable corner square and direction
if(board[corner^1] || board[corner^2]) continue; // two squares next to corner not both empty
if(board[king+dir]) continue; // square next to King not empty
moves[lastMove++] = king+2*dir | king<<8 | king+dir+0x80<<16; // add castling, flagged by 0x80 + square skipped by King
}
You obviously would have to alter the the conditions there under which castling would be considered possible, in particular the tests for which squares should be empty. (Note it does not test for Rooks and virginity of pieces explicitly; these follow from the fact that the castling right still exists.)
Then you would have to alter the part that implements the castling side effect, which currently is
if(!(epSqr & 8) && from == king) { int rook; // move is castling; needs some extra effort to perform
rookSqr = epSqr & ~0x88; // square skipped by King contained in move's flag field
epSqr = (to > from ? from+3 : from-4); // KLUDGE: set epSqr to board corner, so Rook will be removed
board[rookSqr] = rook = board[epSqr]; // grow Rook on square skipped by King
hashKey ^= zob[rook][rookSqr]; // correct hash key for that
pstEval += pst[rook][rookSqr] - 2*pst[rook][epSqr]; // and eval, pre-compensating for wrong sign of e.p. removal
deltaPhase = -weight[rook]; counts[rook]++; // Rook will not really disappear from board
}
You would have to calculate where the other Rook is, and how you have to displace that. You would also have to add some code to UnMake to move that Rook back. In Init() you would have to assign values to some other squares of the 'spoiler' board, (which indicates which castling rights are spoiled by activity on a a given square, and thus should include the extra Rooks).
So there isn't really any need to start from a configurable multi-variant engine like Sjaak. Any normal Chess engine would do. You just hack in the Luft or double castling, modify the initial position, and you are done. You can pick an engine that is simple to understand and modify.
As it happens I was just writing such an engine. It is in my on-line source repository at http://hgm.nubati.net/cgi-bin/gitweb.cgi , the project 'simple.git'. (I intended to call it Simple, but it turns out that name was already taken.) The code for generating castlings in the move generator there is just
You obviously would have to alter the the conditions there under which castling would be considered possible, in particular the tests for which squares should be empty. (Note it does not test for Rooks and virginity of pieces explicitly; these follow from the fact that the castling right still exists.)Then you would have to alter the part that implements the castling side effect, which currently is
You would have to calculate where the other Rook is, and how you have to displace that. You would also have to add some code to UnMake to move that Rook back. In Init() you would have to assign values to some other squares of the 'spoiler' board, (which indicates which castling rights are spoiled by activity on a a given square, and thus should include the extra Rooks).