Check out Grant Acedrex, our featured variant for April, 2024.


[ Help | Earliest Comments | Latest Comments ]
[ List All Subjects of Discussion | Create New Subject of Discussion ]
[ List Earliest Comments Only For Pages | Games | Rated Pages | Rated Games | Subjects of Discussion ]

Single Comment

Double Castling[Subject Thread] [Add Response]
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).