X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=hachu.c;h=a0c878b4c18d585795015ec5c9dce697d1025371;hb=6f3b633d57f5928258c4d383087a0bbb8bd60015;hp=fdf5bb401dd4d0517907ac6965c87ad9c552f8c4;hpb=73f8d53961524d71089ad54b1549a953efa0fe14;p=hachu.git diff --git a/hachu.c b/hachu.c index fdf5bb4..a0c878b 100644 --- a/hachu.c +++ b/hachu.c @@ -89,6 +89,7 @@ #define PROMOTE (1<<2*SQLEN+1) /* promotion bit in move */ #define SPECIAL 1400 /* start of special moves */ #define BURN (SPECIAL + 96) /* start of burn encodings */ +#define CASTLE (SPECIAL + 100) /* castling encodings */ #define STEP(X,Y) (BW*(X)+ (Y)) #define SORTKEY(X) 0 @@ -498,7 +499,7 @@ Vector direction[] = { // clockwise! { 2,-1} }; -int epList[96], ep2List[96], toList[96], reverse[96]; // decoding tables for double and triple moves +int epList[104], ep2List[104], toList[104], reverse[104]; // decoding tables for double and triple moves int kingStep[10], knightStep[10]; // raw tables for step vectors (indexed as -1 .. 8) int neighbors[9]; // similar to kingStep, but starts with null-step char fireFlags[10]; // flags for Fire-Demon presence (last two are dummies, which stay 0, for compactify) @@ -959,6 +960,11 @@ Init (int var) toList[88+i] = kStep[i]; epList[88+i] = 2*kStep[i]; } + toList[100] = BH - 2; epList[100] = BH - 1; ep2List[100] = BH - 3; + toList[100+1] = 2; epList[100+1] = 0; ep2List[100+1] = 3; + toList[100+2] = bsize - BH - 2; epList[100+2] = bsize - BH - 1; ep2List[100+2] = bsize - BH - 3; + toList[100+3] = bsize - BW + 2; epList[100+3] = bsize - BW; ep2List[100+3] = bsize - BW + 3; + // fill distance table for(i=0; i<2*BSIZE; i++) { distance[i] = 0; @@ -1135,6 +1141,17 @@ MarkBurns (int x) for(r=b; r<=t-2; r++) rows[r] |= rows[r+1] | rows[r+2]; // smear vertically } +void +GenCastlings () +{ // castings for Lion Chess. Assumes board width = 8 and Kings on e-file, and K/R value = 280/300! + int f = BH>>1, t = CASTLE; + if(stm != WHITE) f += bsize - BW, t += 2; + if(p[board[f]].value = 280) { + if(p[board[f-4]].value == 300 && board[f-3] == EMPTY && board[f-2] == EMPTY && board[f-1] == EMPTY) moveStack[msp++] = f<new = u->piece; if(u->to >= SPECIAL) { // two-step Lion move + if(u->to >= CASTLE) { // move Rook, faking it was an e.p. victim so that UnMake works automatically + u->epSquare = epList[u->to - SPECIAL]; + u->ep2Square = ep2List[u->to - SPECIAL]; + u->epVictim[0] = board[u->epSquare]; // kludgy: fake that King e.p. captured the Rook! + u->epVictim[1] = board[u->ep2Square]; // should be EMPTY (but you never know, so save as well). + board[u->ep2Square] = u->epVictim[0]; // but put Rook back + board[u->epSquare] = EMPTY; + p[u->epVictim[0]].pos = u->ep2Square; + p[u->epVictim[1]].pos = ABSENT; + u->to = toList[u->to - SPECIAL]; + hashKeyL ^= p[u->epVictim[0]].pieceKey * squareKey[u->epSquare]; + hashKeyH ^= p[u->epVictim[0]].pieceKey * squareKey[u->epSquare+BH]; + hashKeyL ^= p[u->epVictim[0]].pieceKey * squareKey[u->ep2Square]; + hashKeyH ^= p[u->epVictim[0]].pieceKey * squareKey[u->ep2Square+BH]; + } else { // take care of first e.p. victim u->epSquare = u->from + epList[u->to - SPECIAL]; // decode u->epVictim[0] = board[u->epSquare]; // remember for takeback @@ -1335,6 +1367,7 @@ MakeMove(Move m, UndoInfo *u) hashKeyH ^= p[u->epVictim[1]].pieceKey * squareKey[u->ep2Square+BH]; if(p[u->piece].value != LVAL && p[u->epVictim[0]].value == LVAL) deferred |= PROMOTE; // flag non-Lion x Lion cnt50 = 0; // double capture irreversible + } } if(u->fireMask & fireBoard[u->to]) { // we moved next to enemy Fire Demon (must be done after SPECIAL, to decode to-sqr) @@ -2384,7 +2417,8 @@ MoveToText (MOVE move, int multiLine) char *promoChar = ""; if(f == t) { sprintf(buf, "@@@@"); return buf; } // null-move notation in WB protocol buf[0] = '\0'; - if(t >= SPECIAL) { // kludgy! Print as side effect non-standard WB command to remove victims from double-capture (breaks hint command!) + if(t >= SPECIAL) { + if(t < CASTLE) { // castling is printed as a single move, implying its side effects int e = f + epList[t - SPECIAL]; // printf("take %c%d\n", e%BW+'a', e/BW+ONE); sprintf(buf, "%c%d%c%d,", f%BW+'a', f/BW+ONE, e%BW+'a', e/BW+ONE); f = e; @@ -2395,6 +2429,7 @@ MoveToText (MOVE move, int multiLine) sprintf(buf+strlen(buf), "%c%d%c%d,", f%BW+'a', f/BW+ONE, e%BW+'a', e/BW+ONE); f = e; if(multiLine) printf("move %s\n", buf), buf[0] = '\0'; } + } t = g + toList[t - SPECIAL]; } if(move & PROMOTE) promoChar = currentVariant == V_MAKRUK ? "m" : repDraws ? "q" : "+"; @@ -2425,7 +2460,8 @@ MapFromScratch(attacks); Search(-INF-1, INF+1, 0, QSdepth+1, 0, sup1 & ~PROMOTE, sup2, INF); postThinking++; - listStart = retFirst; listEnd = msp = retMSP; + listStart = retFirst; msp = retMSP; + if(currentVariant == V_LION) GenCastlings(); listEnd = msp; } MOVE @@ -2451,6 +2487,11 @@ ParseMove (char *moveText) if(t == f + BW - 1) t2 = SPECIAL + 48; else if(t == f - BW + 1) t2 = SPECIAL + 20; else if(t == f - BW - 1) t2 = SPECIAL + 52; // fake double-move + } else if(currentVariant == V_LION && board[f] != EMPTY && p[board[f]].value == 280 && (t-f == 2 || f-t == 2)) { // castling + if(t == f+2 && f < BW) t2 = CASTLE; else + if(t == f-2 && f < BW) t2 = CASTLE + 1; else + if(t == f+2 && f > BW) t2 = CASTLE + 2; else + if(t == f-2 && f > BW) t2 = CASTLE + 3; } ret = f<>SQLEN & SQUARE)) { int t = moveStack[i] & SQUARE; + if(t >= CASTLE) t = toList[t - SPECIAL]; else // decode castling if(t >= SPECIAL) { int e = sqr + epList[t - SPECIAL]; // decode b[e] = 'C';