- /* 
- This Software is distributed with the following X11 License, 
- sometimes also known as MIT license. 
-   
- Copyright (c) 2010 Miguel A. Ballicora 
-   
-  Permission is hereby granted, free of charge, to any person 
-  obtaining a copy of this software and associated documentation 
-  files (the "Software"), to deal in the Software without 
-  restriction, including without limitation the rights to use, 
-  copy, modify, merge, publish, distribute, sublicense, and/or sell 
-  copies of the Software, and to permit persons to whom the 
-  Software is furnished to do so, subject to the following 
-  conditions: 
-   
-  The above copyright notice and this permission notice shall be 
-  included in all copies or substantial portions of the Software. 
-   
-  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
-  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
-  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
-  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
-  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
-  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
-  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
-  OTHER DEALINGS IN THE SOFTWARE. 
- */ 
-   
-   
- /* NBBOTF will remove the internal bitbase on the fly */ 
- #ifdef NBBOTF 
-         #ifdef WDL_PROBE 
-                 #undef WDL_PROBE 
-         #endif 
- #else 
-         #define WDL_PROBE 
- #endif 
-   
- /*-- Intended to be modified to make public --> Supporting functions the TB generator ---------------------*/ 
-   
- #ifdef GTB_SHARE 
- #define SHARED_forbuilding 
- #endif 
-   
- /*---------------------------------------------------------------------------------------------------------*/ 
- #include <stdlib.h> 
- #include <stdio.h> 
- #include <string.h> 
-   
- #include "gtb-probe.h" 
-   
- #if defined(SHARED_forbuilding) 
-         #include "gtb-prob2.h" 
- #else 
-         #define mySHARED static 
-         typedef unsigned char                   SQ_CONTENT; 
-         typedef unsigned int                    SQUARE; 
- #endif 
-   
- #include "sysport.h" 
- #include "gtb-att.h" 
- #include "gtb-types.h" 
-   
- /*---------------------------------------------------------------------------------------------------------*/ 
- /*#include "posit_t.h"*/ 
-   
- #define MAX_LISTSIZE 17 
- #if 0 
- typedef unsigned                sq_t; 
- typedef unsigned char   pc_t; 
- typedef uint32_t                mv_t; 
- #endif 
-   
- struct posit { 
-         sq_t                    ws[MAX_LISTSIZE]; 
-         sq_t                    bs[MAX_LISTSIZE]; 
-         pc_t                    wp[MAX_LISTSIZE]; 
-         pc_t                    bp[MAX_LISTSIZE]; 
-         sq_t                    ep; 
-         unsigned int    stm; 
-         unsigned int    cas; 
- }; 
- typedef struct  posit posit_t; 
-   
- #if 0 
- typedef long int                tbkey_t; 
- #endif 
-   
- /*---------------------------------------------------------------------------------------------------------*/ 
- /*#include "bool_t.h"*/ 
-   
- #if !defined(H_BOOL) 
- typedef int                                             bool_t; 
- #endif 
-   
- #if !defined(TRUE) 
- #define TRUE ((bool_t)1) 
- #endif 
-   
- #if !defined(FALSE) 
- #define FALSE ((bool_t)0) 
- #endif 
-   
- /*--------- private if external building code is not present ----------------------------------------------*/ 
-   
- #if !defined(SHARED_forbuilding) 
-   
- #define MAX_EGKEYS 145 
- #define SLOTSIZE 1 
- #define NOINDEX ((index_t)(-1)) 
-   
- #if 0 
- typedef unsigned short int      dtm_t; 
- typedef size_t                          index_t; 
- /*typedef int                           index_t;*/ 
- #endif 
-   
- enum Loading_status { 
-                                 STATUS_ABSENT           = 0, 
-                                 STATUS_STATICRAM        = 1, 
-                                 STATUS_MALLOC           = 2, 
-                                 STATUS_FILE             = 3, 
-                                 STATUS_REJECT           = 4 
- }; 
-   
- struct endgamekey { 
-         int             id; 
-         const char *str; 
-         index_t         maxindex; 
-         index_t         slice_n; 
-         void            (*itopc) (index_t, SQUARE *, SQUARE *); 
-         bool_t          (*pctoi) (const SQUARE *, const SQUARE *, index_t *); 
-         dtm_t *         egt_w; 
-         dtm_t *         egt_b; 
-         FILE *          fd; 
-         int             status; 
-         int                     pathn; 
- }; 
- #endif 
-   
- /*----------------------------------------------------------------------------------------------------------*/ 
-   
- /* array for better moves */ 
- #ifdef GTB_SHARE 
- mySHARED int            bettarr [2] [8] [8]; 
- #endif 
-   
- /*------------ ENUMS ----------------------------------------------------------*/ 
-   
- enum Mask_values { 
-                                         RESMASK  = tb_RESMASK, 
-                                         INFOMASK = tb_INFOMASK, 
-                                         PLYSHIFT = tb_PLYSHIFT 
- }; 
-   
- enum Info_values { 
-                                         iDRAW    = tb_DRAW, 
-                                         iWMATE   = tb_WMATE, 
-                                         iBMATE   = tb_BMATE, 
-                                         iFORBID  = tb_FORBID, 
-   
-                                         iDRAWt   = tb_DRAW  |4, 
-                                         iWMATEt  = tb_WMATE |4, 
-                                         iBMATEt  = tb_BMATE |4, 
-                                         iUNKNOWN = tb_UNKNOWN, 
-   
-                                         iUNKNBIT = (1<<2) 
- }; 
-   
- /*-------------------------- inherited from a previous maindef.h -----------*/ 
-   
- #define WHITES (1u<<6) 
- #define BLACKS (1u<<7) 
-   
- #define NOPIECE 0u 
- #define PAWN    1u 
- #define KNIGHT  2u 
- #define BISHOP  3u 
- #define ROOK    4u 
- #define QUEEN   5u 
- #define KING    6u 
-   
- #define WH 0 
- #define BL 1 
- #define Opp(x) ((x)^1) 
- #define wK (KING   | WHITES) 
-   
- /*------------------- 
-        SQUARES 
-   -------------------*/ 
-   
- /* from 1-63 different squares posibles   */ 
-   
- /*squares*/ 
- enum SQUARES { 
-         A1,B1,C1,D1,E1,F1,G1,H1, 
-         A2,B2,C2,D2,E2,F2,G2,H2, 
-         A3,B3,C3,D3,E3,F3,G3,H3, 
-         A4,B4,C4,D4,E4,F4,G4,H4, 
-         A5,B5,C5,D5,E5,F5,G5,H5, 
-         A6,B6,C6,D6,E6,F6,G6,H6, 
-         A7,B7,C7,D7,E7,F7,G7,H7, 
-         A8,B8,C8,D8,E8,F8,G8,H8, 
-         NOSQUARE, 
-         ERRSQUARE = 128 
- }; 
-   
- /*------------------- end of inherited from a previous maindef.h -----------*/ 
-   
- #if !defined(NDEBUG) 
- #define NDEBUG 
- #endif 
- #ifdef DEBUG 
- #undef NDEBUG 
- #endif 
- #include "assert.h" 
-   
- /*------------------- general DEFINES--------------------------- -----------*/ 
-   
- #define gtbNOSIDE       ((unsigned)-1) 
- #define gtbNOINDEX      ((index_t)-1) 
-   
- /*************************************************\ 
- | 
- |                               COMPRESSION SCHEMES 
- | 
- \*************************************************/ 
-   
- #include "gtb-dec.h" 
-   
- static const char *const Extension[] = { 
-                                                          ".gtb.cp0" 
-                                                         ,".gtb.cp1" 
-                                                         ,".gtb.cp2" 
-                                                         ,".gtb.cp3" 
-                                                         ,".gtb.cp4" 
-                                                         ,".gtb.cp5" 
-                                                         ,".gtb.cp6" 
-                                                         ,".gtb.cp7" 
-                                                         ,".gtb.cp8" 
-                                                         ,".gtb.cp9" 
- }; 
-   
- /*************************************************\ 
- | 
- |                                       MOVES 
- | 
- \*************************************************/ 
-   
- enum move_kind { 
-                 NORMAL_MOVE = 0, 
-                 CASTLE_MOVE, 
-                 PASSNT_MOVE, 
-                 PROMOT_MOVE 
- }; 
-   
- enum move_content { 
-                 NOMOVE = 0 
- }; 
-   
- #define MV_TYPE(mv)   ( (BYTE)       ((mv) >>6 & 3 )      ) 
- #define MV_TO(mv)     ( (SQUARE)     ((mv) >>8 & 63)      ) 
- #define MV_PT(mv)     ( (SQ_CONTENT) ((mv) >>(3+16) &7  ) ) 
- #define MV_TK(mv)     ( (SQ_CONTENT) ((mv) >>(6+16) &7  ) ) 
- #define MV_FROM(mv)   ( (SQUARE)     ((mv)     & 63)      ) 
-   
- /* 
- |   move,type,color,piece,from,to,taken,promoted 
- *------------------------------------------------------------------*/ 
-   
- #define MV_BUILD(mv,ty,co,pc,fr,to,tk,pm) (                        \ 
-     (mv)    =  (fr)     | (to)<< 8      | (ty)<<  6     | (co)<<8  \ 
-             |  (pc)<<16 | (pm)<< (3+16) | (tk)<< (6+16)            \ 
- ) 
-   
- #define MV_ADD_TOTK(mv,to,tk) (          \ 
-      mv     |= (uint32_t)(to) << 8       \ 
-             |  (uint32_t)(tk) << (6+16)  \ 
- ) 
-   
- #define map88(x)    (   (x) + ((x)&070)        ) 
- #define unmap88(x)  ( ( (x) + ((x)& 07) ) >> 1 ) 
-   
- /*************************************************\ 
- | 
- |                               STATIC VARIABLES 
- | 
- \*************************************************/ 
-   
- static int GTB_scheme = 4; 
-   
- /*************************************************\ 
- | 
- |       needed for 
- |       PRE LOAD CACHE AND DEPENDENT FUNCTIONS 
- | 
- \*************************************************/ 
-   
- #define EGTB_MAXBLOCKSIZE 65536 
-   
- static int GTB_MAXOPEN = 4; 
-   
- static bool_t                   Uncompressed = TRUE; 
- static unsigned int             zipinfo_init (void); 
- static void                     zipinfo_done (void); 
-   
- enum Flip_flags { 
-                 WE_FLAG = 1, NS_FLAG = 2,  NW_SE_FLAG = 4 
- }; /* used in flipt */ 
-   
- struct filesopen { 
-                 int n; 
-                 tbkey_t *key; 
- }; 
-   
- /* STATIC GLOBALS */ 
-   
- static struct filesopen fd = {0, NULL}; 
-   
- static bool_t                   TB_INITIALIZED = FALSE; 
- static bool_t                   DTM_CACHE_INITIALIZED = FALSE; 
-   
- static int                              WDL_FRACTION = 64; 
- static int                              WDL_FRACTION_MAX = 128; 
-   
- static size_t                   DTM_cache_size = 0; 
- static size_t                   WDL_cache_size = 0; 
-   
- static unsigned int             TB_AVAILABILITY = 0; 
-   
- /* LOCKS */ 
- static mythread_mutex_t Egtb_lock; 
-   
-   
- /****************************************************************************\ 
-  * 
-  * 
-  *                      DEBUGGING or PRINTING ZONE 
-  * 
-  * 
-  ****************************************************************************/ 
-   
- #if 0 
- #define FOLLOW_EGTB 
- #ifndef DEBUG 
- #define DEBUG 
- #endif 
- #endif 
-   
- #define validsq(x) ((x) >= A1 && (x) <= H8) 
-   
- #if defined(DEBUG) 
- static void     print_pos (const sq_t *ws, const sq_t *bs, const pc_t *wp, const pc_t *bp); 
- #endif 
-   
- #if defined(DEBUG) || defined(FOLLOW_EGTB) 
- static void     output_state (unsigned stm, const SQUARE *wSQ, const SQUARE *bSQ, 
-                                                                 const SQ_CONTENT *wPC, const SQ_CONTENT *bPC); 
- static const char *Square_str[64] = { 
-         "a1","b1","c1","d1","e1","f1","g1","h1", 
-         "a2","b2","c2","d2","e2","f2","g2","h2", 
-         "a3","b3","c3","d3","e3","f3","g3","h3", 
-         "a4","b4","c4","d4","e4","f4","g4","h4", 
-         "a5","b5","c5","d5","e5","f5","g5","h5", 
-         "a6","b6","c6","d6","e6","f6","g6","h6", 
-         "a7","b7","c7","d7","e7","f7","g7","h7", 
-         "a8","b8","c8","d8","e8","f8","g8","h8" 
- }; 
- static const char *P_str[] = { 
-         "--", "P", "N", "B", "R", "Q", "K" 
- }; 
- #endif 
-   
- #ifdef FOLLOW_EGTB 
-         #define STAB 
-         #define STABCONDITION 1 /*(stm == BL && whiteSQ[0]==H1 && whiteSQ[1]==D1 && whiteSQ[2]==D3 && blackSQ[0]==C2 )*/ 
-         static bool_t GLOB_REPORT = TRUE; 
- #endif 
-   
- #if defined(FOLLOW_EGTB) 
- static const char *Info_str[8] = { 
-         " Draw", " Wmate", " Bmate", "Illegal", 
-         "~Draw", "~Wmate", "~Bmate", "Unknown" 
- }; 
- #endif 
-   
- static void             list_index (void); 
- static void     fatal_error(void) { 
- } 
-   
- #ifdef STAB 
-         #define FOLLOW_LU(x,y)  {if (GLOB_REPORT) printf ("************** %s: %lu\n", (x), (long unsigned)(y));} 
- #else 
-         #define FOLLOW_LU(x,y) 
- #endif 
-   
- #ifdef STAB 
-         #define FOLLOW_LULU(x,y,z)  {if (GLOB_REPORT) printf ("************** %s: %lu, %lu\n", (x), (long unsigned)(y), (long unsigned)(z));} 
- #else 
-         #define FOLLOW_LULU(x,y,z) 
- #endif 
-   
- #ifdef STAB 
-         #define FOLLOW_label(x) {if (GLOB_REPORT) printf ("************** %s\n", (x));} 
- #else 
-         #define FOLLOW_label(x) 
- #endif 
-   
- #ifdef STAB 
-         #define FOLLOW_DTM(msg,dtm)  {if (GLOB_REPORT) printf ("************** %s: %lu, info:%s, plies:%lu \n"\ 
-         , (msg), (long unsigned)(dtm), (Info_str[(dtm)&INFOMASK]), (long unsigned)((dtm)>>PLYSHIFT)\ 
-         );} 
- #else 
-         #define FOLLOW_DTM(msg,dtm) 
- #endif 
-   
-   
- /*--------------------------------*\ 
- | 
- | 
- |               INDEXING FUNCTIONS 
- | 
- | 
- *---------------------------------*/ 
-   
- #define IDX_set_empty(x) {x=0;x--;} 
- #define IDX_is_empty(x) (0==(1+(x))) 
-   
- #define NO_KKINDEX NOINDEX 
- #define MAX_KKINDEX 462 
- #define MAX_PPINDEX 576 
- #define MAX_PpINDEX (24 * 48) 
- /*1128*/ 
- #define MAX_AAINDEX ((63-62) + (62 * (127-62)/2) - 1 + 1) 
- #define MAX_AAAINDEX (64*21*31) 
- #define MAX_PP48_INDEX (1128) 
- /* (24*23*22/6) + 24 * (24*23/2) */ 
- #define MAX_PPP48_INDEX 8648 
-   
- /* VARIABLES */ 
-   
- static index_t                  kkidx [64] [64]; 
- static index_t                  ppidx [24] [48]; 
- static index_t                  pp48_idx[48][48]; 
- static index_t                  ppp48_idx[48][48][48]; 
-   
- static sq_t                             wksq [MAX_KKINDEX]; 
- static sq_t                             bksq [MAX_KKINDEX]; 
- static sq_t                             pp48_sq_x[MAX_PP48_INDEX]; 
- static sq_t                             pp48_sq_y[MAX_PP48_INDEX]; 
-   
- static index_t                  pp_hi24 [MAX_PPINDEX]; /* was unsigned int */ 
- static index_t                  pp_lo48 [MAX_PPINDEX]; 
- static unsigned int     flipt [64] [64]; 
- static index_t                  aaidx [64] [64]; /* was unsigned int */ 
- static unsigned char    aabase [MAX_AAINDEX]; 
-   
- static uint8_t                  ppp48_sq_x[MAX_PPP48_INDEX]; 
- static uint8_t                  ppp48_sq_y[MAX_PPP48_INDEX]; 
- static uint8_t                  ppp48_sq_z[MAX_PPP48_INDEX]; 
-   
- /* FUNCTIONS */ 
-   
- static void     init_indexing (int verbosity); 
- static void     norm_kkindex (SQUARE x, SQUARE y, /*@out@*/ SQUARE *pi, /*@out@*/ SQUARE *pj); 
- static void     pp_putanchorfirst (SQUARE a, SQUARE b, /*@out@*/ SQUARE *out_anchor, /*@out@*/ SQUARE *out_loosen); 
-   
- static index_t  wsq_to_pidx24 (SQUARE pawn); 
- static index_t  wsq_to_pidx48 (SQUARE pawn); 
- static SQUARE   pidx24_to_wsq (index_t a); 
- static SQUARE   pidx48_to_wsq (index_t a); 
-   
- static SQUARE   flipWE                  (SQUARE x) { return x ^  07;} 
- static SQUARE   flipNS                  (SQUARE x) { return x ^ 070;} 
- static SQUARE   flipNW_SE               (SQUARE x) { return ((x&7)<<3) | (x>>3);} 
- static SQUARE   getcol                  (SQUARE x) { return x &  7;} 
- static SQUARE   getrow                  (SQUARE x) { return x >> 3;} 
- static bool_t   in_queenside    (sq_t x)   { return 0 == (x & (1<<2));} 
-   
- /* 1:0 */ 
- static void     kxk_indextopc   (index_t i, SQUARE *pw, SQUARE *pb); 
-   
- /* 2:0 */ 
- static void     kabk_indextopc  (index_t i, SQUARE *pw, SQUARE *pb); 
- static void     kakb_indextopc  (index_t i, SQUARE *pw, SQUARE *pb); 
- static void             kaak_indextopc  (index_t i, SQUARE *pw, SQUARE *pb); 
-   
- /* 2:1 */ 
- static void     kabkc_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
- static void             kaakb_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
-   
- /* 3:0 */ 
- static void     kabck_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
- static void             kaabk_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
- static void             kaaak_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
- static void             kabbk_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
-   
- /* one pawn */ 
- static void     kpk_indextopc   (index_t i, SQUARE *pw, SQUARE *pb); 
-   
- /* 1:1 one pawn */ 
- static void     kakp_indextopc  (index_t i, SQUARE *pw, SQUARE *pb); 
-   
- /* 2:0 one pawn */ 
- static void     kapk_indextopc  (index_t i, SQUARE *pw, SQUARE *pb); 
-   
- /* 2:0 two pawns */ 
- static void     kppk_indextopc  (index_t i, SQUARE *pw, SQUARE *pb); 
-   
- /*  2:1 one pawn */ 
- static void             kapkb_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
- static void             kabkp_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
- static void             kaakp_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
-   
- /*  2:1 + 3:0 two pawns */ 
- static void             kppka_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
- static void             kappk_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
- static void             kapkp_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
-   
- /*  3:0 one pawn */ 
- static void             kabpk_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
- static void             kaapk_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
-   
- /*  three pawns */ 
- static void             kpppk_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
- static void             kppkp_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
-   
- /* 1:1 two pawns */ 
- static void     kpkp_indextopc  (index_t i, SQUARE *pw, SQUARE *pb); 
-   
- /* corresponding pc to index */ 
- static bool_t   kxk_pctoindex   (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out); 
- static bool_t   kabk_pctoindex  (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out); 
- static bool_t   kakb_pctoindex  (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out); 
- static bool_t   kpk_pctoindex   (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out); 
- static bool_t   kakp_pctoindex  (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out); 
- static bool_t   kapk_pctoindex  (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out); 
- static bool_t   kppk_pctoindex  (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out); 
- static bool_t   kaak_pctoindex  (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out); 
- static bool_t   kabkc_pctoindex (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out); 
-   
- static bool_t   kaakb_pctoindex (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out);/**/ 
-   
- static bool_t   kabck_pctoindex (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out); 
- static bool_t   kaabk_pctoindex (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out);/**/ 
- static bool_t   kaaak_pctoindex (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out); 
- static bool_t   kabbk_pctoindex (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out);/**/ 
- static bool_t   kapkb_pctoindex (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out); 
- static bool_t   kabkp_pctoindex (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out); 
- static bool_t   kaakp_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out); 
- static bool_t   kppka_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out); 
- static bool_t   kappk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out); 
- static bool_t   kapkp_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out); 
- static bool_t   kabpk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out); 
- static bool_t   kaapk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out); 
- static bool_t   kppkp_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out); 
- static bool_t   kpppk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out); 
- static bool_t   kpkp_pctoindex  (const SQUARE *pw,     const SQUARE *pb, /*@out@*/ index_t *out); 
-   
- /* testing functions */ 
- static bool_t   test_kppk  (void); 
- static bool_t   test_kaakb (void); 
- static bool_t   test_kaabk (void); 
- static bool_t   test_kaaak (void); 
- static bool_t   test_kabbk (void); 
- static bool_t   test_kapkb (void); 
- static bool_t   test_kabkp (void); 
- static bool_t   test_kppka (void); 
- static bool_t   test_kappk (void); 
- static bool_t   test_kapkp (void); 
- static bool_t   test_kabpk (void); 
- static bool_t   test_kaapk (void); 
- static bool_t   test_kaakp (void); 
- static bool_t   test_kppkp (void); 
- static bool_t   test_kpppk (void); 
-   
- static unsigned flip_type (SQUARE x, SQUARE y); 
- static index_t  init_kkidx (void); 
- static index_t  init_ppidx (void); 
- static void     init_flipt (void); 
- static index_t  init_aaidx (void); 
- static index_t  init_aaa   (void); 
- static index_t  init_pp48_idx (void); 
- static index_t  init_ppp48_idx (void); 
-   
- enum TB_INDEXES 
-          {       MAX_KXK        = MAX_KKINDEX*64 
-                 ,MAX_kabk       = MAX_KKINDEX*64*64 
-                 ,MAX_kakb       = MAX_KKINDEX*64*64 
-                 ,MAX_kpk        = 24*64*64 
-                 ,MAX_kakp       = 24*64*64*64 
-                 ,MAX_kapk       = 24*64*64*64 
-                 ,MAX_kppk       = MAX_PPINDEX*64*64 
-                 ,MAX_kpkp       = MAX_PpINDEX*64*64 
-                 ,MAX_kaak       = MAX_KKINDEX*MAX_AAINDEX 
-                 ,MAX_kabkc      = MAX_KKINDEX*64*64*64 
-                 ,MAX_kabck      = MAX_KKINDEX*64*64*64 
-                 ,MAX_kaakb      = MAX_KKINDEX*MAX_AAINDEX*64 
-                 ,MAX_kaabk      = MAX_KKINDEX*MAX_AAINDEX*64 
-                 ,MAX_kabbk  = MAX_KKINDEX*MAX_AAINDEX*64 
-                 ,MAX_kaaak      = MAX_KKINDEX*MAX_AAAINDEX 
-                 ,MAX_kapkb  = 24*64*64*64*64 
-                 ,MAX_kabkp  = 24*64*64*64*64 
-                 ,MAX_kabpk  = 24*64*64*64*64 
-                 ,MAX_kppka  = MAX_kppk*64 
-                 ,MAX_kappk  = MAX_kppk*64 
-                 ,MAX_kapkp  = MAX_kpkp*64 
-                 ,MAX_kaapk  = 24*MAX_AAINDEX*64*64 
-                 ,MAX_kaakp  = 24*MAX_AAINDEX*64*64 
-                 ,MAX_kppkp  = 24*MAX_PP48_INDEX*64*64 
-                 ,MAX_kpppk  = MAX_PPP48_INDEX*64*64 
- }; 
-   
- #if defined(SHARED_forbuilding) 
- extern index_t 
- biggest_memory_needed (void) { 
-     return MAX_kabkc; 
- } 
- #endif 
-   
- /*--------------------------------*\ 
- | 
- | 
- |               CACHE PROTOTYPES 
- | 
- | 
- *---------------------------------*/ 
-   
- #if !defined(SHARED_forbuilding) 
- mySHARED bool_t         get_dtm (tbkey_t key, unsigned side, index_t idx, dtm_t *out, bool_t probe_hard); 
- #endif 
-   
- static bool_t           get_dtm_from_cache (tbkey_t key, unsigned side, index_t idx, dtm_t *out); 
-   
-   
- /*--------------------------------*\ 
- | 
- | 
- |                       INIT 
- | 
- | 
- *---------------------------------*/ 
-   
- static bool_t   fd_init (struct filesopen *pfd); 
- static void             fd_done (struct filesopen *pfd); 
-   
- static void             RAM_egtbfree (void); 
-   
- /*--------------------------------------------------------------------------*/ 
- #if !defined(SHARED_forbuilding) 
- mySHARED void                   egtb_freemem (int i); 
- #endif 
-   
- mySHARED struct endgamekey egkey[] = { 
-   
- {0, "kqk",  MAX_KXK,  1, kxk_indextopc,  kxk_pctoindex,  NULL ,  NULL   ,NULL ,0, 0 }, 
- {1, "krk",  MAX_KXK,  1, kxk_indextopc,  kxk_pctoindex,  NULL ,  NULL   ,NULL ,0, 0 }, 
- {2, "kbk",  MAX_KXK,  1, kxk_indextopc,  kxk_pctoindex,  NULL ,  NULL   ,NULL ,0, 0 }, 
- {3, "knk",  MAX_KXK,  1, kxk_indextopc,  kxk_pctoindex,  NULL ,  NULL   ,NULL ,0, 0 }, 
- {4, "kpk",  MAX_kpk,  24,kpk_indextopc,  kpk_pctoindex,  NULL ,  NULL   ,NULL ,0, 0 }, 
-         /* 4 pieces */ 
- {5, "kqkq", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {6, "kqkr", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {7, "kqkb", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {8, "kqkn", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
-   
- {9, "krkr", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {10,"krkb", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {11,"krkn", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
-   
- {12,"kbkb", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {13,"kbkn", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
-   
- {14,"knkn", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
-         /**/ 
- {15,"kqqk", MAX_kaak, 1, kaak_indextopc, kaak_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {16,"kqrk", MAX_kabk, 1, kabk_indextopc, kabk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {17,"kqbk", MAX_kabk, 1, kabk_indextopc, kabk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {18,"kqnk", MAX_kabk, 1, kabk_indextopc, kabk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
-   
- {19,"krrk", MAX_kaak, 1, kaak_indextopc, kaak_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {20,"krbk", MAX_kabk, 1, kabk_indextopc, kabk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {21,"krnk", MAX_kabk, 1, kabk_indextopc, kabk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
-   
- {22,"kbbk", MAX_kaak, 1, kaak_indextopc, kaak_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {23,"kbnk", MAX_kabk, 1, kabk_indextopc, kabk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
-   
- {24,"knnk", MAX_kaak, 1, kaak_indextopc, kaak_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
-         /**/ 
-         /**/ 
- {25,"kqkp", MAX_kakp, 24,kakp_indextopc, kakp_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {26,"krkp", MAX_kakp, 24,kakp_indextopc, kakp_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {27,"kbkp", MAX_kakp, 24,kakp_indextopc, kakp_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {28,"knkp", MAX_kakp, 24,kakp_indextopc, kakp_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
-         /**/ 
- {29,"kqpk", MAX_kapk, 24,kapk_indextopc, kapk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {30,"krpk", MAX_kapk, 24,kapk_indextopc, kapk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {31,"kbpk", MAX_kapk, 24,kapk_indextopc, kapk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {32,"knpk", MAX_kapk, 24,kapk_indextopc, kapk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
-         /**/ 
- {33,"kppk", MAX_kppk, MAX_PPINDEX ,kppk_indextopc, kppk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
-         /**/ 
- {34,"kpkp", MAX_kpkp, MAX_PpINDEX ,kpkp_indextopc, kpkp_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
-         /**/ 
-         /**/ 
-         /* 5 pieces */ 
- { 35,"kqqqk", MAX_kaaak, 1, kaaak_indextopc, kaaak_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 36,"kqqrk", MAX_kaabk, 1, kaabk_indextopc, kaabk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 37,"kqqbk", MAX_kaabk, 1, kaabk_indextopc, kaabk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 38,"kqqnk", MAX_kaabk, 1, kaabk_indextopc, kaabk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 39,"kqrrk", MAX_kabbk, 1, kabbk_indextopc, kabbk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 40,"kqrbk", MAX_kabck, 1, kabck_indextopc, kabck_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 41,"kqrnk", MAX_kabck, 1, kabck_indextopc, kabck_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 42,"kqbbk", MAX_kabbk, 1, kabbk_indextopc, kabbk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 43,"kqbnk", MAX_kabck, 1, kabck_indextopc, kabck_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 44,"kqnnk", MAX_kabbk, 1, kabbk_indextopc, kabbk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 45,"krrrk", MAX_kaaak, 1, kaaak_indextopc, kaaak_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 46,"krrbk", MAX_kaabk, 1, kaabk_indextopc, kaabk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 47,"krrnk", MAX_kaabk, 1, kaabk_indextopc, kaabk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 48,"krbbk", MAX_kabbk, 1, kabbk_indextopc, kabbk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 49,"krbnk", MAX_kabck, 1, kabck_indextopc, kabck_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 50,"krnnk", MAX_kabbk, 1, kabbk_indextopc, kabbk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 51,"kbbbk", MAX_kaaak, 1, kaaak_indextopc, kaaak_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 52,"kbbnk", MAX_kaabk, 1, kaabk_indextopc, kaabk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 53,"kbnnk", MAX_kabbk, 1, kabbk_indextopc, kabbk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 54,"knnnk", MAX_kaaak, 1, kaaak_indextopc, kaaak_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 55,"kqqkq", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 56,"kqqkr", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 57,"kqqkb", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 58,"kqqkn", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 59,"kqrkq", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 60,"kqrkr", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 61,"kqrkb", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 62,"kqrkn", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 63,"kqbkq", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 64,"kqbkr", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 65,"kqbkb", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 66,"kqbkn", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 67,"kqnkq", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 68,"kqnkr", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 69,"kqnkb", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 70,"kqnkn", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 71,"krrkq", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 72,"krrkr", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 73,"krrkb", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 74,"krrkn", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 75,"krbkq", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 76,"krbkr", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 77,"krbkb", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 78,"krbkn", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 79,"krnkq", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 80,"krnkr", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 81,"krnkb", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 82,"krnkn", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 83,"kbbkq", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 84,"kbbkr", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 85,"kbbkb", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 86,"kbbkn", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 87,"kbnkq", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 88,"kbnkr", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 89,"kbnkb", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 90,"kbnkn", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 91,"knnkq", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 92,"knnkr", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 93,"knnkb", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 94,"knnkn", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
-   
- { 95,"kqqpk", MAX_kaapk, 24, kaapk_indextopc, kaapk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 96,"kqrpk", MAX_kabpk, 24, kabpk_indextopc, kabpk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 97,"kqbpk", MAX_kabpk, 24, kabpk_indextopc, kabpk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 98,"kqnpk", MAX_kabpk, 24, kabpk_indextopc, kabpk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- { 99,"krrpk", MAX_kaapk, 24, kaapk_indextopc, kaapk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {100,"krbpk", MAX_kabpk, 24, kabpk_indextopc, kabpk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {101,"krnpk", MAX_kabpk, 24, kabpk_indextopc, kabpk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {102,"kbbpk", MAX_kaapk, 24, kaapk_indextopc, kaapk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {103,"kbnpk", MAX_kabpk, 24, kabpk_indextopc, kabpk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {104,"knnpk", MAX_kaapk, 24, kaapk_indextopc, kaapk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
-   
- {105,"kqppk", MAX_kappk, MAX_PPINDEX, kappk_indextopc, kappk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {106,"krppk", MAX_kappk, MAX_PPINDEX, kappk_indextopc, kappk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {107,"kbppk", MAX_kappk, MAX_PPINDEX, kappk_indextopc, kappk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {108,"knppk", MAX_kappk, MAX_PPINDEX, kappk_indextopc, kappk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
-   
- {109,"kqpkq", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {110,"kqpkr", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {111,"kqpkb", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {112,"kqpkn", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {113,"krpkq", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {114,"krpkr", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {115,"krpkb", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {116,"krpkn", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {117,"kbpkq", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {118,"kbpkr", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {119,"kbpkb", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {120,"kbpkn", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {121,"knpkq", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {122,"knpkr", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {123,"knpkb", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {124,"knpkn", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
-   
- {125,"kppkq", MAX_kppka, MAX_PPINDEX, kppka_indextopc, kppka_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {126,"kppkr", MAX_kppka, MAX_PPINDEX, kppka_indextopc, kppka_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {127,"kppkb", MAX_kppka, MAX_PPINDEX, kppka_indextopc, kppka_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {128,"kppkn", MAX_kppka, MAX_PPINDEX, kppka_indextopc, kppka_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
-   
- {129,"kqqkp", MAX_kaakp, 24, kaakp_indextopc, kaakp_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {130,"kqrkp", MAX_kabkp, 24, kabkp_indextopc, kabkp_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {131,"kqbkp", MAX_kabkp, 24, kabkp_indextopc, kabkp_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {132,"kqnkp", MAX_kabkp, 24, kabkp_indextopc, kabkp_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {133,"krrkp", MAX_kaakp, 24, kaakp_indextopc, kaakp_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {134,"krbkp", MAX_kabkp, 24, kabkp_indextopc, kabkp_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {135,"krnkp", MAX_kabkp, 24, kabkp_indextopc, kabkp_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {136,"kbbkp", MAX_kaakp, 24, kaakp_indextopc, kaakp_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {137,"kbnkp", MAX_kabkp, 24, kabkp_indextopc, kabkp_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {138,"knnkp", MAX_kaakp, 24, kaakp_indextopc, kaakp_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
-   
- {139,"kqpkp", MAX_kapkp, MAX_PpINDEX, kapkp_indextopc, kapkp_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {140,"krpkp", MAX_kapkp, MAX_PpINDEX, kapkp_indextopc, kapkp_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {141,"kbpkp", MAX_kapkp, MAX_PpINDEX, kapkp_indextopc, kapkp_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {142,"knpkp", MAX_kapkp, MAX_PpINDEX, kapkp_indextopc, kapkp_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
-   
- {143,"kppkp", MAX_kppkp, 24*MAX_PP48_INDEX, kppkp_indextopc, kppkp_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
- {144,"kpppk", MAX_kpppk, MAX_PPP48_INDEX, kpppk_indextopc, kpppk_pctoindex, NULL ,  NULL   ,NULL ,0, 0 }, 
-   
- {MAX_EGKEYS, NULL,  0,        1, NULL,           NULL,           NULL,   NULL   ,NULL ,0 ,0} 
-   
- }; 
-   
- #define EGKEY_HASH_SIZE 512 
- static tbkey_t egkey_hash[EGKEY_HASH_SIZE]; 
-   
- static size_t 
- str_hash_func_1 (const char * str) 
- { 
-         size_t h = 5381; 
-         int c; 
-         while ((c = *str++)) 
-                 h = h * 31 + c; 
-         return h; 
- } 
-   
- static size_t 
- str_hash_func_2 (const char * str) 
- { 
-         size_t h = 0; 
-         int c; 
-         while ((c = *str++)) 
-                 h = h * 65599 + c; 
-         return 2 * h + 1; 
- } 
-   
- static void 
- init_egkey_hash (void) 
- { 
-         size_t h1, h2; 
-         int i; 
-   
-         for (i = 0; i < EGKEY_HASH_SIZE; i++) 
-                 egkey_hash[i] = -1; 
-   
-         for (i = 0; i < MAX_EGKEYS; i++) { 
-                 h1 = str_hash_func_1 (egkey[i].str) & (EGKEY_HASH_SIZE - 1); 
-                 h2 = str_hash_func_2 (egkey[i].str); 
-                 while (egkey_hash[h1] >= 0) 
-                         h1 = (h1 + h2) & (EGKEY_HASH_SIZE - 1); 
-                 egkey_hash[h1] = egkey[i].id; 
-         } 
- } 
-   
-   
- static int eg_was_open[MAX_EGKEYS]; 
-   
- static uint64_t Bytes_read = 0; 
-   
- /****************************************************************************\ 
- | 
- | 
- |                                               PATH MANAGEMENT ZONE 
- | 
- | 
- \****************************************************************************/ 
-   
- #define MAXPATHLEN tb_MAXPATHLEN 
- #define MAX_GTBPATHS 10 
-   
- static int                      Gtbpath_end_index = 0; 
- static const char **    Gtbpath = NULL; 
-   
- /*---------------- EXTERNAL PATH MANAGEMENT --------------------------------*/ 
-   
- extern const char *tbpaths_getmain (void) {     return Gtbpath[0];} 
-   
- extern const char ** 
- tbpaths_init(void) 
- { 
-         const char **newps; 
-         newps  = (const char **) malloc (sizeof (char *));
-         if (newps != NULL) { 
-                 newps[0] = NULL; 
-         } 
-         return newps; 
- } 
-   
- static const char ** 
- tbpaths_add_single(const char **ps, const char *newpath) 
- { 
-         size_t counter; 
-         const char **newps; 
-         size_t i, psize; 
-         char *ppath; 
-   
-         if (NULL == ps) 
-                 return NULL; 
-   
-         ppath  = (char *) malloc (- psize  * sizeof (char));
-         if (NULL == ppath) 
-                 return ps; /* failed to incorporate a new path */ 
-         for (i = 0; i < psize; i++) ppath[i] = newpath[i]; 
-   
-         for (counter = 0; ps[counter] != NULL; counter++) 
-                 ; 
-   
-         /* cast to deal with const poisoning */ 
-         newps  = (const char **) realloc ((char **)- ps , sizeof(char *) * (- counter +2));
-         if (newps != NULL) { 
-                 newps [counter] = ppath; 
-                 newps [counter+1] = NULL; 
-         } 
-         return newps; 
- } 
-   
-   
- extern const char ** 
- tbpaths_add(const char **ps, const char *newpath) 
- { 
-         size_t i, psize; 
-         char *mpath; 
-   
-         if (NULL == ps) 
-                 return NULL; 
-   
-         mpath  = (char *) malloc (- psize  * sizeof (char));
-         if (NULL == mpath) { 
-                 return ps; /* failed to incorporate a new path */ 
-         } 
-         for (i = 0; i < psize; i++) mpath[i] = newpath[i]; 
-   
-         for (i = 0; i < psize; i++) { 
-                 if(';' == mpath[i]) 
-                         mpath[i] = '\0'; 
-         } 
-   
-         for (i = 0;;) { 
-                 while (i < psize && mpath[i] == '\0') i++; 
-                 if (i >= psize) break; 
-                 ps = tbpaths_add_single (ps, &mpath[i]); 
-                 while (i < psize && mpath[i] != '\0') i++; 
-         } 
-   
-         return ps; 
- } 
-   
-   
- extern const char ** 
- tbpaths_done(const char **ps) 
- { 
-         int counter; 
-         void *q; 
-   
-         if (ps != NULL) { 
-                 for (counter = 0; ps[counter] != NULL; counter++) { 
-                         /* cast to deal with const poisoning */ 
-                         void *p = (void *) ps[counter]; 
-                 } 
-                 /* cast to deal with const poisoning */ 
-                 q = (void *) ps; 
-         } 
-         return NULL; 
- } 
-   
- /*---------------- PATH INITIALIZATION ROUTINES ----------------------------*/ 
-   
- static void path_system_reset(void) {Gtbpath_end_index = 0;} 
-   
- static bool_t 
- path_system_init (const char **path) 
- { 
-         size_t i; 
-         size_t sz; 
-         const char *x; 
-         bool_t ok = TRUE; 
-         path_system_reset(); 
-   
-         if (path == NULL) { 
-                 return FALSE; 
-         } 
-   
-         /* calculate needed size for Gtbpath */ 
-         i = 0; 
-         do { 
-                 x = path[i++]; 
-         } while (x != NULL); 
-         sz = i; /* sz includes the NULL */ 
-   
-   
-         Gtbpath  = (const char **) malloc (- sz  * sizeof(char *));
-   
-         if (Gtbpath) { 
-   
-                 ok = TRUE; 
-                 /* point to the same strings provided */ 
-                 Gtbpath_end_index = 0; 
-                 for (i = 0; i < sz; i++) { 
-                         Gtbpath[i] = path[i]; 
-                         Gtbpath_end_index++; 
-                 } 
-   
-         } else { 
-                 ok = FALSE; 
-         } 
-         return ok; 
-   
- } 
-   
- static void 
- path_system_done (void) 
- { 
-         /* before we free Gtbpath, we have to deal with the 
-         "const poisoning" and cast it. free() does not accept 
-         const pointers */ 
-         char ** p = (char **) Gtbpath; 
-         /* clean up */ 
-         if (p != NULL) 
-         return; 
- } 
-   
-   
- /****************************************************************************\ 
-  * 
-  * 
-  *                                              General Initialization Zone 
-  * 
-  * 
-  ****************************************************************************/ 
-   
-   
- #ifdef WDL_PROBE 
- static size_t           wdl_cache_init (size_t cache_mem); 
- static void             wdl_cache_flush (void); 
-   
- static void                     wdl_cache_reset_counters (void); 
- static void                     wdl_cache_done (void); 
-   
- static bool_t           get_WDL_from_cache (tbkey_t key, unsigned side, index_t idx, unsigned int *out); 
- static bool_t           wdl_preload_cache (tbkey_t key, unsigned side, index_t idx); 
- #endif 
-   
- #ifdef GTB_SHARE 
- static void     init_bettarr (void); 
- #endif 
-   
- static void     eg_was_open_reset(void) 
- { 
-         int i; 
-         for (i = 0; i < MAX_EGKEYS; i++) { 
-                 eg_was_open[i] = 0; 
-         } 
- } 
-   
- static long unsigned int eg_was_open_count(void) 
- { 
-         long int i, x; 
-         for (i = 0, x = 0; i < MAX_EGKEYS; i++) { 
-                 x += eg_was_open[i]; 
-         } 
-         return (long unsigned) x; 
- } 
-   
-   
- enum  Sizes {INISIZE = 4096}; 
- static char ini_str[INISIZE]; 
- static void-  sjoin_s (char *- s , size_t-  size , const char *- tail , size_t-  max ) {- strncat_s (- s ,-  size ,-  tail ,-  max  - strlen(- s ) - 1);} // Pierre-Marie Baty -- safer version
 
-   
- char * 
- tb_init (int verbosity, int decoding_sch, const char **paths) 
- { 
-         unsigned int zi; 
-         int paths_ok; 
-         char *ret_str; 
-         char localstr[256]; 
-   
-   
-         init_egkey_hash (); 
-   
-         if (verbosity) { 
-                 ini_str[0] = '\0'; 
-                 ret_str = ini_str; 
-         } else { 
-                 ret_str = NULL; 
-         } 
-   
-         paths_ok = path_system_init (paths); 
-   
-         if (paths_ok && verbosity) { 
-                 int g; 
-                 sjoin_s(ini_str,sizeof(ini_str),"\nGTB PATHS\n",INISIZE); // Pierre-Marie Baty -- using a more secure version of this function 
-                 for (g = 0; Gtbpath[g] != NULL; g++) { 
-                         const char *p = Gtbpath[g]; 
-                         if (0 == g) { 
-                                 sprintf_s (localstr, sizeof(localstr),"  main: %s\n", p); // Pierre-Marie Baty -- using sprintf_s() instead of sprintf 
-                         } else { 
-                                 sprintf_s (localstr, sizeof(localstr),"    #%d: %s\n", g, p); // Pierre-Marie Baty -- using sprintf_s() instead of sprintf 
-                         } 
-          sjoin_s(ini_str,sizeof(ini_str),localstr,INISIZE); // Pierre-Marie Baty -- using a more secure version of this function 
-                 } 
-         } 
-   
-         if (!paths_ok && verbosity) { 
-                 sjoin_s (ini_str,sizeof(ini_str),"\nGTB PATHS not initialized\n",INISIZE); // Pierre-Marie Baty -- using a more secure version of this function 
-         } 
-   
-         if (!reach_was_initialized()) 
-                 reach_init(); 
-   
-         attack_maps_init (); /* external initialization */ 
-   
-         init_indexing(0 /* no verbosity */); 
-   
-         #ifdef GTB_SHARE 
-         init_bettarr(); 
-         #endif 
-   
-         if (!fd_init (&fd) && verbosity) { 
-                 sjoin_s (ini_str,sizeof(ini_str),"  File Open Memory initialization = **FAILED**\n",INISIZE); // Pierre-Marie Baty -- using a more secure version of this function 
-                 return ret_str; 
-         } 
-   
-         GTB_scheme = decoding_sch; 
-         Uncompressed = GTB_scheme == 0; 
-   
-         if (GTB_scheme == 0) { 
-                 Uncompressed = TRUE; 
-         } 
-   
-         set_decoding_scheme(GTB_scheme); 
-   
-         if (verbosity) { 
-                 sjoin_s (ini_str,sizeof(ini_str),"\nGTB initialization\n",INISIZE); // Pierre-Marie Baty -- using a more secure version of this function 
-       sprintf_s (localstr, sizeof (localstr), "  Compression  Scheme = %d\n", GTB_scheme); // Pierre-Marie Baty -- using sprintf_s() instead of sprintf 
-                 sjoin_s (ini_str,sizeof(ini_str),localstr,INISIZE); // Pierre-Marie Baty -- using a more secure version of this function 
-         } 
-   
-         zi = zipinfo_init(); 
-   
-         TB_AVAILABILITY = zi; 
-   
-         if (verbosity) { 
-                 if (0 == zi) { 
-                         sjoin_s (ini_str,sizeof(ini_str),"  Compression Indexes = **FAILED**\n",INISIZE); // Pierre-Marie Baty -- using a more secure version of this function 
-                 } else { 
-                         int n, bit; 
-   
-                         n = 3; bit = 1; 
-                         if (zi&(1u<<bit)) 
-             sprintf_s (localstr, sizeof (localstr), "  Compression Indexes (%d-pc) = PASSED\n",n); // Pierre-Marie Baty -- using sprintf_s() instead of sprintf 
-                         else 
-             sprintf_s (localstr, sizeof (localstr), "  Compression Indexes (%d-pc) = **FAILED**\n",n); // Pierre-Marie Baty -- using sprintf_s() instead of sprintf 
-                         sjoin_s (ini_str,sizeof(ini_str),localstr,INISIZE); // Pierre-Marie Baty -- using a more secure version of this function 
-   
-                         n = 4; bit = 3; 
-                         if (zi&(1u<<bit)) 
-             sprintf_s (localstr, sizeof (localstr), "  Compression Indexes (%d-pc) = PASSED\n",n); // Pierre-Marie Baty -- using sprintf_s() instead of sprintf 
-                         else 
-             sprintf_s (localstr, sizeof (localstr), "  Compression Indexes (%d-pc) = **FAILED**\n",n); // Pierre-Marie Baty -- using sprintf_s() instead of sprintf 
-                         sjoin_s (ini_str,sizeof(ini_str),localstr,INISIZE); // Pierre-Marie Baty -- using a more secure version of this function 
-   
-                         n = 5; bit = 5; 
-                         if (zi&(1u<<bit)) 
-             sprintf_s (localstr, sizeof (localstr), "  Compression Indexes (%d-pc) = PASSED\n",n); // Pierre-Marie Baty -- using sprintf_s() instead of sprintf 
-                         else 
-                                 sprintf_s (localstr, sizeof(localstr),"  Compression Indexes (%d-pc) = **FAILED**\n",n); // Pierre-Marie Baty -- using sprintf_s() instead of sprintf 
-                         sjoin_s (ini_str,sizeof(ini_str),localstr,INISIZE); // Pierre-Marie Baty -- using a more secure version of this function 
-                 } 
-                 sjoin_s (ini_str,sizeof(ini_str),"\n",INISIZE); // Pierre-Marie Baty -- using a more secure version of this function 
-         } 
-   
-         eg_was_open_reset(); 
-         Bytes_read = 0; 
-   
-         mythread_mutex_init (&Egtb_lock); 
-   
-         TB_INITIALIZED = TRUE; 
-   
-         return ret_str; 
- } 
-   
- extern unsigned int 
- tb_availability(void) 
- { 
-         return TB_AVAILABILITY; 
- } 
-   
- extern bool_t 
- tb_is_initialized (void) 
- { 
-         return TB_INITIALIZED; 
- } 
-   
- extern void 
- tb_done (void) 
- { 
-         fd_done (&fd); 
-         RAM_egtbfree(); 
-         zipinfo_done(); 
-         path_system_done(); 
-         mythread_mutex_destroy (&Egtb_lock); 
-         TB_INITIALIZED = FALSE; 
-   
-         /* 
-                 HERE, I should be free() the ini_str, but in 
-                 the current implementation, it is static 
-                 rather than dynamic. 
-         */ 
-         return; 
- } 
-   
- char * 
- tb_restart(int verbosity, int decoding_sch, const char **paths) 
- { 
-         if (tb_is_initialized()) { 
-                 tb_done(); 
-         } 
-         return tb_init(verbosity, decoding_sch, paths); 
- } 
-   
- /* whenever the program exits should release this memory */ 
- static void 
- RAM_egtbfree (void) 
- { 
-         int i; 
-         for (i = 0; egkey[i].str != NULL; i++) { 
-                 egtb_freemem (i); 
-         } 
- } 
-   
- /*--------------------------------------------------------------------------*/ 
-   
- #ifdef GTB_SHARE 
- static void 
- init_bettarr (void) 
- { 
- /* 
-                 iDRAW  = 0, iWMATE  = 1, iBMATE  = 2, iFORBID  = 3, 
-                 iDRAWt = 4, iWMATEt = 5, iBMATEt = 6, iUNKNOWN = 7 
-  */ 
-   
-         int temp[] = { 
-         /*White*/ 
-         /*iDRAW   vs*/ 
-                 1, 2, 1, 1,     2, 2, 2, 2, 
-         /*iWMATE  vs*/ 
-                 1, 3, 1, 1,     1, 1, 1, 1, 
-         /*iBMATE  vs*/ 
-                 2, 2, 4, 1,     2, 2, 2, 2, 
-         /*iFORBID vs*/ 
-                 2, 2, 2, 2,     2, 2, 2, 2, 
-   
-         /*iDRAWt  vs*/ 
-                 1, 2, 1, 1,     2, 2, 1, 2, 
-         /*iWMATEt vs*/ 
-                 1, 2, 1, 1,     1, 3, 1, 1, 
-         /*iBMATEt vs*/ 
-                 1, 2, 1, 1,     2, 2, 4, 2, 
-         /*iUNKNOWN  */ 
-                 1, 2, 1, 1,     1, 2, 1, 2, 
-   
-         /*Black*/ 
-         /*iDRAW   vs*/ 
-                 1, 1, 2, 1,     2, 2, 2, 2, 
-         /*iWMATE  vs*/ 
-                 2, 4, 2, 1,     2, 2, 2, 2, 
-         /*iBMATE  vs*/ 
-                 1, 1, 3, 1,     1, 1, 1, 1, 
-         /*iFORBID vs*/ 
-                 2, 2, 2, 2,     2, 2, 2, 2, 
-   
-         /*iDRAWt  vs*/ 
-                 1, 1, 2, 1,     2, 1, 2, 2, 
-         /*iWMATEt vs*/ 
-                 1, 1, 2, 1,     2, 4, 2, 2, 
-         /*iBMATEt vs*/ 
-                 1, 1, 2, 1,     1, 1, 3, 1, 
-         /*iUNKNOWN  */ 
-                 1, 1, 2, 1,     1, 1, 2, 2 
-         }; 
-   
-         int i, j, k, z; 
-   
-         /* reset */ 
-         z = 0; 
-         for (i = 0; i < 2; i++) 
-                 for (j = 0; j < 8; j++) 
-                         for (k = 0; k < 8; k++) 
-                                 bettarr [i][j][k] = temp[z++]; 
-   
-         return; 
- } 
- #endif 
-   
- /* 
- | 
- |       Own File Descriptors 
- | 
- \*---------------------------------------------------------------------------*/ 
-   
- static bool_t 
- fd_init (struct filesopen *pfd) 
- { 
-         tbkey_t *p; 
-     int i, allowed; 
-   
-         pfd->n = 0; 
-   
-         allowed = mysys_fopen_max() - 5 /*stdin,stdout,sterr,stdlog,book*/; 
-         if (allowed < 4) 
-                 GTB_MAXOPEN = 4; 
-         if (allowed > 32) 
-                 GTB_MAXOPEN = 32; 
-   
-         p  =     (- tbkey_t  *) malloc(sizeof(- tbkey_t )*(size_t)- GTB_MAXOPEN );
-   
-         if (p != NULL) { 
-                 for (i = 0; i < GTB_MAXOPEN; i++) { 
-                         p[i] = -1; 
-                 } 
-                 pfd->key = p; 
-                 return TRUE; 
-         } else { 
-                 return FALSE; 
-         } 
- } 
-   
- static void 
- fd_done (struct filesopen *pfd) 
- { 
-     int i; 
-         tbkey_t closingkey; 
-         FILE *finp; 
-   
-   
-         for (i = 0; i < pfd->n; i++) { 
-                 closingkey = pfd->key[i]; 
-                 finp = egkey [closingkey].fd; 
-                 egkey[closingkey].fd = NULL; 
-                 pfd->key[i] = -1; 
-         } 
-         pfd->n = 0; 
- } 
-   
- /****************************************************************************\ 
- | 
- | 
- |                                                               PROBE ZONE 
- | 
- | 
- \****************************************************************************/ 
-   
- #if !defined(SHARED_forbuilding) 
-   
- /* shared with building routines */ 
- mySHARED void                   list_sq_copy    (const SQUARE *a, SQUARE *b); 
- mySHARED void                   list_pc_copy    (const SQ_CONTENT *a, SQ_CONTENT *b); 
- mySHARED dtm_t                  inv_dtm                 (dtm_t x); 
- mySHARED bool_t                 egtb_get_id     (SQ_CONTENT *w, SQ_CONTENT *b, tbkey_t *id); 
- mySHARED void                   list_sq_flipNS  (SQUARE *s); 
- mySHARED dtm_t                  adjust_up               (dtm_t dist); 
- mySHARED dtm_t                  bestx                   (unsigned stm, dtm_t a, dtm_t b); 
- mySHARED void                   sortlists               (SQUARE *ws, SQ_CONTENT *wp); 
-   
- mySHARED /*@NULL@*/     FILE * fd_openit(tbkey_t key); 
-   
- mySHARED dtm_t                  dtm_unpack      (unsigned stm, unsigned char packed); 
- mySHARED void                   unpackdist      (dtm_t d, unsigned int *res, unsigned int *ply); 
- mySHARED dtm_t                  packdist        (unsigned int inf, unsigned int ply); 
-   
- mySHARED bool_t                 fread_entry_packed      (FILE *dest, unsigned side, dtm_t *px); 
- mySHARED bool_t                 fpark_entry_packed  (FILE *finp, unsigned side, index_t max, index_t idx); 
- #endif 
-   
- /* use only with probe */ 
- static bool_t                   egtb_get_dtm    (tbkey_t k, unsigned stm, const SQUARE *wS, const SQUARE *bS, bool_t probe_hard, dtm_t *dtm); 
- static void                             removepiece (SQUARE *ys, SQ_CONTENT *yp, int j); 
- static bool_t                   egtb_filepeek (tbkey_t key, unsigned side, index_t idx, dtm_t *out_dtm); 
-   
-   
- /*prototype*/ 
- #ifdef WDL_PROBE 
- static bool_t 
- tb_probe_wdl 
-                         (unsigned stm, 
-                          const SQUARE *inp_wSQ, 
-                          const SQUARE *inp_bSQ, 
-                          const SQ_CONTENT *inp_wPC, 
-                          const SQ_CONTENT *inp_bPC, 
-                          bool_t probingtype, 
-                          /*@out@*/ unsigned *res); 
- #endif 
-   
- static bool_t 
- tb_probe_       (unsigned stm, 
-                          SQUARE epsq, 
-                          const SQUARE *inp_wSQ, 
-                          const SQUARE *inp_bSQ, 
-                          const SQ_CONTENT *inp_wPC, 
-                          const SQ_CONTENT *inp_bPC, 
-                          bool_t probingtype, 
-                          /*@out@*/ unsigned *res, 
-                          /*@out@*/ unsigned *ply); 
-   
-   
- extern bool_t 
- tb_probe_soft 
-                         (unsigned stm, 
-                          SQUARE epsq, 
-                          unsigned castles, 
-                          const SQUARE *inp_wSQ, 
-                          const SQUARE *inp_bSQ, 
-                          const SQ_CONTENT *inp_wPC, 
-                          const SQ_CONTENT *inp_bPC, 
-                          /*@out@*/ unsigned *res, 
-                          /*@out@*/ unsigned *ply) 
- { 
-         if (castles != 0) 
-                 return FALSE; 
-         return tb_probe_ (stm, epsq, inp_wSQ, inp_bSQ, inp_wPC, inp_bPC, FALSE, res, ply); 
- } 
-   
- extern bool_t 
- tb_probe_hard 
-                         (unsigned stm, 
-                          SQUARE epsq, 
-                          unsigned castles, 
-                          const SQUARE *inp_wSQ, 
-                          const SQUARE *inp_bSQ, 
-                          const SQ_CONTENT *inp_wPC, 
-                          const SQ_CONTENT *inp_bPC, 
-                          /*@out@*/ unsigned *res, 
-                          /*@out@*/ unsigned *ply) 
- { 
-         if (castles != 0) 
-                 return FALSE; 
-         return tb_probe_ (stm, epsq, inp_wSQ, inp_bSQ, inp_wPC, inp_bPC, TRUE, res, ply); 
- } 
-   
- extern bool_t 
- tb_probe_WDL_soft 
-                         (unsigned stm, 
-                          SQUARE epsq, 
-                          unsigned castles, 
-                          const SQUARE *inp_wSQ, 
-                          const SQUARE *inp_bSQ, 
-                          const SQ_CONTENT *inp_wPC, 
-                          const SQ_CONTENT *inp_bPC, 
-                          /*@out@*/ unsigned *res) 
- { 
-         unsigned ply_n; 
-         unsigned *ply = &ply_n; 
-         if (castles != 0) 
-                 return FALSE; 
-         if (epsq != NOSQUARE) 
-                 return tb_probe_ (stm, epsq, inp_wSQ, inp_bSQ, inp_wPC, inp_bPC, FALSE, res, ply); 
-   
-         /* probe bitbase like, assuming no en passant */ 
-         #ifdef WDL_PROBE 
-         return tb_probe_wdl    (stm, inp_wSQ, inp_bSQ, inp_wPC, inp_bPC, FALSE, res); 
-         #else 
-         return tb_probe_ (stm, epsq, inp_wSQ, inp_bSQ, inp_wPC, inp_bPC, FALSE, res, ply); 
-         #endif 
- } 
-   
- extern bool_t 
- tb_probe_WDL_hard 
-                         (unsigned stm, 
-                          SQUARE epsq, 
-                          unsigned castles, 
-                          const SQUARE *inp_wSQ, 
-                          const SQUARE *inp_bSQ, 
-                          const SQ_CONTENT *inp_wPC, 
-                          const SQ_CONTENT *inp_bPC, 
-                          /*@out@*/ unsigned *res) 
- { 
-         unsigned ply_n; 
-         unsigned *ply = &ply_n; 
-         if (castles != 0) 
-                 return FALSE; 
-         if (epsq != NOSQUARE) 
-                 return tb_probe_ (stm, epsq, inp_wSQ, inp_bSQ, inp_wPC, inp_bPC, TRUE, res, ply); 
-   
-         /* probe bitbase like, assuming no en passant */ 
-         #ifdef WDL_PROBE 
-         return tb_probe_wdl    (stm, inp_wSQ, inp_bSQ, inp_wPC, inp_bPC, TRUE, res); 
-         #else 
-         return tb_probe_ (stm, epsq, inp_wSQ, inp_bSQ, inp_wPC, inp_bPC, TRUE, res, ply); 
-         #endif 
- } 
-   
-   
- static bool_t 
- tb_probe_       (unsigned stm, 
-                          SQUARE epsq, 
-                          const SQUARE *inp_wSQ, 
-                          const SQUARE *inp_bSQ, 
-                          const SQ_CONTENT *inp_wPC, 
-                          const SQ_CONTENT *inp_bPC, 
-                          bool_t probingtype, 
-                          /*@out@*/ unsigned *res, 
-                          /*@out@*/ unsigned *ply) 
- { 
-         int i = 0, j = 0; 
-         tbkey_t id = -1; 
-         dtm_t dtm = 0; 
-   
-         SQUARE          storage_ws [MAX_LISTSIZE], storage_bs [MAX_LISTSIZE]; 
-         SQ_CONTENT  storage_wp [MAX_LISTSIZE], storage_bp [MAX_LISTSIZE]; 
-   
-         SQUARE     *ws = storage_ws; 
-         SQUARE     *bs = storage_bs; 
-         SQ_CONTENT *wp = storage_wp; 
-         SQ_CONTENT *bp = storage_bp; 
-   
-         SQUARE     *xs; 
-         SQUARE     *ys; 
-         SQ_CONTENT *xp; 
-         SQ_CONTENT *yp; 
-   
-         SQUARE          tmp_ws [MAX_LISTSIZE], tmp_bs [MAX_LISTSIZE]; 
-         SQ_CONTENT  tmp_wp [MAX_LISTSIZE], tmp_bp [MAX_LISTSIZE]; 
-   
-         SQUARE *temps; 
-         bool_t straight = FALSE; 
-   
-         SQUARE capturer_a, capturer_b, xed = NOSQUARE; 
-   
-         unsigned int plies; 
-         unsigned int inf; 
-   
-         bool_t  okdtm  = TRUE; 
-         bool_t  okcall = TRUE; 
-   
-         /************************************/ 
-   
-         assert (- stm  ==-  WH  ||-  stm  ==-  BL );
 
-         /*assert (inp_wPC[0] == KING && inp_bPC[0] == KING );*/ 
-         assert ((- epsq  >> 3) == 2 || (- epsq  >> 3) == 5 ||-  epsq  ==-  NOSQUARE );
 
-   
-         /* VALID ONLY FOR KK!! */ 
-         if (inp_wPC[1] == NOPIECE && inp_bPC[1] == NOPIECE) { 
-                 index_t dummy_i; 
-                 bool_t b = kxk_pctoindex (inp_wSQ, inp_bSQ, &dummy_i); 
-                 *res = b? iDRAW: iFORBID; 
-                 *ply = 0; 
-                 return TRUE; 
-         } 
-   
-         /* copy input */ 
-         list_pc_copy (inp_wPC, wp); 
-         list_pc_copy (inp_bPC, bp); 
-         list_sq_copy (inp_wSQ, ws); 
-         list_sq_copy (inp_bSQ, bs); 
-   
-         sortlists (ws, wp); 
-         sortlists (bs, bp); 
-   
-         FOLLOW_label("EGTB_PROBE") 
-   
-         if (egtb_get_id (wp, bp, &id)) { 
-                 FOLLOW_LU("got ID",id) 
-                 straight = TRUE; 
-         } else if (egtb_get_id (bp, wp, &id)) { 
-                 FOLLOW_LU("rev ID",id) 
-                 straight = FALSE; 
-                 list_sq_flipNS (ws); 
-                 list_sq_flipNS (bs); 
-         temps = ws; 
-         ws = bs; 
-         bs = temps; 
-                 stm = Opp(stm); 
-                 if (epsq != NOSQUARE) epsq ^= 070;                              /* added */ 
-                 {SQ_CONTENT *tempp = wp; wp = bp; bp = tempp;}  /* added */ 
-         } else { 
-                 #if defined(DEBUG) 
-                 printf("did not get id...\n"); 
-                 output_state (stm, ws, bs, wp, bp); 
-                 #endif 
-                 unpackdist (iFORBID, res, ply); 
-                 return FALSE; 
-         } 
-   
-         /* store position... */ 
-         list_pc_copy (wp, tmp_wp); 
-         list_pc_copy (bp, tmp_bp); 
-         list_sq_copy (ws, tmp_ws); 
-         list_sq_copy (bs, tmp_bs); 
-   
-         /* x will be stm and y will be stw */ 
-         if (stm == WH) { 
-         xs = ws; 
-         xp = wp; 
-         ys = bs; 
-         yp = bp; 
-     } else { 
-         xs = bs; 
-         xp = bp; 
-         ys = ws; 
-         yp = wp; 
-         } 
-   
-         okdtm = egtb_get_dtm (id, stm, ws, bs, probingtype, &dtm); 
-   
-         FOLLOW_LU("dtmok?",okdtm) 
-         FOLLOW_DTM("dtm", dtm) 
-   
-         if (okdtm) { 
-   
-                 capturer_a = NOSQUARE; 
-                 capturer_b = NOSQUARE; 
-   
-                 if (epsq != NOSQUARE) { 
-                         /* captured pawn, trick: from epsquare to captured */ 
-                         xed = epsq ^ (1<<3); 
-   
-                         /* find index captured (j) */ 
-                         for (j = 0; ys[j] != NOSQUARE; j++) { 
-                                 if (ys[j] == xed) break; 
-                         } 
-   
-                         /* try first possible ep capture */ 
-                         if (0 == (0x88 & (map88(xed) + 1))) 
-                                 capturer_a = xed + 1; 
-                         /* try second possible ep capture */ 
-                         if (0 == (0x88 & (map88(xed) - 1))) 
-                                 capturer_b = xed - 1; 
-   
-                         if (ys[j] == xed) { 
-   
-                                 /* find capturers (i) */ 
-                                 for (i = 0; xs[i] != NOSQUARE && okcall; i++) { 
-   
-                                         if (xp[i]==PAWN && (xs[i]==capturer_a || xs[i]==capturer_b)) { 
-                                                 dtm_t epscore = iFORBID; 
-   
-                                                 /* execute capture */ 
-                                                 xs[i] = epsq; 
-                                                 removepiece (ys, yp, j); 
-   
-                                                 okcall = tb_probe_ (Opp(stm), NOSQUARE, ws, bs, wp, bp, probingtype, &inf, &plies); 
-   
-                                                 if (okcall) { 
-                                                         epscore = packdist (inf, plies); 
-                                                         epscore = adjust_up (epscore); 
-   
-                                                         /* chooses to ep or not */ 
-                                                         dtm = bestx (stm, epscore, dtm); 
-                                                 } 
-   
-                                                 /* restore position */ 
-                                                 list_pc_copy (tmp_wp, wp); 
-                                                 list_pc_copy (tmp_bp, bp); 
-   
-                                                 list_sq_copy (tmp_ws, ws); 
-                                                 list_sq_copy (tmp_bs, bs); 
-                                         } 
-                                 } 
-                         } 
-                 } /* ep */ 
-   
-                 if (straight) { 
-                         unpackdist (dtm, res, ply); 
-                 } else { 
-                         unpackdist (inv_dtm (dtm), res, ply); 
-                 } 
-         } 
-   
-         if (!okdtm || !okcall) { 
-                 unpackdist (iFORBID, res, ply); 
-         } 
-   
-         return okdtm && okcall; 
- } 
-   
- #ifdef _MSC_VER 
- /* to silence warning for sprintf usage */ 
- #pragma warning(disable:4996) 
- #endif 
-   
- static bool_t 
- egtb_filepeek (tbkey_t key, unsigned side, index_t idx, dtm_t *out_dtm) 
- { 
-         FILE *finp; 
-   
- #define USE_FD 
-   
-         #if !defined(USE_FD) 
-         char buf[1024]; 
-         char *filename = buf; 
-         #endif 
-   
-         bool_t ok; 
-     dtm_t x=0; 
-         index_t maxindex  = egkey[key].maxindex; 
-   
-   
-   
-         assert (- side  ==-  WH  ||-  side  ==-  BL );
 
-   
-   
-         #if defined(USE_FD) 
-                 if (NULL == (finp = egkey[key].fd) ) { 
-                         if (NULL == (finp = fd_openit (key))) { 
-                                 return FALSE; 
-                         } 
-                 } 
-         #else 
-                 sprintf (- buf , "%s.gtb",-  egkey [- key ]- . str);
 
-                 if (- NULL  == (- finp  = fopen (- filename , "rb"))) {
 
-                         return FALSE; 
-                 } 
-         #endif 
-   
-         ok = fpark_entry_packed (finp, side, maxindex, idx); 
-         ok = ok && fread_entry_packed (finp, side, &x); 
-   
-         if (ok) { 
-                 *out_dtm = x; 
-         } else 
-                 *out_dtm = iFORBID; 
-   
-         #if !defined(USE_FD) 
-         #endif 
-   
-         return ok; 
- } 
-   
- /* will get defined later */ 
- static bool_t                   dtm_cache_is_on (void); 
-   
- static bool_t 
- egtb_get_dtm (tbkey_t k, unsigned stm, const SQUARE *wS, const SQUARE *bS, bool_t probe_hard_flag, dtm_t *dtm) 
- { 
-         bool_t idxavail; 
-         index_t idx; 
-         dtm_t *tab[2]; 
-         bool_t (*pc2idx) (const SQUARE *, const SQUARE *, index_t *); 
-   
-         FOLLOW_label("egtb_get_dtm --> starts") 
-   
-         if (egkey[k].status == STATUS_MALLOC || egkey[k].status == STATUS_STATICRAM) { 
-   
-                 tab[WH] = egkey[k].egt_w; 
-                 tab[BL] = egkey[k].egt_b; 
-                 pc2idx  = egkey[k].pctoi; 
-   
-                 idxavail = pc2idx (wS, bS, &idx); 
-   
-                 FOLLOW_LU("indexavail (RAM)",idxavail) 
-   
-                 if (idxavail) { 
-                         *dtm = tab[stm][idx]; 
-                 } else { 
-                         *dtm = iFORBID; 
-                 } 
-   
-                 return TRUE; 
-   
-         } else if (egkey[k].status == STATUS_ABSENT) { 
-   
-                 pc2idx   = egkey[k].pctoi; 
-                 idxavail = pc2idx (wS, bS, &idx); 
-   
-                 FOLLOW_LU("indexavail (HD)",idxavail) 
-   
-                 if (idxavail) { 
-                         bool_t success; 
-   
-                         /* 
-                         |               LOCK 
-                         *-------------------------------*/ 
-                         mythread_mutex_lock (&Egtb_lock); 
-   
-                         if (dtm_cache_is_on()) { 
-   
-                                 success = get_dtm       (k, stm, idx, dtm, probe_hard_flag); 
-   
-                                 FOLLOW_LU("get_dtm (succ)",success) 
-                                 FOLLOW_LU("get_dtm (dtm )",*dtm) 
-   
-                                         #if defined(DEBUG) 
-                                         if (Uncompressed) { 
-                                                 dtm_t   dtm_temp; 
-                                                 bool_t  ok; 
-                                                 bool_t  success2; 
-   
-                                                 assert (- decoding_scheme () == 0 &&-  GTB_scheme  == 0);
 
-   
-                                                 success2 = egtb_filepeek (k, stm, idx, &dtm_temp); 
-                                                 ok =  (success == success2) && (!success || *dtm == dtm_temp); 
-                                                 if (!ok) { 
-                                                         printf ("\nERROR\nsuccess1=%d sucess2=%d\n" 
-                                                                         "k=%d stm=%u idx=%d dtm_peek=%d dtm_cache=%d\n", 
-                                                                         success, success2, k, stm, idx, dtm_temp, *dtm); 
-                                                         fatal_error(); 
-                                                 } 
-                                         } 
-                                         #endif 
-   
-                         } else { 
-                                 if (probe_hard_flag && Uncompressed) 
-                                         success = egtb_filepeek (k, stm, idx, dtm); 
-                                 else 
-                                         success = FALSE; 
-                         } 
-   
-                         mythread_mutex_unlock (&Egtb_lock); 
-                         /*------------------------------*\ 
-                         |               UNLOCK 
-                         */ 
-   
-   
-                         if (success) { 
-                                 return TRUE; 
-                         } else { 
-                                 if (probe_hard_flag) /* after probing hard and failing, no chance to succeed later */ 
-                                         egkey[k].status = STATUS_REJECT; 
-                                 *dtm = iUNKNOWN; 
-                                 return FALSE; 
-                         } 
-   
-                 } else { 
-                         *dtm = iFORBID; 
-                         return  TRUE; 
-                 } 
-   
-         } else if (egkey[k].status == STATUS_REJECT) { 
-   
-                 FOLLOW_label("STATUS_REJECT") 
-   
-                 *dtm = iFORBID; 
-                 return  FALSE; 
-         } else { 
-   
-                 FOLLOW_label("STATUS_WRONG!") 
-   
-                 *dtm = iFORBID; 
-                 return  FALSE; 
-         } 
-   
- } 
-   
- static void 
- removepiece (SQUARE *ys, SQ_CONTENT *yp, int j) 
- { 
-     int k; 
-         for (k = j; ys[k] != NOSQUARE; k++) { 
-                 ys[k] = ys[k+1]; 
-                 yp[k] = yp[k+1]; 
-         } 
- } 
-   
- /* 
- | 
- |       mySHARED by probe and build 
- | 
- \*----------------------------------------------------*/ 
-   
- mySHARED /*@NULL@*/ FILE * 
- fd_openit (tbkey_t key) 
- { 
-         int                     i; 
-         tbkey_t                 closingkey; 
-         FILE *                  finp = NULL; 
-         char                    buf[4096]; 
-         char *                  filename = buf; 
-         int                     start; 
-         int                             end; 
-         int                             pth; 
-         const char *    extension; 
-   
-         assert (0 <=-  key  &&-  key  <-  MAX_EGKEYS );
 
-         assert (0 <=-  fd. n &&-  fd. n <=-  GTB_MAXOPEN );
 
-   
-         /* test if I reach limit of files open */ 
-         if (fd.n == GTB_MAXOPEN) { 
-   
-                 /* fclose the last accessed, first in the list */ 
-                 closingkey = fd.key[0]; 
-                 finp = egkey [closingkey].fd; 
-                 egkey[closingkey].fd = NULL; 
-                 finp = NULL; 
-   
-                 for (i = 1; i < fd.n; i++) { 
-                         fd.key[i-1] = fd.key[i]; 
-                 } 
-                 fd.key[--fd.n] = -1; 
-         } 
-   
-   
-         /* set proper extensions to the File */ 
-         if (Uncompressed) { 
-                 assert (- decoding_scheme () == 0 &&-  GTB_scheme  == 0);
 
-                 extension = ".gtb"; 
-         } else { 
-                 extension = Extension[decoding_scheme()]; 
-         } 
-   
-         /* Scan folders to find the File*/ 
-         finp = NULL; 
-   
-         start = egkey[key].pathn; 
-         end   = Gtbpath_end_index; 
-   
- /*@@ 
- printf ("start: %d\n",start); 
- printf ("===================Gtbpath[0]=%s\n",Gtbpath[0]); 
- */ 
-         for (pth = start; NULL == finp && pth < end && Gtbpath[pth] != NULL; pth++) { 
-                 const char *path = Gtbpath[pth]; 
- /*@@ 
- printf ("path: %s\n",path); 
- */ 
-                 if (pl == 0) { 
-                                 sprintf (- buf , "%s%s%s",-  path ,-  egkey [- key ]- . str,-  extension );
 
-                 } else { 
-                         if (isfoldersep( path[pl-1] )) { 
-                                 sprintf (- buf , "%s%s%s",-  path ,-  egkey [- key ]- . str,-  extension );
 
-                         } else { 
-                                 sprintf (- buf , "%s%s%s%s",-  path ,-  FOLDERSEP ,-  egkey [- key ]- . str,-  extension );
 
-                         } 
-                 } 
- /*printf ("try to open %s   --> ",filename);*/ 
-                 /* Finally found the file? */ 
-                 finp  = fopen (- filename , "rb");
- /*printf ("%d\n",finp != NULL);*/ 
-         } 
-   
-         /* File was found and opened */ 
-         if (NULL != finp) { 
-                 fd.key [fd.n++] = key; 
-                 egkey[key].fd = finp; 
-                 egkey[key].pathn = pth; /* remember succesful path */ 
-                 eg_was_open[key] = 1; 
-                 return finp; 
-         } 
-   
-         start = 0; 
-         end   = egkey[key].pathn; 
-         for (pth = start; NULL == finp && pth < end && Gtbpath[pth] != NULL; pth++) { 
-                 const char *path = Gtbpath[pth]; 
-   
-                 if (pl == 0) { 
-                                 sprintf (- buf , "%s%s%s",-  path ,-  egkey [- key ]- . str,-  extension );
 
-                 } else { 
-                         if (isfoldersep( path[pl-1] )) { 
-                                 sprintf (- buf , "%s%s%s",-  path ,-  egkey [- key ]- . str,-  extension );
 
-                         } else { 
-                                 sprintf (- buf , "%s%s%s%s",-  path ,-  FOLDERSEP ,-  egkey [- key ]- . str,-  extension );
 
-                         } 
-                 } 
- /*printf ("try to open %s   --> ",filename);*/ 
-                 /* Finally found the file? */ 
-                 finp  = fopen (- filename , "rb");
- /*printf ("%d\n",finp != NULL);*/ 
-         } 
-   
-   
-         /* File was found and opened */ 
-         if (NULL != finp) { 
-                 fd.key [fd.n++] = key; 
-                 egkey[key].fd = finp; 
-                 egkey[key].pathn = pth; /* remember succesful path */ 
-                 eg_was_open[key] = 1; 
-         } 
-   
-         return finp; 
- } 
-   
- #ifdef _MSC_VER 
- /* to silence warning for sprintf usage */ 
- #pragma warning(default:4996) 
- #endif 
-   
- mySHARED void 
- sortlists (SQUARE *ws, SQ_CONTENT *wp) 
- { 
-         int i, j; 
-         SQUARE ts; 
-         SQ_CONTENT tp; 
-         /* input is sorted */ 
-         for (i = 0; wp[i] != NOPIECE; i++) { 
-                 for (j = (i+1); wp[j] != NOPIECE; j++) { 
-                         if (wp[j] > wp[i]) { 
-                                 tp = wp[i]; wp[i] = wp[j]; wp[j] = tp; 
-                                 ts = ws[i]; ws[i] = ws[j]; ws[j] = ts; 
-                         } 
-                 } 
-         } 
- } 
-   
- mySHARED void 
- list_sq_copy (const SQUARE *a, SQUARE *b) 
- { 
-         while (NOSQUARE != (*b++ = *a++)) 
-                 ; 
- } 
-   
- mySHARED void 
- list_pc_copy (const SQ_CONTENT *a, SQ_CONTENT *b) 
- { 
-         while (NOPIECE != (*b++ = *a++)) 
-                 ; 
- } 
-   
- mySHARED dtm_t 
- inv_dtm (dtm_t x) 
- { 
-         unsigned mat; 
-         assert ( (- x  &-  iUNKNBIT ) == 0);
 
-   
-         if (x == iDRAW || x == iFORBID) 
-                 return x; 
-   
-         mat = (unsigned)x & 3u; 
-         if (mat == iWMATE) 
-                 mat = iBMATE; 
-         else 
-                 mat = iWMATE; 
-   
-         x = (dtm_t) (((unsigned)x & ~3u) | mat); 
-   
-         return x; 
- } 
-   
- static const char pctoch[] = {'-','p','n','b','r','q','k'}; 
-   
- mySHARED bool_t 
- egtb_get_id (SQ_CONTENT *w, SQ_CONTENT *b, tbkey_t *id) 
- { 
-   
-         char pcstr[2*MAX_LISTSIZE]; 
-         SQ_CONTENT *s; 
-         char *t; 
-         bool_t found; 
-         tbkey_t i; 
-         static tbkey_t cache_i = 0; 
-         size_t h1, h2; 
-   
-         assert (- PAWN  == 1 &&-  KNIGHT  == 2 &&-  BISHOP  == 3 &&-  ROOK  == 4 &&-  QUEEN  == 5 &&-  KING  == 6);
 
-   
-         t = pcstr; 
-   
-         s = w; 
-         while (NOPIECE != *s) 
-                 *t++ = pctoch[*s++]; 
-         s = b; 
-         while (NOPIECE != *s) 
-                 *t++ = pctoch[*s++]; 
-   
-         *t = '\0'; 
-   
-         found  = (0 == strcmp(- pcstr ,-  egkey [- cache_i ]- . str));
-         if (found) { 
-                 *id = cache_i; 
-                 return found; 
-         } 
-   
-         h1 = str_hash_func_1 (pcstr) & (EGKEY_HASH_SIZE - 1); 
-         h2 = str_hash_func_2 (pcstr); 
-         while (1) { 
-                 i = egkey_hash[h1]; 
-                 if (i < 0) 
-                         break; 
-                 found  = (0 == strcmp(- pcstr ,-  egkey [- i ]- . str));
-                 if (found) 
-                         break; 
-                 h1 = (h1 + h2) & (EGKEY_HASH_SIZE - 1); 
-         } 
-         if (found) { 
-                 cache_i = *id = i; 
-         } 
-   
-         return found; 
- } 
-   
- mySHARED void 
- list_sq_flipNS (SQUARE *s) 
- { 
-         while (*s != NOSQUARE) { 
-                 *s ^= 070; 
-                 s++; 
-         } 
- } 
-   
- mySHARED void 
- unpackdist (dtm_t d, unsigned int *res, unsigned int *ply) 
- { 
-         *ply = (unsigned int)d >> PLYSHIFT; 
-         *res = d & INFOMASK; 
- } 
-   
- mySHARED dtm_t 
- packdist (unsigned int inf, unsigned int ply) 
- { 
-         return (dtm_t) (inf | ply << PLYSHIFT); 
- } 
-   
- mySHARED dtm_t 
- adjust_up (dtm_t dist) 
- { 
-         #if 0 
-         static const dtm_t adding[] = { 
-                 0, 1<<PLYSHIFT, 1<<PLYSHIFT, 0, 
-                 0, 1<<PLYSHIFT, 1<<PLYSHIFT, 0 
-         }; 
-         dist += adding [dist&INFOMASK]; 
-         return dist; 
-         #else 
-         unsigned udist = (unsigned) dist; 
-         switch (udist & INFOMASK) { 
-                 case iWMATE: 
-                 case iWMATEt: 
-                 case iBMATE: 
-                 case iBMATEt: 
-                         udist += (1u << PLYSHIFT); 
-                         break; 
-                 default: 
-                         break; 
-         } 
-         return (dtm_t) udist; 
-         #endif 
- } 
-   
-   
- mySHARED dtm_t 
- bestx (unsigned stm, dtm_t a, dtm_t b) 
- { 
-         unsigned int key; 
-         static const unsigned int 
-         comparison [4] [4] = { 
-                                 /*draw, wmate, bmate, forbid*/ 
-         /* draw  */ {0, 3, 0, 0}, 
-         /* wmate */ {0, 1, 0, 0}, 
-         /* bmate */ {3, 3, 2, 0}, 
-         /* forbid*/ {3, 3, 3, 0} 
-   
-         /* 0 = selectfirst   */ 
-         /* 1 = selectlowest  */ 
-         /* 2 = selecthighest */ 
-         /* 3 = selectsecond  */ 
-         }; 
-   
-         static const unsigned int xorkey [2] = {0, 3}; 
-         dtm_t retu[4]; 
-         dtm_t ret = iFORBID; 
-   
-         assert (- stm  ==-  WH  ||-  stm  ==-  BL );
 
-         assert ((- a  &-  iUNKNBIT ) == 0 && (- b  &-  iUNKNBIT ) == 0 );
 
-   
-         if (a == iFORBID) 
-                 return b; 
-         if (b == iFORBID) 
-                 return a; 
-   
-         retu[0] = a; /* first parameter */ 
-         retu[1] = a; /* the lowest by default */ 
-         retu[2] = b; /* highest by default */ 
-         retu[3] = b; /* second parameter */ 
-         if (b < a) { 
-                 retu[1] = b; 
-                 retu[2] = a; 
-         } 
-   
-         key = comparison [a&3] [b&3] ^ xorkey[stm]; 
-         ret = retu [key]; 
-   
-         return ret; 
- } 
-   
-   
- /*--------------------------------------------------------------------------*\ 
-  |                                                              PACKING ZONE 
-  *--------------------------------------------------------------------------*/ 
-   
- inline 
- mySHARED dtm_t 
- dtm_unpack (unsigned stm, unsigned char packed) 
- { 
-         unsigned int info, plies, prefx, store, moves; 
-         dtm_t ret; 
-         unsigned int p = packed; 
-   
-         if (iDRAW == p || iFORBID == p) { 
-                 return (dtm_t) p; 
-         } 
-   
-         info  = (unsigned int) p & 3; 
-         store = (unsigned int) p >> 2; 
-   
-         if (WH == stm) { 
-                 switch (info) { 
-                         case iWMATE: 
-                                                 moves = store + 1; 
-                                                 plies = moves * 2 - 1; 
-                                                 prefx = info; 
-                                                 break; 
-   
-                         case iBMATE: 
-                                                 moves = store; 
-                                                 plies = moves * 2; 
-                                                 prefx = info; 
-                                                 break; 
-   
-                         case iDRAW: 
-                                                 moves = store + 1 + 63; 
-                                                 plies = moves * 2 - 1; 
-                                                 prefx = iWMATE; 
-                                                 break; 
-   
-                         case iFORBID: 
-   
-                                                 moves = store + 63; 
-                                                 plies = moves * 2; 
-                                                 prefx = iBMATE; 
-                                                 break; 
-                         default: 
-             plies = 0; 
-             prefx = 0; 
-                                                 break; 
-   
-                 } 
-                 ret = (dtm_t) (prefx | (plies << 3)); 
-         } else { 
-                 switch (info) { 
-                         case iBMATE: 
-                                                 moves = store + 1; 
-                                                 plies = moves * 2 - 1; 
-                                                 prefx = info; 
-                                                 break; 
-   
-                         case iWMATE: 
-                                                 moves = store; 
-                                                 plies = moves * 2; 
-                                                 prefx = info; 
-                                                 break; 
-   
-                         case iDRAW: 
-   
-                                                 if (store == 63) { 
-                                                 /*      exception: no position in the 5-man 
-                                                         TBs needs to store 63 for iBMATE 
-                                                         it is then used to indicate iWMATE 
-                                                         when just overflows */ 
-                                                         store++; 
-   
-                                                         moves = store + 63; 
-                                                         plies = moves * 2; 
-                                                         prefx = iWMATE; 
-   
-                                                         break; 
-                                                 } 
-   
-                                                 moves = store + 1 + 63; 
-                                                 plies = moves * 2 - 1; 
-                                                 prefx = iBMATE; 
-                                                 break; 
-   
-                         case iFORBID: 
-   
-                                                 moves = store + 63; 
-                                                 plies = moves * 2; 
-                                                 prefx = iWMATE; 
-                                                 break; 
-                         default: 
-             plies = 0; 
-             prefx = 0; 
-                                                 break; 
-   
-                 } 
-                 ret = (dtm_t) (prefx | (plies << 3)); 
-         } 
-         return ret; 
- } 
-   
-   
- /* 
- static bool_t fwrite_entry_packed (FILE *dest, unsigned side, dtm_t x); 
- */ 
-   
-   
- mySHARED bool_t 
- fread_entry_packed (FILE *finp, unsigned side, dtm_t *px) 
- { 
-         unsigned char p[SLOTSIZE]; 
-         bool_t ok  = (- SLOTSIZE  == fread (- p , sizeof(unsigned char),-  SLOTSIZE ,-  finp ));
-         if (ok) { 
-                 *px = dtm_unpack (side, p[0]); 
-         } 
-         return ok; 
- } 
-   
-   
- mySHARED bool_t 
- fpark_entry_packed  (FILE *finp, unsigned side, index_t max, index_t idx) 
- { 
-         bool_t ok; 
-         index_t i; 
-         long int fseek_i; 
-         index_t sz = (index_t) sizeof(unsigned char); 
-   
-         assert (- side  ==-  WH  ||-  side  ==-  BL );
 
-         i = ((index_t)side * max + idx) * sz; 
-         fseek_i = (long int) i; 
-         ok  = (0 == fseek (- finp ,-  fseek_i ,-  SEEK_SET ));
-         return ok; 
- } 
-   
- /*----------------------------------------------------*\ 
- | 
- |       shared by probe and build 
- | 
- \*/ 
-   
- static size_t 
- hash_func_1 (tbkey_t key, unsigned side, index_t offset) 
- { 
-         size_t h = offset | (key << 1) | side; 
-         h = ((h >> 16) ^ h) * 0x45d9f3b; 
-         h = ((h >> 16) ^ h) * 0x45d9f3b; 
-         h = ((h >> 16) ^ h); 
-         return h; 
- } 
-   
- static size_t 
- hash_func_2 (tbkey_t key, unsigned side, index_t offset) 
- { 
-         size_t h = offset | (key << 1) | side; 
-         h = ((h >> 16) ^ h) * 0x3335b369; 
-         h = ((h >> 16) ^ h) * 0x3335b369; 
-         h = ((h >> 16) ^ h); 
-         return h * 2 + 1; 
- } 
-   
- /*---------------------------------------------------------------------*\ 
- |                       WDL CACHE Implementation  ZONE 
- \*---------------------------------------------------------------------*/ 
-   
- #define WDL_entries_per_unit 4 
- #define WDL_entry_mask     3 
- static size_t           WDL_units_per_block = 0; 
-   
- static bool_t           WDL_CACHE_INITIALIZED = FALSE; 
-   
- typedef unsigned char unit_t; /* block unit */ 
-   
- typedef struct wdl_block        wdl_block_t; 
-   
- struct wdl_block { 
-         tbkey_t                 key; 
-         unsigned                side; 
-         index_t                 offset; 
-         unit_t                  *p_arr; 
-         wdl_block_t             *prev; 
-         wdl_block_t             *next; 
- }; 
-   
- struct WDL_CACHE { 
-         /* defined at init */ 
-         bool_t                  cached; 
-         size_t                  max_blocks; 
-         size_t                  entries_per_block; 
-         unit_t           *      buffer; 
-   
-         /* flushables */ 
-         wdl_block_t     *       top; 
-         wdl_block_t *   bot; 
-         size_t                  n; 
-         wdl_block_t *   blocks; /* was entry */ 
-   
-         /* fast lookup in LRU list */ 
-         wdl_block_t**   hash_table; 
-         size_t                  ht_size; 
-         size_t                  ht_used; 
-   
-         /* counters */ 
-         uint64_t                hard; 
-         uint64_t                soft; 
-         uint64_t                hardmisses; 
-         uint64_t                hits; 
-         uint64_t                softmisses; 
-         uint64_t                comparisons; 
- }; 
-   
- struct WDL_CACHE        wdl_cache = {FALSE,0,0,NULL, 
-                                                                  NULL,NULL,0,NULL, 
-                                                                  0,0,0,0,0,0}; 
-   
-   
- /*---------------------------------------------------------------------*\ 
- |                       DTM CACHE Implementation  ZONE 
- \*---------------------------------------------------------------------*/ 
-   
- struct dtm_block; 
-   
- typedef struct dtm_block dtm_block_t; 
-   
- struct dtm_block { 
-         tbkey_t                 key; 
-         unsigned                side; 
-         index_t                 offset; 
-         dtm_t                   *p_arr; 
-         dtm_block_t             *prev; 
-         dtm_block_t             *next; 
- }; 
-   
- struct cache_table { 
-         /* defined at init */ 
-         bool_t                  cached; 
-         size_t                  max_blocks; 
-         size_t                  entries_per_block; 
-         dtm_t *                 buffer; 
-   
-         /* flushables */ 
-         dtm_block_t     *       top; 
-         dtm_block_t *   bot; 
-         size_t                  n; 
-         dtm_block_t *   entry; 
-   
-         /* fast lookup in LRU list */ 
-         dtm_block_t**   hash_table; 
-         size_t                  ht_size; 
-         size_t                  ht_used; 
-   
-         /* counters */ 
-         uint64_t                hard; 
-         uint64_t                soft; 
-         uint64_t                hardmisses; 
-         uint64_t                hits; 
-         uint64_t                softmisses; 
-         unsigned long   comparisons; 
- }; 
-   
- struct cache_table      dtm_cache = {FALSE,0,0,NULL, 
-                                                                 NULL,NULL,0,NULL, 
-                                                                 0,0,0,0,0,0}; 
-   
- struct general_counters { 
-         /* counters */ 
-         uint64_t                hits; 
-         uint64_t                miss; 
- }; 
-   
- static struct general_counters Drive = {0,0}; 
-   
-   
- static void             split_index (size_t entries_per_block, index_t i, index_t *o, index_t *r); 
- static dtm_block_t *point_block_to_replace (void); 
- static bool_t           preload_cache (tbkey_t key, unsigned side, index_t idx); 
- static void                     movetotop (dtm_block_t *t); 
-   
- /*--cache prototypes--------------------------------------------------------*/ 
-   
- /*- WDL --------------------------------------------------------------------*/ 
- #ifdef WDL_PROBE 
- static unsigned int             wdl_extract (unit_t *uarr, index_t x); 
- static wdl_block_t *    wdl_point_block_to_replace (void); 
- static void                             wdl_movetotop (wdl_block_t *t); 
-   
- #if 0 
- static bool_t                   wdl_cache_init (size_t cache_mem); 
- static void                             wdl_cache_flush (void); 
- static bool_t                   get_WDL (tbkey_t key, unsigned side, index_t idx, unsigned int *info_out, bool_t probe_hard_flag); 
- #endif 
-   
- static bool_t                   wdl_cache_is_on (void); 
- static void                             wdl_cache_reset_counters (void); 
- static void                             wdl_cache_done (void); 
-   
- static wdl_block_t *    wdl_point_block_to_replace (void); 
- static bool_t                   get_WDL_from_cache (tbkey_t key, unsigned side, index_t idx, unsigned int *out); 
- static void                             wdl_movetotop (wdl_block_t *t); 
- static bool_t                   wdl_preload_cache (tbkey_t key, unsigned side, index_t idx); 
- #endif 
- /*--------------------------------------------------------------------------*/ 
- /*- DTM --------------------------------------------------------------------*/ 
- static bool_t                   dtm_cache_is_on (void); 
- static void                             dtm_cache_reset_counters (void); 
- static void                             dtm_cache_done (void); 
-   
- static size_t                   dtm_cache_init (size_t cache_mem); 
- static void                             dtm_cache_flush (void); 
- /*--------------------------------------------------------------------------*/ 
-   
- static bool_t 
- dtm_cache_is_on (void) 
- { 
-         return dtm_cache.cached; 
- } 
-   
- static void 
- dtm_cache_reset_counters (void) 
- { 
-         dtm_cache.hard = 0; 
-         dtm_cache.soft = 0; 
-         dtm_cache.hardmisses = 0; 
-         dtm_cache.hits = 0; 
-         dtm_cache.softmisses = 0; 
-         dtm_cache.comparisons = 0; 
-         return; 
- } 
-   
-   
- static size_t 
- dtm_cache_init (size_t cache_mem) 
- { 
-         unsigned int    i; 
-         dtm_block_t     *p; 
-         size_t                  entries_per_block; 
-         size_t                  max_blocks; 
-         size_t                  block_mem; 
-   
-         if (DTM_CACHE_INITIALIZED) 
-                 dtm_cache_done(); 
-   
-         entries_per_block       = 16 * 1024;  /* fixed, needed for the compression schemes */ 
-   
-         block_mem                       = entries_per_block * sizeof(dtm_t); 
-   
-         max_blocks                      = cache_mem / block_mem; 
-         if (!Uncompressed && 1 > max_blocks) 
-                 max_blocks = 1; 
-         cache_mem                       = max_blocks * block_mem; 
-   
-   
-         dtm_cache_reset_counters (); 
-   
-         dtm_cache.entries_per_block     = entries_per_block; 
-         dtm_cache.max_blocks            = max_blocks; 
-         dtm_cache.cached                        = TRUE; 
-         dtm_cache.top                           = NULL; 
-         dtm_cache.bot                           = NULL; 
-         dtm_cache.n                             = 0; 
-   
-         if (0 ==-  cache_mem  ||-  NULL  == (- dtm_cache. buffer = (- dtm_t  *)  malloc (- cache_mem ))) {
 
-                 dtm_cache.cached = FALSE; 
-                 dtm_cache.buffer = NULL; 
-                 dtm_cache.entry = NULL; 
-                 return 0; 
-         } 
-   
-         if (0 ==-  max_blocks ||-  NULL  == (- dtm_cache. entry  = (- dtm_block_t  *) malloc (- max_blocks  * sizeof(- dtm_block_t )))) {
 
-                 dtm_cache.cached = FALSE; 
-                 dtm_cache.entry = NULL; 
-                 dtm_cache.buffer = NULL; 
-                 return 0; 
-         } 
-   
-         for (i = 0; i < max_blocks; i++) { 
-                 p = &dtm_cache.entry[i]; 
-                 p->key          = -1; 
-                 p->side         = gtbNOSIDE; 
-                 p->offset       = gtbNOINDEX; 
-                 p->p_arr        = dtm_cache.buffer + i * entries_per_block; 
-                 p->prev         = NULL; 
-                 p->next         = NULL; 
-         } 
-   
-         dtm_cache.ht_size = 1; 
-         while (dtm_cache.ht_size < max_blocks * 4) 
-                 dtm_cache.ht_size *= 2; 
-         dtm_cache.ht_used = 0; 
-         dtm_cache. hash_table = (- dtm_block_t **) malloc (- dtm_cache. ht_size * sizeof(- dtm_block_t *));;
-         if (dtm_cache.hash_table == NULL) { 
-                 dtm_cache.cached = FALSE; 
-                 dtm_cache.entry = NULL; 
-                 dtm_cache.buffer = NULL; 
-                 return 0; 
-         } 
-   
-         for (i = 0; i < dtm_cache.ht_size; i++) { 
-                 dtm_cache.hash_table[i] = NULL; 
-         } 
-   
-         DTM_CACHE_INITIALIZED = TRUE; 
-   
-         return cache_mem; 
- } 
-   
-   
- static void 
- dtm_cache_done (void) 
- { 
-         assert(- DTM_CACHE_INITIALIZED );
 
-   
-         dtm_cache.cached = FALSE; 
-         dtm_cache.hard = 0; 
-         dtm_cache.soft = 0; 
-         dtm_cache.hardmisses = 0; 
-         dtm_cache.hits = 0; 
-         dtm_cache.softmisses = 0; 
-         dtm_cache.comparisons = 0; 
-         dtm_cache.max_blocks = 0; 
-         dtm_cache.entries_per_block = 0; 
-   
-         dtm_cache.top = NULL; 
-         dtm_cache.bot = NULL; 
-         dtm_cache.n = 0; 
-   
-         if (dtm_cache.buffer != NULL) 
-         dtm_cache.buffer = NULL; 
-   
-         if (dtm_cache.entry != NULL) 
-         dtm_cache.entry = NULL; 
-   
-         if (dtm_cache.hash_table != NULL) 
-                 free (- dtm_cache. hash_table);
 
-         dtm_cache.hash_table = NULL; 
-   
-         DTM_CACHE_INITIALIZED = FALSE; 
-   
-         return; 
- } 
-   
- static void 
- dtm_cache_flush (void) 
- { 
-         unsigned int    i; 
-         dtm_block_t     *p; 
-         size_t entries_per_block = dtm_cache.entries_per_block; 
-         size_t max_blocks = dtm_cache.max_blocks; 
-   
-         dtm_cache.top                           = NULL; 
-         dtm_cache.bot                           = NULL; 
-         dtm_cache.n                             = 0; 
-   
-         for (i = 0; i < max_blocks; i++) { 
-                 p = &dtm_cache.entry[i]; 
-                 p->key          = -1; 
-                 p->side         = gtbNOSIDE; 
-                 p->offset       = gtbNOINDEX; 
-                 p->p_arr        = dtm_cache.buffer + i * entries_per_block; 
-                 p->prev         = NULL; 
-                 p->next         = NULL; 
-         } 
-         dtm_cache_reset_counters (); 
-         return; 
- } 
-   
-   
- /*---- end tbcache zone ----------------------------------------------------------------------*/ 
-   
- extern bool_t 
- tbcache_is_on (void) 
- { 
-         return dtm_cache_is_on() || wdl_cache_is_on(); 
- } 
-   
-   
- /* STATISTICS OUTPUT */ 
-   
- extern void 
- tbstats_get (struct TB_STATS *x) 
- { 
-         long unsigned mask = 0xfffffffflu; 
-         uint64_t memory_hits, total_hits; 
-   
-   
-         /* 
-         |       WDL CACHE 
-         \*---------------------------------------------------*/ 
-   
-         x->wdl_easy_hits[0] = (long unsigned)(wdl_cache.hits & mask); 
-         x->wdl_easy_hits[1] = (long unsigned)(wdl_cache.hits >> 32); 
-   
-         x->wdl_hard_prob[0] = (long unsigned)(wdl_cache.hard & mask); 
-         x->wdl_hard_prob[1] = (long unsigned)(wdl_cache.hard >> 32); 
-   
-         x->wdl_soft_prob[0] = (long unsigned)(wdl_cache.soft & mask); 
-         x->wdl_soft_prob[1] = (long unsigned)(wdl_cache.soft >> 32); 
-   
-         x->wdl_cachesize    = WDL_cache_size; 
-   
-         /* occupancy */ 
-         x->wdl_occupancy = wdl_cache.max_blocks==0? 0:(double)100.0*(double)wdl_cache.n/(double)wdl_cache.max_blocks; 
-   
-         /* 
-         |       DTM CACHE 
-         \*---------------------------------------------------*/ 
-   
-         x->dtm_easy_hits[0] = (long unsigned)(dtm_cache.hits & mask); 
-         x->dtm_easy_hits[1] = (long unsigned)(dtm_cache.hits >> 32); 
-   
-         x->dtm_hard_prob[0] = (long unsigned)(dtm_cache.hard & mask); 
-         x->dtm_hard_prob[1] = (long unsigned)(dtm_cache.hard >> 32); 
-   
-         x->dtm_soft_prob[0] = (long unsigned)(dtm_cache.soft & mask); 
-         x->dtm_soft_prob[1] = (long unsigned)(dtm_cache.soft >> 32); 
-   
-         x->dtm_cachesize    = DTM_cache_size; 
-   
-         /* occupancy */ 
-         x->dtm_occupancy = dtm_cache.max_blocks==0? 0:(double)100.0*(double)dtm_cache.n/(double)dtm_cache.max_blocks; 
-   
-         /* 
-         |       GENERAL 
-         \*---------------------------------------------------*/ 
-   
-         /* memory */ 
-         memory_hits = wdl_cache.hits + dtm_cache.hits; 
-         x->memory_hits[0] = (long unsigned)(memory_hits & mask); 
-         x->memory_hits[1] = (long unsigned)(memory_hits >> 32); 
-   
-         /* hard drive */ 
-         x->drive_hits[0] = (long unsigned)(Drive.hits & mask); 
-         x->drive_hits[1] = (long unsigned)(Drive.hits >> 32); 
-   
-         x->drive_miss[0] = (long unsigned)(Drive.miss & mask); 
-         x->drive_miss[1] = (long unsigned)(Drive.miss >> 32); 
-   
-         x->bytes_read[0] = (long unsigned)(Bytes_read & mask); 
-         x->bytes_read[1] = (long unsigned)(Bytes_read >> 32); 
-   
-         x->files_opened = eg_was_open_count(); 
-   
-         /* total */ 
-         total_hits = memory_hits + Drive.hits; 
-         x->total_hits[0] = (long unsigned)(total_hits & mask); 
-         x->total_hits[1] = (long unsigned)(total_hits >> 32); 
-   
-         /* efficiency */ 
-         { uint64_t denominator = memory_hits + Drive.hits + Drive.miss; 
-         x->memory_efficiency = 0==denominator? 0: 100.0 * (double)(memory_hits) / (double)(denominator); 
-         } 
- } 
-   
-   
- extern bool_t 
- tbcache_init (size_t cache_mem, int wdl_fraction) 
- { 
-         assert (- wdl_fraction  <=-  WDL_FRACTION_MAX  &&-  wdl_fraction  >= 0);
 
-   
-         /* defensive against input */ 
-         if (wdl_fraction > WDL_FRACTION_MAX) wdl_fraction = WDL_FRACTION_MAX; 
-         if (wdl_fraction <                0) wdl_fraction = 0; 
-         WDL_FRACTION = wdl_fraction; 
-   
-         DTM_cache_size = (cache_mem/(size_t)WDL_FRACTION_MAX)*(size_t)(WDL_FRACTION_MAX-WDL_FRACTION); 
-         WDL_cache_size = (cache_mem/(size_t)WDL_FRACTION_MAX)*(size_t)                                  WDL_FRACTION ; 
-   
-         #ifdef WDL_PROBE 
-         /* returns the actual memory allocated */ 
-         DTM_cache_size = dtm_cache_init (DTM_cache_size); 
-         WDL_cache_size = wdl_cache_init (WDL_cache_size); 
-         #else 
-         /* returns the actual memory allocated */ 
-         DTM_cache_size = dtm_cache_init (DTM_cache_size); 
-         #endif 
-         tbstats_reset (); 
-         return TRUE; 
- } 
-   
- extern bool_t 
- tbcache_restart (size_t cache_mem, int wdl_fraction) 
- { 
-         return tbcache_init (cache_mem, wdl_fraction); 
- } 
-   
- extern void 
- tbcache_done (void) 
- { 
-         dtm_cache_done(); 
-         #ifdef WDL_PROBE 
-         wdl_cache_done(); 
-         #endif 
-         tbstats_reset (); 
-         return; 
- } 
-   
- extern void 
- tbcache_flush (void) 
- { 
-         dtm_cache_flush(); 
-         #ifdef WDL_PROBE 
-         wdl_cache_flush(); 
-         #endif 
-         tbstats_reset (); 
-         return; 
- } 
-   
- extern void 
- tbstats_reset (void) 
- { 
-         dtm_cache_reset_counters (); 
-         #ifdef WDL_PROBE 
-         wdl_cache_reset_counters (); 
-         #endif 
-         eg_was_open_reset(); 
-         Drive.hits = 0; 
-         Drive.miss = 0; 
-         return; 
- } 
-   
- static void dtm_hash_insert (dtm_block_t * e); 
-   
- static void 
- dtm_hash_rebuild (void) 
- { 
-         dtm_block_t     * p; 
-         size_t i; 
-   
-         for (i = 0; i < dtm_cache.ht_size; i++) 
-                 dtm_cache.hash_table[i] = NULL; 
-         dtm_cache.ht_used = 0; 
-   
-         for (p = dtm_cache.top; p != NULL; p = p->prev) 
-                 dtm_hash_insert (p); 
- } 
-   
- static void 
- dtm_hash_insert (dtm_block_t * e) 
- { 
-         size_t h1, h2; 
-   
-         if (dtm_cache.ht_used > dtm_cache.ht_size * 3 / 4) 
-                 dtm_hash_rebuild(); 
-   
-     h1 = hash_func_1 (e->key, e->side, e->offset) & (dtm_cache.ht_size - 1); 
-     h2 = hash_func_2 (e->key, e->side, e->offset); 
-     while (dtm_cache.hash_table[h1]) 
-         h1 = (h1 + h2) & (dtm_cache.ht_size - 1); 
-     dtm_cache.hash_table[h1] = e; 
-     dtm_cache.ht_used++; 
- } 
-   
- static dtm_block_t      * 
- dtm_cache_pointblock (tbkey_t key, unsigned side, index_t idx) 
- { 
-         index_t                 offset; 
-         index_t                 remainder; 
-         dtm_block_t     *       p; 
-         dtm_block_t     *       ret; 
-         size_t                  h1, h2; 
-   
-         if (!dtm_cache_is_on()) 
-                 return NULL; 
-   
-         split_index (dtm_cache.entries_per_block, idx, &offset, &remainder); 
-   
-         ret   = NULL; 
-   
-         h1 = hash_func_1 (key, side, offset) & (dtm_cache.ht_size - 1); 
-         h2 = hash_func_2 (key, side, offset); 
-         while (1) { 
-                 p = dtm_cache.hash_table[h1]; 
-                 if (!p) 
-                         break; 
-   
-                 dtm_cache.comparisons++; 
-   
-                 if (key == p->key && side == p->side && offset  == p->offset) { 
-                         ret = p; 
-                         break; 
-                 } 
-   
-                 h1 = (h1 + h2) & (dtm_cache.ht_size - 1); 
-         } 
-   
-         FOLLOW_LU("point_to_dtm_block ok?",(ret!=NULL)) 
-   
-         return ret; 
- } 
-   
- /****************************************************************************\ 
- | 
- | 
- |                       WRAPPERS for ENCODING/DECODING FUNCTIONS ZONE 
- | 
- | 
- \****************************************************************************/ 
-   
- #include "gtb-dec.h" 
-   
- /* 
- | 
- |       PRE LOAD CACHE AND DEPENDENT FUNCTIONS 
- | 
- \*--------------------------------------------------------------------------*/ 
-   
- struct ZIPINFO { 
-         index_t         extraoffset; 
-         index_t         totalblocks; 
-         index_t *       blockindex; 
- }; 
-   
- struct ZIPINFO Zipinfo[MAX_EGKEYS]; 
-   
- static index_t  egtb_block_getnumber            (tbkey_t key, unsigned side, index_t idx); 
- static index_t  egtb_block_getsize                      (tbkey_t key, index_t idx); 
- static index_t  egtb_block_getsize_zipped       (tbkey_t key, index_t block ); 
- static  bool_t  egtb_block_park                         (tbkey_t key, index_t block); 
- static  bool_t  egtb_block_read                         (tbkey_t key, index_t len, unsigned char *buffer); 
- static  bool_t  egtb_block_decode                       (tbkey_t key, index_t z, unsigned char *bz, index_t n, unsigned char *bp); 
- static  bool_t  egtb_block_unpack                       (unsigned side, index_t n, const unsigned char *bp, dtm_t *out); 
- static  bool_t  egtb_file_beready                       (tbkey_t key); 
- static  bool_t  egtb_loadindexes                        (tbkey_t key); 
- static index_t  egtb_block_uncompressed_to_index (tbkey_t key, index_t b); 
- static  bool_t  fread32                                         (FILE *f, unsigned long int *y); 
-   
-   
- static unsigned int 
- zipinfo_init (void) 
- { 
-         int i, start, end; 
-         unsigned ret; 
-         bool_t ok, complet[8] = {0,0,0,0,0,0,0,0}; 
-         bool_t pa, partial[8] = {0,0,0,0,0,0,0,0}; 
-         unsigned int z; 
-         int x, j; 
-   
-         /* reset all values */ 
-         for (i = 0; i < MAX_EGKEYS; i++) { 
-                 Zipinfo[i].blockindex = NULL; 
-                 Zipinfo[i].extraoffset = 0; 
-                 Zipinfo[i].totalblocks = 0; 
-         } 
-   
-         /* load all values */ 
-         start = 0; 
-         end   = 5; 
-         x         = 3; 
-         for (i = start, ok = TRUE, pa = FALSE; i < end; i++) { 
-                 ok = NULL != fd_openit(i); 
-                 pa = pa || ok; 
-                 ok = ok && egtb_loadindexes (i); 
-         } 
-         complet[x] = ok; 
-         partial[x] = pa; 
-   
-         start = 5; 
-         end   = 35; 
-         x         = 4; 
-         for (i = start, ok = TRUE, pa = FALSE; i < end; i++) { 
-                 ok = NULL != fd_openit(i); 
-                 pa = pa || ok; 
-                 ok = ok && egtb_loadindexes (i); 
-         } 
-         complet[x] = ok; 
-         partial[x] = pa; 
-   
-         start = 35; 
-         end   = MAX_EGKEYS; 
-         x         = 5; 
-         for (i = start, ok = TRUE, pa = FALSE; i < end; i++) { 
-                 ok = NULL != fd_openit(i); 
-                 pa = pa || ok; 
-                 ok = ok && egtb_loadindexes (i); 
-         } 
-         complet[x] = ok; 
-         partial[x] = pa; 
-   
-   
-         for (j = 0, z = 0, x = 3; x < 8; x++) { 
-                 if (partial[x]) z |= 1u << j; 
-                 j++; 
-                 if (complet[x]) z |= 1u << j; 
-                 j++; 
-         } 
-   
-         ret = z; 
-   
-         return ret; 
- } 
-   
- static void 
- zipinfo_done (void) 
- { 
-         int i; 
-         bool_t ok; 
-         for (i = 0, ok = TRUE; ok && i < MAX_EGKEYS; i++) { 
-                 if (Zipinfo[i].blockindex != NULL) { 
-                         free(- Zipinfo [- i ]- . blockindex);
 
-                         Zipinfo[i].blockindex = NULL; 
-                         Zipinfo[i].extraoffset = 0; 
-                         Zipinfo[i].totalblocks = 0; 
-                 } 
-         } 
-         return; 
- } 
-   
- static size_t 
- zipinfo_memory_allocated (void) 
- { 
-         int i; 
-         index_t accum_blocks = 0; 
-         for (i = 0; i < MAX_EGKEYS; i++) { 
-                 if (Zipinfo[i].blockindex != NULL) { 
-                         accum_blocks += Zipinfo[i].totalblocks; 
-                 } 
-         } 
-         return (size_t)accum_blocks * sizeof(index_t); 
- } 
-   
- extern size_t 
- tb_indexmemory (void) 
- { 
-         return zipinfo_memory_allocated (); 
- } 
-   
- static bool_t 
- fread32 (FILE *f, unsigned long int *y) 
- { 
-         enum SIZE {SZ = 4}; 
-         int i; 
-         unsigned long int x; 
-         unsigned char p[SZ]; 
-         bool_t ok; 
-   
-         ok  = (- SZ  == fread (- p , sizeof(unsigned char),-  SZ ,-  f ));
-   
-         if (ok) { 
-                 for (x = 0, i = 0; i < SZ; i++) { 
-                         x |= (unsigned long int)p[i] << (i*8); 
-                 } 
-                 *y = x; 
-         } 
-         return ok; 
- } 
-   
- static bool_t 
- egtb_loadindexes (tbkey_t key) 
- { 
-   
-         unsigned long int blocksize = 1; 
-         unsigned long int tailblocksize1 = 0; 
-         unsigned long int tailblocksize2 = 0; 
-     unsigned long int offset=0; 
-         unsigned long int dummy; 
-         unsigned long int i; 
-         unsigned long int blocks; 
-         unsigned long int n_idx; 
-         unsigned long int idx = 0; 
-         index_t *p; 
-   
-         bool_t ok; 
-   
-         FILE *f; 
-   
-         if (Uncompressed) { 
-                 assert (- decoding_scheme () == 0 &&-  GTB_scheme  == 0);
 
-                 return TRUE; /* no need to load indexes */ 
-         } 
-         if (Zipinfo[key].blockindex != NULL) 
-                 return TRUE; /* indexes must have been loaded already */ 
-   
-         if (NULL == (f = egkey[key].fd)) 
-                 return FALSE; /* file was no open */ 
-   
-         /* Get Reserved bytes, blocksize, offset */ 
-         ok  = (0 == fseek (- f , 0,-  SEEK_SET )) &&
-         fread32 (f, &dummy) && 
-         fread32 (f, &dummy) && 
-         fread32 (f, &blocksize) && 
-         fread32 (f, &dummy) && 
-         fread32 (f, &tailblocksize1) && 
-         fread32 (f, &dummy) && 
-         fread32 (f, &tailblocksize2) && 
-         fread32 (f, &dummy) && 
-         fread32 (f, &offset) && 
-         fread32 (f, &dummy); 
-   
-         blocks = (offset - 40)/4 -1; 
-         n_idx = blocks + 1; 
-   
-         p = NULL; 
-   
-         ok  =-  ok  &&-  NULL  != (- p  = (- index_t  *)malloc (- n_idx  * sizeof(- index_t )));
-   
-         /* Input of Indexes */ 
-         for (i = 0; ok && i < n_idx; i++) { 
-                 ok = fread32 (f, &idx); 
-                 p [- i ] = (- index_t )- idx ; /* reads a 32 bit int, and converts it to index_t */ assert (sizeof(- index_t ) >= 4);
-         } 
-   
-         if (ok) { 
-                 Zipinfo[key].extraoffset = 0; 
-                 Zipinfo[key].totalblocks = (index_t) n_idx; 
-                 Zipinfo[key].blockindex  = p; 
-         } 
-   
-         if (!ok && p != NULL) { 
-         } 
-   
-         return ok; 
- } 
-   
- static index_t 
- egtb_block_uncompressed_to_index (tbkey_t key, index_t b) 
- { 
-         index_t max; 
-         index_t blocks_per_side; 
-         index_t idx; 
-   
-         max = egkey[key].maxindex; 
-         blocks_per_side = 1 + (max-1) / (index_t)dtm_cache.entries_per_block; 
-   
-         if (b < blocks_per_side) { 
-                 idx = 0; 
-         } else { 
-                 b -= blocks_per_side; 
-                 idx = max; 
-         } 
-         idx += b * (index_t)dtm_cache.entries_per_block; 
-         return idx; 
- } 
-   
-   
- static index_t 
- egtb_block_getnumber (tbkey_t key, unsigned side, index_t idx) 
- { 
-         index_t blocks_per_side; 
-         index_t block_in_side; 
-         index_t max = egkey[key].maxindex; 
-   
-         blocks_per_side = 1 + (max-1) / (index_t)dtm_cache.entries_per_block; 
-         block_in_side   = idx         / (index_t)dtm_cache.entries_per_block; 
-   
-         return (index_t)side * blocks_per_side + block_in_side; /* block */ 
- } 
-   
-   
- static index_t 
- egtb_block_getsize (tbkey_t key, index_t idx) 
- { 
-         index_t blocksz = (index_t) dtm_cache.entries_per_block; 
-         index_t maxindex  = egkey[key].maxindex; 
-         index_t block, offset, x; 
-   
-         assert (- dtm_cache. entries_per_block <=-  MAXINDEX_T );
 
-         assert (0 <=-  idx  &&-  idx  <-  maxindex );
 
-   
-         block = idx / blocksz; 
-         offset = block * blocksz; 
-   
-         /* 
-         |       adjust block size in case that this is the last block 
-         |       and is shorter than "blocksz" 
-         */ 
-         if ( (offset + blocksz) > maxindex) 
-                 x = maxindex - offset; /* last block size */ 
-         else 
-                 x = blocksz; /* size of a normal block */ 
-   
-         return x; 
- } 
-   
- static index_t 
- egtb_block_getsize_zipped (tbkey_t key, index_t block ) 
- { 
-         index_t i, j; 
-         assert (- Zipinfo [- key ]- . blockindex !=-  NULL );
 
-         i = Zipinfo[key].blockindex[block]; 
-         j = Zipinfo[key].blockindex[block+1]; 
-         return j - i; 
- } 
-   
-   
- static bool_t 
- egtb_file_beready (tbkey_t key) 
- { 
-         bool_t success; 
-         success =       (NULL != egkey[key].fd) || 
-                                 (NULL != fd_openit(key) && egtb_loadindexes (key)); 
-         return success; 
- } 
-   
-   
- static bool_t 
- egtb_block_park  (tbkey_t key, index_t block) 
- { 
-         index_t i; 
-         long fseek_i; 
-         assert (- egkey [- key ]- . fd !=-  NULL );
 
-   
-         if (Uncompressed) { 
-                 assert (- decoding_scheme () == 0 &&-  GTB_scheme  == 0);
 
-                 i = egtb_block_uncompressed_to_index (key, block); 
-         } else { 
-                 assert (- Zipinfo [- key ]- . blockindex !=-  NULL );
 
-                 i  = Zipinfo[key].blockindex[block]; 
-                 i += Zipinfo[key].extraoffset; 
-         } 
-   
-         fseek_i = (long) i; 
-         return 0 == fseek (- egkey [- key ]- . fd,-  fseek_i ,-  SEEK_SET );
 
- } 
-   
-   
- static bool_t 
- egtb_block_read (tbkey_t key, index_t len, unsigned char *buffer) 
- { 
-         assert (- egkey [- key ]- . fd !=-  NULL );
 
-         assert (sizeof(size_t) >= sizeof(- len ));
 
-         return ((size_t)- len  == fread (- buffer , sizeof (unsigned char), (size_t)- len ,-  egkey [- key ]- . fd));
 
- } 
-   
- tbkey_t TB_PROBE_indexing_dummy; 
-   
- static bool_t 
- egtb_block_decode (tbkey_t key, index_t z, unsigned char *bz, index_t n, unsigned char *bp) 
- /* bz:buffer zipped to bp:buffer packed */ 
- { 
-         size_t zz = (size_t) z; 
-         size_t nn = (size_t) n; 
-         TB_PROBE_indexing_dummy = key; /* to silence compiler */ 
-         assert (sizeof(size_t) >= sizeof(- n ));
 
-         assert (sizeof(size_t) >= sizeof(- z ));
 
-         return decode (zz-1, bz+1, nn, bp); 
- } 
-   
- static bool_t 
- egtb_block_unpack (unsigned side, index_t n, const unsigned char *bp, dtm_t *out) 
- /* bp:buffer packed to out:distance to mate buffer */ 
- { 
-     index_t i; 
-     if (WH == side) { 
-         for (i = 0; i < n; i++) { 
-             *out++ = dtm_unpack (WH, bp[i]); 
-         } 
-     } else { 
-         for (i = 0; i < n; i++) { 
-             *out++ = dtm_unpack (BL, bp[i]); 
-         } 
-     } 
-         return TRUE; 
- } 
-   
- static bool_t 
- preload_cache (tbkey_t key, unsigned side, index_t idx) 
- /* output to the least used block of the cache */ 
- { 
-         dtm_block_t     *pblock; 
-         dtm_t                   *p; 
-         bool_t                  ok; 
-     unsigned char    Buffer_zipped [EGTB_MAXBLOCKSIZE]; 
-     unsigned char    Buffer_packed [EGTB_MAXBLOCKSIZE]; 
-   
-         FOLLOW_label("preload_cache starts") 
-   
-         if (idx >= egkey[key].maxindex) { 
-                 FOLLOW_LULU("Wrong index", __LINE__, idx) 
-                 return FALSE; 
-         } 
-   
-         /* find aged blocked in cache */ 
-         pblock = point_block_to_replace(); 
-   
-         if (NULL == pblock) 
-                 return FALSE; 
-   
-         p = pblock->p_arr; 
-   
-         if (Uncompressed) { 
-   
-                 index_t block = egtb_block_getnumber (key, side, idx); 
-                 index_t n     = egtb_block_getsize   (key, idx); 
-   
-                 ok =       egtb_file_beready (key) 
-                                 && egtb_block_park   (key, block) 
-                                 && egtb_block_read   (key, n, Buffer_packed) 
-                                 && egtb_block_unpack (side, n, Buffer_packed, p); 
-   
-                 FOLLOW_LULU("preload_cache", __LINE__, ok) 
-   
-                 assert (- decoding_scheme () == 0 &&-  GTB_scheme  == 0);
 
-   
-                 if (ok) { Bytes_read = Bytes_read + (uint64_t) n; } 
-   
-         } else { 
-   
-         index_t block = 0; 
-                 index_t n = 0; 
-                 index_t z = 0; 
-   
-                 ok =       egtb_file_beready (key); 
-   
-                 FOLLOW_LULU("preload_cache", __LINE__, ok) 
-   
-                 if (ok) { 
-                         block = egtb_block_getnumber (key, side, idx); 
-                         n     = egtb_block_getsize   (key, idx); 
-                         z     = egtb_block_getsize_zipped (key, block); 
-                 } 
-   
-                 ok =       ok 
-                                 && egtb_block_park   (key, block); 
-                 FOLLOW_LULU("preload_cache", __LINE__, ok) 
-   
-                 ok =       ok 
-                                 && egtb_block_read   (key, z, Buffer_zipped); 
-                 FOLLOW_LULU("preload_cache", __LINE__, ok) 
-   
-         mythread_mutex_unlock (&Egtb_lock); 
-   
-                 ok =       ok 
-                                 && egtb_block_decode (key, z, Buffer_zipped, n, Buffer_packed); 
-                 FOLLOW_LULU("preload_cache", __LINE__, ok) 
-   
-         mythread_mutex_lock (&Egtb_lock); 
-             pblock = point_block_to_replace(); 
-             p = pblock->p_arr; 
-   
-                 ok =       ok 
-                                 && egtb_block_unpack (side, n, Buffer_packed, p); 
-                 FOLLOW_LULU("preload_cache", __LINE__, ok) 
-   
-                 if (ok) { Bytes_read = Bytes_read + (uint64_t) z; } 
-         } 
-   
-         if (ok) { 
-   
-                 index_t                 offset; 
-                 index_t                 remainder; 
-                 split_index (dtm_cache.entries_per_block, idx, &offset, &remainder); 
-   
-                 pblock->key    = key; 
-                 pblock->side   = side; 
-                 pblock->offset = offset; 
-                 dtm_hash_insert (pblock); 
-         } else { 
-                 /* make it unusable */ 
-                 pblock->key    = -1; 
-                 pblock->side   = gtbNOSIDE; 
-                 pblock->offset = gtbNOINDEX; 
-         } 
-   
-         FOLLOW_LU("preload_cache?", ok) 
-   
-         return ok; 
- } 
-   
- /****************************************************************************\ 
- | 
- | 
- |                                               MEMORY ALLOCATION ZONE 
- | 
- | 
- \****************************************************************************/ 
-   
-   
- mySHARED void 
- egtb_freemem (int i) 
- { 
-         if (egkey[i].status == STATUS_MALLOC) { 
-                 assert (- egkey [- i ]- . egt_w !=-  NULL );
 
-                 assert (- egkey [- i ]- . egt_b !=-  NULL );
 
-                 egkey[i].egt_w = NULL; 
-                 egkey[i].egt_b = NULL; 
-         } 
-         egkey[i].status = STATUS_ABSENT; 
- } 
-   
- /***************************************************************************/ 
-   
- mySHARED bool_t 
- get_dtm (tbkey_t key, unsigned side, index_t idx, dtm_t *out, bool_t probe_hard_flag) 
- { 
-         bool_t found; 
-   
-         if (probe_hard_flag) { 
-                 dtm_cache.hard++; 
-         } else { 
-                 dtm_cache.soft++; 
-         } 
-   
-         if (get_dtm_from_cache (key, side, idx, out)) { 
-                 dtm_cache.hits++; 
-                 found = TRUE; 
-         } else if (probe_hard_flag) { 
-                 dtm_cache.hardmisses++; 
-                 found = preload_cache (key, side, idx) && 
-                                 get_dtm_from_cache (key, side, idx, out); 
-   
-                 if (found) { 
-                         Drive.hits++; 
-                 } else { 
-                         Drive.miss++; 
-                 } 
-   
-   
-         } else { 
-                 dtm_cache.softmisses++; 
-                 found = FALSE; 
-         } 
-         return found; 
- } 
-   
-   
- static bool_t 
- get_dtm_from_cache (tbkey_t key, unsigned side, index_t idx, dtm_t *out) 
- { 
-         index_t         offset; 
-         index_t         remainder; 
-         bool_t          found; 
-         dtm_block_t     *p; 
-   
-         if (!dtm_cache_is_on()) 
-                 return FALSE; 
-   
-         split_index (dtm_cache.entries_per_block, idx, &offset, &remainder); 
-   
-         found = NULL != (p = dtm_cache_pointblock (key, side, idx)); 
-   
-         if (found) { 
-                 *out = p->p_arr[remainder]; 
-                 movetotop(p); 
-         } 
-   
-         FOLLOW_LU("get_dtm_from_cache ok?",found) 
-   
-         return found; 
- } 
-   
-   
- static void 
- split_index (size_t entries_per_block, index_t i, index_t *o, index_t *r) 
- { 
-         index_t n; 
-         n  = i / (index_t) entries_per_block; 
-         *o = n * (index_t) entries_per_block; 
-         *r = i - *o; 
-         return; 
- } 
-   
-   
- static dtm_block_t * 
- point_block_to_replace (void) 
- { 
-         dtm_block_t *p, *t, *s; 
-   
-         assert (0 ==-  dtm_cache. n ||-  dtm_cache. top !=-  NULL );
 
-         assert (0 ==-  dtm_cache. n ||-  dtm_cache. bot !=-  NULL );
 
-         assert (0 ==-  dtm_cache. n ||-  dtm_cache. bot->- prev  ==-  NULL );
 
-         assert (0 ==-  dtm_cache. n ||-  dtm_cache. top->- next  ==-  NULL );
 
-   
-         /* no cache is being used */ 
-         if (dtm_cache.max_blocks == 0) 
-                 return NULL; 
-   
-         if (dtm_cache.n > 0 && -1 == dtm_cache.top->key) { 
-   
-                 /* top entry is unusable, should be the one to replace*/ 
-                 p = dtm_cache.top; 
-   
-         } else 
-         if (dtm_cache.n == 0) { 
-   
-                 assert (- NULL  !=-  dtm_cache. entry);
 
-                 p = &dtm_cache.entry[dtm_cache.n++]; 
-                 dtm_cache.top = p; 
-                 dtm_cache.bot = p; 
-   
-                 p->prev = NULL; 
-                 p->next = NULL; 
-   
-         } else 
-         if (dtm_cache.n < dtm_cache.max_blocks) { /* add */ 
-   
-                 assert (- NULL  !=-  dtm_cache. entry);
 
-                 s = dtm_cache.top; 
-                 p = &dtm_cache.entry[dtm_cache.n++]; 
-                 dtm_cache.top = p; 
-   
-                 assert (- NULL  !=-  p  &&-  NULL  !=-  s );
 
-                 s->next = p; 
-                 p->prev = s; 
-                 p->next = NULL; 
-   
-         } else if (1 < dtm_cache.max_blocks) { /* replace*/ 
-   
-                 assert (- NULL  !=-  dtm_cache. bot &&-  NULL  !=-  dtm_cache. top);
 
-                 t = dtm_cache.bot; 
-                 s = dtm_cache.top; 
-   
-                 dtm_cache.bot = t->next; 
-                 dtm_cache.top = t; 
-   
-                 s->next = t; 
-                 t->prev = s; 
-   
-                 dtm_cache.top->next = NULL; 
-   
-                 dtm_cache.bot->prev = NULL; 
-   
-                 p = t; 
-   
-         } else { 
-   
-                 assert (1 ==-  dtm_cache. max_blocks);
 
-                 p =     dtm_cache.top; 
-                 assert (- p  ==-  dtm_cache. bot &&-  p  ==-  dtm_cache. entry);
 
-         } 
-   
-         /* make the information content unusable, it will be replaced */ 
-         p->key    = -1; 
-         p->side   = gtbNOSIDE; 
-         p->offset = gtbNOINDEX; 
-   
-         return p; 
- } 
-   
- static void 
- movetotop (dtm_block_t *t) 
- { 
-         dtm_block_t *s, *nx, *pv; 
-   
-   
-         if (t->next == NULL) /* at the top already */ 
-                 return; 
-   
-         /* detach */ 
-         pv = t->prev; 
-         nx = t->next; 
-   
-         if (pv == NULL)  /* at the bottom */ 
-                 dtm_cache.bot = nx; 
-         else 
-                 pv->next = nx; 
-   
-         if (nx == NULL) /* at the top */ 
-                 dtm_cache.top = pv; 
-         else 
-                 nx->prev = pv; 
-   
-         /* relocate */ 
-         s = dtm_cache.top; 
-         if (s == NULL) 
-                 dtm_cache.bot = t; 
-         else 
-                 s->next = t; 
-   
-         t->next = NULL; 
-         t->prev = s; 
-         dtm_cache.top = t; 
-   
-         return; 
- } 
-   
- /****************************************************************************\ 
-  * 
-  * 
-  *                                                              INDEXING ZONE 
-  * 
-  * 
-  ****************************************************************************/ 
-   
- static void 
- init_indexing (int verbosity) 
- { 
-         index_t a,b,c,d,e,f; 
-   
-         init_flipt (); 
-   
-         a = init_kkidx     () ; 
-         b = init_ppidx     () ; 
-         c = init_aaidx     () ; 
-         d = init_aaa       () ; 
-         e = init_pp48_idx  () ; 
-         f = init_ppp48_idx () ; 
-   
-         if (verbosity) { 
-                 printf ("\nGTB supporting tables, Initialization\n"); 
-                 printf ("  Max    kk idx: %8d\n", (int)- a  );
 
-                 printf ("  Max    pp idx: %8d\n", (int)- b  );
 
-                 printf ("  Max    aa idx: %8d\n", (int)- c  );
 
-                 printf ("  Max   aaa idx: %8d\n", (int)- d  );
 
-                 printf ("  Max  pp48 idx: %8d\n", (int)- e  );
 
-                 printf ("  Max ppp48 idx: %8d\n", (int)- f  );
 
-         } 
-   
-         if (!reach_was_initialized()) 
-                 reach_init(); 
-   
-         /* testing used only in development stage */ 
-   
- #ifdef _MSC_VER 
- #pragma warning(disable:4127) 
- #endif 
-   
-         if (0) { 
-                 list_index (); 
-                 printf ("\nTEST indexing functions\n"); 
-   
-                 test_kaakb (); 
-                 test_kaabk (); 
-                 test_kaaak (); 
-                 test_kabbk (); 
-   
-                 test_kapkb (); 
-                 test_kabkp (); 
-   
-                 test_kppka (); 
-   
-                 test_kapkp (); 
-                 test_kabpk(); 
-                 test_kaapk (); 
-   
-                 test_kappk (); 
-                 test_kaakp (); 
-                 test_kppk (); 
-                 test_kppkp (); 
-                 test_kpppk (); 
-         } 
-   
- #ifdef _MSC_VER 
- #pragma warning(default:4127) 
- #endif 
-   
-         return; 
- } 
-   
-   
- static index_t 
- init_kkidx (void) 
- /* modifies kkidx[][], wksq[], bksq[] */ 
- { 
-         index_t idx; 
-         SQUARE x, y, i, j; 
-   
-         /* default is noindex */ 
-         for (x = 0; x < 64; x++) { 
-                 for (y = 0; y < 64; y++) { 
-                         IDX_set_empty(kkidx [x][y]); 
-                 } 
-         } 
-   
-         idx = 0; 
-         for (x = 0; x < 64; x++) { 
-                 for (y = 0; y < 64; y++) { 
-   
-                         /* is x,y illegal? continue */ 
-                         if (possible_attack (x, y, wK) || x == y) 
-                                 continue; 
-   
-                         /* normalize */ 
-                         /*i <-- x; j <-- y */ 
-                         norm_kkindex (x, y, &i, &j); 
-   
-                         if (IDX_is_empty(kkidx [i][j])) { /* still empty */ 
-                                 kkidx [i][j] = idx; 
-                                 kkidx [x][y] = idx; 
-                                 bksq [idx] = i; 
-                                 wksq [idx] = j; 
-                                 idx++; 
-                         } 
-                 } 
-         } 
-   
-   
-         return idx; 
- } 
-   
-   
- static index_t 
- init_aaidx (void) 
- /* modifies aabase[], aaidx[][] */ 
- { 
-         index_t idx; 
-         SQUARE x, y; 
-   
-         /* default is noindex */ 
-         for (x = 0; x < 64; x++) { 
-                 for (y = 0; y < 64; y++) { 
-                         IDX_set_empty(aaidx [x][y]); 
-                 } 
-         } 
-   
-         for (idx = 0; idx < MAX_AAINDEX; idx++) 
-                 aabase [idx] = 0; 
-   
-         idx = 0; 
-         for (x = 0; x < 64; x++) { 
-                 for (y = x + 1; y < 64; y++) { 
-   
-                         assert (- idx  == (int)((- y  --  x ) +-  x  * (127-- x )/2 - 1) );
 
-   
-                         if (IDX_is_empty(aaidx [x][y])) { /* still empty */ 
-                                 aaidx [x] [y] = idx; 
-                                 aaidx [y] [x] = idx; 
-                                 aabase [idx] = (unsigned char) x; 
-                                 idx++; 
-                         } else { 
-                                 assert (- aaidx  [- x ] [- y ] ==-  idx );
 
-                         } 
-   
-   
-                 } 
-         } 
-   
-   
-         return idx; 
- } 
-   
-   
- static index_t 
- init_ppidx (void) 
- /* modifies ppidx[][], pp_hi24[], pp_lo48[] */ 
- { 
-         index_t i, j; 
-         index_t idx = 0; 
-         SQUARE a, b; 
-   
-         /* default is noindex */ 
-         for (i = 0; i < 24; i++) { 
-                 for (j = 0; j < 48; j++) { 
-                         IDX_set_empty(ppidx [i][j]); 
-                 } 
-         } 
-   
-         for (idx = 0; idx < MAX_PPINDEX; idx++) { 
-                 IDX_set_empty(pp_hi24 [idx]); 
-                 IDX_set_empty(pp_lo48 [idx]); 
-         } 
-   
-         idx = 0; 
-         for (a = H7; a >= A2; a--) { 
-   
-                 if ((a & 07) < 4) /* square in the queen side */ 
-                         continue; 
-   
-                 for (b = a - 1; b >= A2; b--) { 
-   
-                         SQUARE anchor, loosen; 
-   
-                         pp_putanchorfirst (a, b, &anchor, &loosen); 
-   
-                         if ((anchor & 07) > 3) { /* square in the king side */ 
-                                 anchor = flipWE(anchor); 
-                                 loosen = flipWE(loosen); 
-                         } 
-   
-                         i = wsq_to_pidx24 (anchor); 
-                         j = wsq_to_pidx48 (loosen); 
-   
-                         if (IDX_is_empty(ppidx [i] [j])) { 
-   
-                 ppidx [i] [j] = idx; 
-                 pp_hi24 [idx] = i; 
-                 pp_lo48 [idx] = j; 
-                                 idx++; 
-                         } 
-   
-                 } 
-         } 
-         return idx; 
- } 
-   
- static void 
- init_flipt (void) 
- { 
-         unsigned int i, j; 
-         for (i = 0; i < 64; i++) { 
-                 for (j = 0; j < 64; j++) { 
-                         flipt [i] [j] = flip_type (i, j); 
-                 } 
-         } 
- } 
-   
- /*--- NORMALIZE -------*/ 
-   
- static void 
- norm_kkindex (SQUARE x, SQUARE y, /*@out@*/ SQUARE *pi, /*@out@*/ SQUARE *pj) 
- { 
-         unsigned int rowx, rowy, colx, coly; 
-   
-   
-         if (getcol(x) > 3) { 
-                 x = flipWE (x); /* x = x ^ 07  */ 
-                 y = flipWE (y); 
-         } 
-         if (getrow(x) > 3)  { 
-                 x = flipNS (x); /* x = x ^ 070  */ 
-                 y = flipNS (y); 
-         } 
-         rowx = getrow(x); 
-         colx = getcol(x); 
-         if ( rowx > colx ) { 
-                 x = flipNW_SE (x); /* x = ((x&7)<<3) | (x>>3) */ 
-                 y = flipNW_SE (y); 
-         } 
-         rowy = getrow(y); 
-         coly = getcol(y); 
-         if ( rowx == colx && rowy > coly) { 
-                 x = flipNW_SE (x); 
-                 y = flipNW_SE (y); 
-         } 
-   
-         *pi = x; 
-         *pj = y; 
- } 
-   
- static unsigned int 
- flip_type (SQUARE x, SQUARE y) 
- { 
-         unsigned int rowx, rowy, colx, coly; 
-         unsigned int ret = 0; 
-   
-   
-   
-         if (getcol(x) > 3) { 
-                 x = flipWE (x); /* x = x ^ 07  */ 
-                 y = flipWE (y); 
-                 ret |= 1; 
-         } 
-         if (getrow(x) > 3)  { 
-                 x = flipNS (x); /* x = x ^ 070  */ 
-                 y = flipNS (y); 
-                 ret |= 2; 
-         } 
-         rowx = getrow(x); 
-         colx = getcol(x); 
-         if ( rowx > colx ) { 
-                 x = flipNW_SE (x); /* x = ((x&7)<<3) | (x>>3) */ 
-                 y = flipNW_SE (y); 
-                 ret |= 4; 
-         } 
-         rowy = getrow(y); 
-         coly = getcol(y); 
-         if ( rowx == colx && rowy > coly) { 
-                 x = flipNW_SE (x); 
-                 y = flipNW_SE (y); 
-                 ret |= 4; 
-         } 
-         return ret; 
- } 
-   
-   
- static void 
- pp_putanchorfirst (SQUARE a, SQUARE b, /*@out@*/ SQUARE *out_anchor, /*@out@*/ SQUARE *out_loosen) 
- { 
-         unsigned int anchor, loosen; 
-   
-         unsigned int row_b, row_a; 
-         row_b = b & 070; 
-         row_a = a & 070; 
-   
-         /* default */ 
-         anchor = a; 
-         loosen = b; 
-         if (row_b > row_a) { 
-                 anchor = b; 
-                 loosen = a; 
-         } 
-         else 
-         if (row_b == row_a) { 
-                 unsigned int x, col, inv, hi_a, hi_b; 
-                 x = a; 
-                 col = x & 07; 
-                 inv = col ^ 07; 
-                 x = (1u<<col) | (1u<<inv); 
-                 x &= (x-1); 
-                 hi_a = x; 
-   
-                 x = b; 
-                 col = x & 07; 
-                 inv = col ^ 07; 
-                 x = (1u<<col) | (1u<<inv); 
-                 x &= (x-1); 
-                 hi_b = x; 
-   
-                 if (hi_b > hi_a) { 
-                         anchor = b; 
-                         loosen = a; 
-                 } 
-   
-                 if (hi_b < hi_a) { 
-                         anchor = a; 
-                         loosen = b; 
-                 } 
-   
-                 if (hi_b == hi_a) { 
-                         if (a < b) { 
-                                 anchor = a; 
-                                 loosen = b; 
-                         } else { 
-                                 anchor = b; 
-                                 loosen = a; 
-                         } 
-                 } 
-         } 
-   
-         *out_anchor = anchor; 
-         *out_loosen = loosen; 
-         return; 
- } 
-   
-   
- static index_t 
- wsq_to_pidx24 (SQUARE pawn) 
- { 
-         unsigned int idx24; 
-         SQUARE sq = pawn; 
-   
-         /* input can be only queen side, pawn valid */ 
-         assert (- A2  <=-  pawn  &&-  pawn  <-  A8 );
 
-   
-         sq ^= 070; /* flipNS*/ 
-         sq -= 8;   /* down one row*/ 
-         idx24 = (sq+(sq&3)) >> 1; 
-         return (index_t) idx24; 
- } 
-   
- static index_t 
- wsq_to_pidx48 (SQUARE pawn) 
- { 
-         unsigned int idx48; 
-         SQUARE sq = pawn; 
-   
-         /* input can be both queen or king side, pawn valid square  */ 
-         assert (- A2  <=-  pawn  &&-  pawn  <-  A8 );
 
-   
-         sq ^= 070; /* flipNS*/ 
-         sq -= 8;   /* down one row*/ 
-         idx48 = sq; 
-         return (index_t)idx48; 
- } 
-   
- static SQUARE 
- pidx24_to_wsq (index_t a) 
- { 
-         enum  {B11100  = 7u << 2}; 
-         unsigned int x = (unsigned int) a;      /* x is pslice */ 
-   
-         x += x & B11100; /* get upper part and double it */ 
-         x += 8;          /* add extra row  */ 
-         x ^= 070;        /* flip NS */ 
-         return (SQUARE) x; 
- } 
-   
- static SQUARE 
- pidx48_to_wsq (index_t a) 
- { 
-         unsigned int x; 
-         /* x is pslice */ 
-         x = (unsigned int)a; 
-         x += 8;          /* add extra row  */ 
-         x ^= 070;        /* flip NS */ 
-         return x; 
- } 
-   
-   
- static void 
- kxk_indextopc (index_t i, SQUARE *pw, SQUARE *pb) 
- { 
-         enum  {BLOCK_A = 64}; 
-   
-         index_t a = i / BLOCK_A; 
-         index_t b = i - a * BLOCK_A; 
-   
-         pw[0] = wksq [a]; 
-         pb[0] = bksq [a]; 
-         pw[1] = (SQUARE) b; 
-         pw[2] = NOSQUARE; 
-         pb[1] = NOSQUARE; 
-   
-         assert (- kxk_pctoindex  (- pw ,-  pb , &- a ) &&-  a  ==-  i );
 
-   
-         return; 
- } 
-   
- static bool_t 
- kxk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out) 
- { 
-         enum  {BLOCK_A = 64}; 
-         SQUARE *p; 
-         SQUARE ws[32], bs[32]; 
-         index_t ki; 
-         int i; 
-   
-         unsigned int ft; 
-   
-         ft = flip_type (inp_pb[0],inp_pw[0]); 
-   
-   
-   
-         for (i = 0; inp_pw[i] != NOSQUARE; i++) { 
-                 ws[i] = inp_pw[i]; 
-         } 
-         ws[i] = NOSQUARE; 
-         for (i = 0; inp_pb[i] != NOSQUARE; i++) { 
-                 bs[i] = inp_pb[i]; 
-         } 
-         bs[i] = NOSQUARE; 
-   
-         if ((ft & 1) != 0) { 
-                 for (p = ws; *p != NOSQUARE; p++) 
-                                 *p = flipWE (*p); 
-                 for (p = bs; *p != NOSQUARE; p++) 
-                                 *p = flipWE (*p); 
-         } 
-   
-         if ((ft & 2) != 0) { 
-                 for (p = ws; *p != NOSQUARE; p++) 
-                                 *p = flipNS (*p); 
-                 for (p = bs; *p != NOSQUARE; p++) 
-                                 *p = flipNS (*p); 
-         } 
-   
-         if ((ft & 4) != 0) { 
-                 for (p = ws; *p != NOSQUARE; p++) 
-                                 *p = flipNW_SE (*p); 
-                 for (p = bs; *p != NOSQUARE; p++) 
-                                 *p = flipNW_SE (*p); 
-         } 
-   
-         ki = kkidx [bs[0]] [ws[0]]; /* kkidx [black king] [white king] */ 
-   
-         if (IDX_is_empty(ki)) { 
-                 *out = NOINDEX; 
-                 return FALSE; 
-         } 
-         *out = ki * BLOCK_A + (index_t) ws[1]; 
-         return TRUE; 
-   
- } 
-   
-   
- static void 
- kabk_indextopc (index_t i, SQUARE *pw, SQUARE *pb) 
- { 
-         enum  {BLOCK_A = 64*64, BLOCK_B = 64}; 
-         index_t a, b, c, r; 
-   
-         r = i; 
-         a  = r / BLOCK_A; 
-         r -= a * BLOCK_A; 
-         b  = r / BLOCK_B; 
-         r -= b * BLOCK_B; 
-         c  = r; 
-   
-         pw[0] = wksq [a]; 
-         pb[0] = bksq [a]; 
-   
-         pw[1] = (SQUARE) b; 
-         pw[2] = (SQUARE) c; 
-         pw[3] = NOSQUARE; 
-   
-         pb[1] = NOSQUARE; 
-   
-         assert (- kabk_pctoindex  (- pw ,-  pb , &- a ) &&-  a  ==-  i );
 
-   
-         return; 
- } 
-   
-   
- static bool_t 
- kabk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out) 
- { 
-         enum  {BLOCK_A = 64*64, BLOCK_B = 64}; 
-         SQUARE *p; 
-         SQUARE ws[32], bs[32]; 
-         index_t ki; 
-         int i; 
-   
-         unsigned int ft; 
-   
-         ft = flip_type (inp_pb[0],inp_pw[0]); 
-   
-   
-         for (i = 0; inp_pw[i] != NOSQUARE; i++) { 
-                 ws[i] = inp_pw[i]; 
-         } 
-         ws[i] = NOSQUARE; 
-         for (i = 0; inp_pb[i] != NOSQUARE; i++) { 
-                 bs[i] = inp_pb[i]; 
-         } 
-         bs[i] = NOSQUARE; 
-   
-         if ((ft & 1) != 0) { 
-                 for (p = ws; *p != NOSQUARE; p++) 
-                                 *p = flipWE (*p); 
-                 for (p = bs; *p != NOSQUARE; p++) 
-                                 *p = flipWE (*p); 
-         } 
-   
-         if ((ft & 2) != 0) { 
-                 for (p = ws; *p != NOSQUARE; p++) 
-                                 *p = flipNS (*p); 
-                 for (p = bs; *p != NOSQUARE; p++) 
-                                 *p = flipNS (*p); 
-         } 
-   
-         if ((ft & 4) != 0) { 
-                 for (p = ws; *p != NOSQUARE; p++) 
-                                 *p = flipNW_SE (*p); 
-                 for (p = bs; *p != NOSQUARE; p++) 
-                                 *p = flipNW_SE (*p); 
-         } 
-   
-         ki = kkidx [bs[0]] [ws[0]]; /* kkidx [black king] [white king] */ 
-   
-         if (IDX_is_empty(ki)) { 
-                 *out = NOINDEX; 
-                 return FALSE; 
-         } 
-         *out = ki * BLOCK_A + (index_t)ws[1] * BLOCK_B + (index_t)ws[2]; 
-         return TRUE; 
-   
- } 
-   
-   
- static void 
- kabkc_indextopc (index_t i, SQUARE *pw, SQUARE *pb) 
- { 
-         enum  {BLOCK_A = 64*64*64, BLOCK_B = 64*64, BLOCK_C = 64}; 
-         index_t a, b, c, d, r; 
-   
-         r = i; 
-         a  = r / BLOCK_A; 
-         r -= a * BLOCK_A; 
-         b  = r / BLOCK_B; 
-         r -= b * BLOCK_B; 
-         c  = r / BLOCK_C; 
-         r -= c * BLOCK_C; 
-         d  = r; 
-   
-         pw[0] = wksq [a]; 
-         pb[0] = bksq [a]; 
-   
-         pw[1] = (SQUARE) b; 
-         pw[2] = (SQUARE) c; 
-         pw[3] = NOSQUARE; 
-   
-         pb[1] = (SQUARE) d; 
-         pb[2] = NOSQUARE; 
-   
-         assert (- kabkc_pctoindex  (- pw ,-  pb , &- a ) &&-  a  ==-  i );
 
-   
-         return; 
- } 
-   
-   
- static bool_t 
- kabkc_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out) 
- { 
-         enum  {N_WHITE = 3, N_BLACK = 2}; 
-   
-         enum  {BLOCK_A = 64*64*64, BLOCK_B = 64*64, BLOCK_C = 64}; 
-         SQUARE ws[MAX_LISTSIZE], bs[MAX_LISTSIZE]; 
-         index_t ki; 
-         int i; 
-         unsigned int ft; 
-   
-         #if 0 
-                 ft = flip_type (inp_pb[0], inp_pw[0]); 
-         #else 
-                 ft = flipt [inp_pb[0]] [inp_pw[0]]; 
-         #endif 
-   
-   
-         for (i = 0; i < N_WHITE; i++) ws[i] = inp_pw[i]; ws[N_WHITE] = NOSQUARE; 
-         for (i = 0; i < N_BLACK; i++) bs[i] = inp_pb[i]; bs[N_BLACK] = NOSQUARE; 
-   
-         if ((ft & WE_FLAG) != 0) { 
-                 for (i = 0; i < N_WHITE; i++) ws[i] = flipWE (ws[i]); 
-                 for (i = 0; i < N_BLACK; i++) bs[i] = flipWE (bs[i]); 
-         } 
-   
-         if ((ft & NS_FLAG) != 0) { 
-                 for (i = 0; i < N_WHITE; i++) ws[i] = flipNS (ws[i]); 
-                 for (i = 0; i < N_BLACK; i++) bs[i] = flipNS (bs[i]); 
-         } 
-   
-         if ((ft & NW_SE_FLAG) != 0) { 
-                 for (i = 0; i < N_WHITE; i++) ws[i] = flipNW_SE (ws[i]); 
-                 for (i = 0; i < N_BLACK; i++) bs[i] = flipNW_SE (bs[i]); 
-         } 
-   
-   
-         ki = kkidx [bs[0]] [ws[0]]; /* kkidx [black king] [white king] */ 
-   
-         if (IDX_is_empty(ki)) { 
-                 *out = NOINDEX; 
-                 return FALSE; 
-         } 
-         *out = ki * BLOCK_A + (index_t)ws[1] * BLOCK_B + (index_t)ws[2] * BLOCK_C + (index_t)bs[1]; 
-         return TRUE; 
-   
- } 
-   
- /* ABC/ ***/ 
-   
- extern void 
- kabck_indextopc (index_t i, SQUARE *pw, SQUARE *pb) 
- { 
-         enum  {BLOCK_A = 64*64*64, BLOCK_B = 64*64, BLOCK_C = 64}; 
-         index_t a, b, c, d, r; 
-   
-         r = i; 
-         a  = r / BLOCK_A; 
-         r -= a * BLOCK_A; 
-         b  = r / BLOCK_B; 
-         r -= b * BLOCK_B; 
-         c  = r / BLOCK_C; 
-         r -= c * BLOCK_C; 
-         d  = r; 
-   
-         pw[0] = wksq [a]; 
-         pb[0] = bksq [a]; 
-   
-         pw[1] = (SQUARE) b; 
-         pw[2] = (SQUARE) c; 
-         pw[3] = (SQUARE) d; 
-         pw[4] = NOSQUARE; 
-   
-         pb[1] = NOSQUARE; 
-   
-         assert (- kabck_pctoindex  (- pw ,-  pb , &- a ) &&-  a  ==-  i );
 
-   
-         return; 
- } 
-   
-   
- extern bool_t 
- kabck_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out) 
- { 
-         enum  {N_WHITE = 4, N_BLACK = 1}; 
-         enum  {BLOCK_A = 64*64*64, BLOCK_B = 64*64, BLOCK_C = 64}; 
-   
-         SQUARE ws[MAX_LISTSIZE], bs[MAX_LISTSIZE]; 
-         index_t ki; 
-         int i; 
-         unsigned int ft; 
-   
-         ft = flipt [inp_pb[0]] [inp_pw[0]]; 
-   
-   
-         for (i = 0; i < N_WHITE; i++) ws[i] = inp_pw[i]; ws[N_WHITE] = NOSQUARE; 
-         for (i = 0; i < N_BLACK; i++) bs[i] = inp_pb[i]; bs[N_BLACK] = NOSQUARE; 
-   
-         if ((ft & WE_FLAG) != 0) { 
-                 for (i = 0; i < N_WHITE; i++) ws[i] = flipWE (ws[i]); 
-                 for (i = 0; i < N_BLACK; i++) bs[i] = flipWE (bs[i]); 
-         } 
-   
-         if ((ft & NS_FLAG) != 0) { 
-                 for (i = 0; i < N_WHITE; i++) ws[i] = flipNS (ws[i]); 
-                 for (i = 0; i < N_BLACK; i++) bs[i] = flipNS (bs[i]); 
-         } 
-   
-         if ((ft & NW_SE_FLAG) != 0) { 
-                 for (i = 0; i < N_WHITE; i++) ws[i] = flipNW_SE (ws[i]); 
-                 for (i = 0; i < N_BLACK; i++) bs[i] = flipNW_SE (bs[i]); 
-         } 
-   
-   
-         ki = kkidx [bs[0]] [ws[0]]; /* kkidx [black king] [white king] */ 
-   
-         if (IDX_is_empty(ki)) { 
-                 *out = NOINDEX; 
-                 return FALSE; 
-         } 
-         *out = ki * BLOCK_A + (index_t)ws[1] * BLOCK_B + (index_t)ws[2] * BLOCK_C + (index_t)ws[3]; 
-         return TRUE; 
-   
- } 
-   
-   
- static void 
- kakb_indextopc (index_t i, SQUARE *pw, SQUARE *pb) 
- { 
-         enum  {BLOCK_A = 64*64, BLOCK_B = 64}; 
-         index_t a, b, c, r; 
-   
-         r = i; 
-         a  = r / BLOCK_A; 
-         r -= a * BLOCK_A; 
-         b  = r / BLOCK_B; 
-         r -= b * BLOCK_B; 
-         c  = r; 
-   
-         pw[0] = wksq [a]; 
-         pb[0] = bksq [a]; 
-   
-         pw[1] = (SQUARE) b; 
-         pw[2] = NOSQUARE; 
-   
-         pb[1] = (SQUARE) c; 
-         pb[2] = NOSQUARE; 
-   
-         assert (- kakb_pctoindex  (- pw ,-  pb , &- a ) &&-  a  ==-  i );
 
-   
-         return; 
- } 
-   
-   
- static bool_t 
- kakb_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out) 
- { 
-         enum  {BLOCK_A = 64*64, BLOCK_B = 64}; 
-         SQUARE ws[32], bs[32]; 
-         index_t ki; 
-         unsigned int ft; 
-   
-         #if 0 
-                 ft = flip_type (inp_pb[0], inp_pw[0]); 
-         #else 
-                 ft = flipt [inp_pb[0]] [inp_pw[0]]; 
-         #endif 
-   
-   
-         ws[0] = inp_pw[0]; 
-         ws[1] = inp_pw[1]; 
-         ws[2] = NOSQUARE; 
-   
-         bs[0] = inp_pb[0]; 
-         bs[1] = inp_pb[1]; 
-         bs[2] = NOSQUARE; 
-   
-         if ((ft & 1) != 0) { 
-                 ws[0] = flipWE (ws[0]); 
-                 ws[1] = flipWE (ws[1]); 
-                 bs[0] = flipWE (bs[0]); 
-                 bs[1] = flipWE (bs[1]); 
-         } 
-   
-         if ((ft & 2) != 0) { 
-                 ws[0] = flipNS (ws[0]); 
-                 ws[1] = flipNS (ws[1]); 
-                 bs[0] = flipNS (bs[0]); 
-                 bs[1] = flipNS (bs[1]); 
-         } 
-   
-         if ((ft & 4) != 0) { 
-                 ws[0] = flipNW_SE (ws[0]); 
-                 ws[1] = flipNW_SE (ws[1]); 
-                 bs[0] = flipNW_SE (bs[0]); 
-                 bs[1] = flipNW_SE (bs[1]); 
-         } 
-   
-         ki = kkidx [bs[0]] [ws[0]]; /* kkidx [black king] [white king] */ 
-   
-         if (IDX_is_empty(ki)) { 
-                 *out = NOINDEX; 
-                 return FALSE; 
-         } 
-         *out = ki * BLOCK_A + (index_t)ws[1] * BLOCK_B + (index_t)bs[1]; 
-         return TRUE; 
-   
- } 
-   
- /********************** KAAKB *************************************/ 
-   
- static bool_t   test_kaakb (void); 
- static bool_t   kaakb_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); 
- static void             kaakb_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
-   
- static bool_t 
- test_kaakb (void) 
- { 
-   
-         enum  {MAXPC = 16+1}; 
-         char            str[] = "kaakb"; 
-         SQUARE          a, b, c, d, e; 
-         SQUARE          pw[MAXPC], pb[MAXPC]; 
-         SQUARE          px[MAXPC], py[MAXPC]; 
-   
-         index_t         i, j; 
-         bool_t          err = FALSE; 
-   
-   
-         for (a = 0; a < 64; a++) { 
-                 for (b = 0; b < 64; b++) { 
-                 for (c = 0; c < 64; c++) { 
-                 for (d = 0; d < 64; d++) { 
-                 for (e = 0; e < 64; e++) { 
-   
-                         pw[0] = a; 
-                         pw[1] = b; 
-                         pw[2] = c; 
-                         pw[3] = NOSQUARE; 
-   
-                         pb[0] = d; 
-                         pb[1] = e; 
-                         pb[2] = NOSQUARE; 
-   
-                         if (kaakb_pctoindex (pw, pb, &i)) { 
-                                                         kaakb_indextopc (i, px, py); 
-                                                         kaakb_pctoindex (px, py, &j); 
-                                                         if (i != j) { 
-                                                                 err = TRUE; 
-                                                         } 
-                         } 
-   
-                 } 
-                 } 
-                 } 
-                 } 
-   
-         if ((a&1)==0) { 
-         } 
-         } 
-   
-         if (err) 
-                 printf ("> %s NOT passed\n",-  str );
 
-         else 
-                 printf ("> %s PASSED\n",-  str );
 
-         return !err; 
- } 
-   
- static void 
- kaakb_indextopc (index_t i, SQUARE *pw, SQUARE *pb) 
- { 
-         enum  { 
-                         BLOCK_B = 64, 
-                         BLOCK_A = BLOCK_B * MAX_AAINDEX 
-                 }; 
-         index_t a, b, c, r, x, y; 
-   
-         r = i; 
-         a  = r / BLOCK_A; 
-         r -= a * BLOCK_A; 
-   
-         b  = r / BLOCK_B; 
-         r -= b * BLOCK_B; 
-   
-         c  = r; 
-   
-         assert (- i  == (- a  *-  BLOCK_A  +-  b  *-  BLOCK_B  +-  c ));
 
-   
-         pw[0] = wksq [a]; 
-         pb[0] = bksq [a]; 
-   
-         x = aabase [b]; 
-         y = (b + 1) + x - (x * (127-x)/2); 
-   
-         pw[1] = (SQUARE) x; 
-         pw[2] = (SQUARE) y; 
-         pw[3] = NOSQUARE; 
-   
-         pb[1] = (SQUARE) c; 
-         pb[2] = NOSQUARE; 
-   
-         assert (- kaakb_pctoindex  (- pw ,-  pb , &- a ) &&-  a  ==-  i );
 
-   
-         return; 
- } 
-   
- static bool_t 
- kaakb_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out) 
- { 
-         enum  {N_WHITE = 3, N_BLACK = 2}; 
-         enum  { 
-                         BLOCK_B = 64, 
-                         BLOCK_A = BLOCK_B * MAX_AAINDEX 
-                 }; 
-         SQUARE ws[MAX_LISTSIZE], bs[MAX_LISTSIZE]; 
-         index_t ki, ai; 
-         unsigned int ft; 
-         int i; 
-   
-         ft = flipt [inp_pb[0]] [inp_pw[0]]; 
-   
-   
-         for (i = 0; i < N_WHITE; i++) ws[i] = inp_pw[i]; ws[N_WHITE] = NOSQUARE; 
-         for (i = 0; i < N_BLACK; i++) bs[i] = inp_pb[i]; bs[N_BLACK] = NOSQUARE; 
-   
-         if ((ft & WE_FLAG) != 0) { 
-                 for (i = 0; i < N_WHITE; i++) ws[i] = flipWE (ws[i]); 
-                 for (i = 0; i < N_BLACK; i++) bs[i] = flipWE (bs[i]); 
-         } 
-   
-         if ((ft & NS_FLAG) != 0) { 
-                 for (i = 0; i < N_WHITE; i++) ws[i] = flipNS (ws[i]); 
-                 for (i = 0; i < N_BLACK; i++) bs[i] = flipNS (bs[i]); 
-         } 
-   
-         if ((ft & NW_SE_FLAG) != 0) { 
-                 for (i = 0; i < N_WHITE; i++) ws[i] = flipNW_SE (ws[i]); 
-                 for (i = 0; i < N_BLACK; i++) bs[i] = flipNW_SE (bs[i]); 
-         } 
-   
-         ki = kkidx [bs[0]] [ws[0]]; /* kkidx [black king] [white king] */ 
-         ai = aaidx [ws[1]] [ws[2]]; 
-   
-         if (IDX_is_empty(ki) || IDX_is_empty(ai)) { 
-                 *out = NOINDEX; 
-                 return FALSE; 
-         } 
-         *out = ki * BLOCK_A + ai * BLOCK_B + (index_t)bs[1]; 
-         return TRUE; 
- } 
-   
- /****************** End KAAKB *************************************/ 
-   
- /********************** KAAB/K ************************************/ 
-   
- static bool_t   test_kaabk (void); 
- static bool_t   kaabk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); 
- static void             kaabk_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
-   
- static bool_t 
- test_kaabk (void) 
- { 
-   
-         enum  {MAXPC = 16+1}; 
-         char            str[] = "kaabk"; 
-         SQUARE          a, b, c, d, e; 
-         SQUARE          pw[MAXPC], pb[MAXPC]; 
-         SQUARE          px[MAXPC], py[MAXPC]; 
-   
-         index_t         i, j; 
-         bool_t          err = FALSE; 
-   
-   
-         for (a = 0; a < 64; a++) { 
-                 for (b = 0; b < 64; b++) { 
-                 for (c = 0; c < 64; c++) { 
-                 for (d = 0; d < 64; d++) { 
-                 for (e = 0; e < 64; e++) { 
-   
-                         pw[0] = a; 
-                         pw[1] = b; 
-                         pw[2] = c; 
-                         pw[3] = d; 
-                         pw[4] = NOSQUARE; 
-   
-                         pb[0] = e; 
-                         pb[1] = NOSQUARE; 
-   
-                         if (kaabk_pctoindex (pw, pb, &i)) { 
-                                                         kaabk_indextopc (i, px, py); 
-                                                         kaabk_pctoindex (px, py, &j); 
-                                                         if (i != j) { 
-                                                                 err = TRUE; 
-                                                         } 
-                         } 
-   
-                 } 
-                 } 
-                 } 
-                 } 
-   
-         if ((a&1)==0) { 
-         } 
-         } 
-   
-         if (err) 
-                 printf ("> %s NOT passed\n",-  str );
 
-         else 
-                 printf ("> %s PASSED\n",-  str );
 
-         return !err; 
- } 
-   
- static void 
- kaabk_indextopc (index_t i, SQUARE *pw, SQUARE *pb) 
- { 
-         enum  { 
-                         BLOCK_B = 64, 
-                         BLOCK_A = BLOCK_B * MAX_AAINDEX 
-                 }; 
-         index_t a, b, c, r, x, y; 
-   
-         r = i; 
-         a  = r / BLOCK_A; 
-         r -= a * BLOCK_A; 
-   
-         b  = r / BLOCK_B; 
-         r -= b * BLOCK_B; 
-   
-         c  = r; 
-   
-         assert (- i  == (- a  *-  BLOCK_A  +-  b  *-  BLOCK_B  +-  c ));
 
-   
-         pw[0] = wksq [a]; 
-         pb[0] = bksq [a]; 
-   
-         x = aabase [b]; 
-         y = (b + 1) + x - (x * (127-x)/2); 
-   
-         pw[1] = (SQUARE) x; 
-         pw[2] = (SQUARE) y; 
-         pw[3] = (SQUARE) c; 
-         pw[4] = NOSQUARE; 
-   
-         pb[1] = NOSQUARE; 
-   
-         assert (- kaabk_pctoindex  (- pw ,-  pb , &- a ) &&-  a  ==-  i );
 
-   
-         return; 
- } 
-   
- static bool_t 
- kaabk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out) 
- { 
-         enum  {N_WHITE = 4, N_BLACK = 1}; 
-         enum  { 
-                         BLOCK_B = 64, 
-                         BLOCK_A = BLOCK_B * MAX_AAINDEX 
-                 }; 
-         SQUARE ws[MAX_LISTSIZE], bs[MAX_LISTSIZE]; 
-         index_t ki, ai; 
-         unsigned int ft; 
-         int i; 
-   
-         ft = flipt [inp_pb[0]] [inp_pw[0]]; 
-   
-   
-         for (i = 0; i < N_WHITE; i++) ws[i] = inp_pw[i]; ws[N_WHITE] = NOSQUARE; 
-         for (i = 0; i < N_BLACK; i++) bs[i] = inp_pb[i]; bs[N_BLACK] = NOSQUARE; 
-   
-         if ((ft & WE_FLAG) != 0) { 
-                 for (i = 0; i < N_WHITE; i++) ws[i] = flipWE (ws[i]); 
-                 for (i = 0; i < N_BLACK; i++) bs[i] = flipWE (bs[i]); 
-         } 
-   
-         if ((ft & NS_FLAG) != 0) { 
-                 for (i = 0; i < N_WHITE; i++) ws[i] = flipNS (ws[i]); 
-                 for (i = 0; i < N_BLACK; i++) bs[i] = flipNS (bs[i]); 
-         } 
-   
-         if ((ft & NW_SE_FLAG) != 0) { 
-                 for (i = 0; i < N_WHITE; i++) ws[i] = flipNW_SE (ws[i]); 
-                 for (i = 0; i < N_BLACK; i++) bs[i] = flipNW_SE (bs[i]); 
-         } 
-   
-         ki = kkidx [bs[0]] [ws[0]]; /* kkidx [black king] [white king] */ 
-         ai = aaidx [ws[1]] [ws[2]]; 
-   
-         if (IDX_is_empty(ki) || IDX_is_empty(ai)) { 
-                 *out = NOINDEX; 
-                 return FALSE; 
-         } 
-         *out = ki * BLOCK_A + ai * BLOCK_B + (index_t)ws[3]; 
-         return TRUE; 
- } 
-   
- /****************** End KAAB/K *************************************/ 
-   
- /********************** KABB/K ************************************/ 
-   
- static bool_t   test_kabbk (void); 
- static bool_t   kabbk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); 
- static void             kabbk_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
-   
- static bool_t 
- test_kabbk (void) 
- { 
-   
-         enum  {MAXPC = 16+1}; 
-         char            str[] = "kabbk"; 
-         SQUARE          a, b, c, d, e; 
-         SQUARE          pw[MAXPC], pb[MAXPC]; 
-         SQUARE          px[MAXPC], py[MAXPC]; 
-   
-         index_t         i, j; 
-         bool_t          err = FALSE; 
-   
-   
-         for (a = 0; a < 64; a++) { 
-                 for (b = 0; b < 64; b++) { 
-                 for (c = 0; c < 64; c++) { 
-                 for (d = 0; d < 64; d++) { 
-                 for (e = 0; e < 64; e++) { 
-   
-                         pw[0] = a; 
-                         pw[1] = b; 
-                         pw[2] = c; 
-                         pw[3] = d; 
-                         pw[4] = NOSQUARE; 
-   
-                         pb[0] = e; 
-                         pb[1] = NOSQUARE; 
-   
-                         if (kabbk_pctoindex (pw, pb, &i)) { 
-                                                         kabbk_indextopc (i, px, py); 
-                                                         kabbk_pctoindex (px, py, &j); 
-                                                         if (i != j) { 
-                                                                 err = TRUE; 
-                                                         } 
-                         } 
-   
-                 } 
-                 } 
-                 } 
-                 } 
-   
-         if ((a&1)==0) { 
-         } 
-         } 
-   
-         if (err) 
-                 printf ("> %s NOT passed\n",-  str );
 
-         else 
-                 printf ("> %s PASSED\n",-  str );
 
-         return !err; 
- } 
-   
- static void 
- kabbk_indextopc (index_t i, SQUARE *pw, SQUARE *pb) 
- { 
-         enum  { 
-                         BLOCK_B = 64, 
-                         BLOCK_A = BLOCK_B * MAX_AAINDEX 
-                 }; 
-         index_t a, b, c, r, x, y; 
-   
-         r = i; 
-         a  = r / BLOCK_A; 
-         r -= a * BLOCK_A; 
-   
-         b  = r / BLOCK_B; 
-         r -= b * BLOCK_B; 
-   
-         c  = r; 
-   
-         assert (- i  == (- a  *-  BLOCK_A  +-  b  *-  BLOCK_B  +-  c ));
 
-   
-         pw[0] = wksq [a]; 
-         pb[0] = bksq [a]; 
-   
-         x = aabase [b]; 
-         y = (b + 1) + x - (x * (127-x)/2); 
-   
-         pw[1] = (SQUARE) c; 
-         pw[2] = (SQUARE) x; 
-         pw[3] = (SQUARE) y; 
-         pw[4] = NOSQUARE; 
-   
-         pb[1] = NOSQUARE; 
-   
-         assert (- kabbk_pctoindex  (- pw ,-  pb , &- a ) &&-  a  ==-  i );
 
-   
-         return; 
- } 
-   
- static bool_t 
- kabbk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out) 
- { 
-         enum  {N_WHITE = 4, N_BLACK = 1}; 
-         enum  { 
-                         BLOCK_B = 64, 
-                         BLOCK_A = BLOCK_B * MAX_AAINDEX 
-                 }; 
-         SQUARE ws[MAX_LISTSIZE], bs[MAX_LISTSIZE]; 
-         index_t ki, ai; 
-         unsigned int ft; 
-         int i; 
-   
-         ft = flipt [inp_pb[0]] [inp_pw[0]]; 
-   
-   
-         for (i = 0; i < N_WHITE; i++) ws[i] = inp_pw[i]; ws[N_WHITE] = NOSQUARE; 
-         for (i = 0; i < N_BLACK; i++) bs[i] = inp_pb[i]; bs[N_BLACK] = NOSQUARE; 
-   
-         if ((ft & WE_FLAG) != 0) { 
-                 for (i = 0; i < N_WHITE; i++) ws[i] = flipWE (ws[i]); 
-                 for (i = 0; i < N_BLACK; i++) bs[i] = flipWE (bs[i]); 
-         } 
-   
-         if ((ft & NS_FLAG) != 0) { 
-                 for (i = 0; i < N_WHITE; i++) ws[i] = flipNS (ws[i]); 
-                 for (i = 0; i < N_BLACK; i++) bs[i] = flipNS (bs[i]); 
-         } 
-   
-         if ((ft & NW_SE_FLAG) != 0) { 
-                 for (i = 0; i < N_WHITE; i++) ws[i] = flipNW_SE (ws[i]); 
-                 for (i = 0; i < N_BLACK; i++) bs[i] = flipNW_SE (bs[i]); 
-         } 
-   
-         ki = kkidx [bs[0]] [ws[0]]; /* kkidx [black king] [white king] */ 
-         ai = aaidx [ws[2]] [ws[3]]; 
-   
-         if (IDX_is_empty(ki) || IDX_is_empty(ai)) { 
-                 *out = NOINDEX; 
-                 return FALSE; 
-         } 
-         *out = ki * BLOCK_A + ai * BLOCK_B + (index_t)ws[1]; 
-         return TRUE; 
- } 
-   
- /********************** End KABB/K *************************************/ 
-   
- /********************** init KAAA/K ************************************/ 
-   
- static index_t 
- aaa_getsubi (sq_t x, sq_t y, sq_t z); 
-   
- static sq_t             aaa_xyz [MAX_AAAINDEX] [3]; 
- static index_t          aaa_base [64]; 
-   
- static index_t 
- init_aaa (void) 
- /* modifies aaa_base[], aaa_xyz[][] */ 
- { 
-         index_t comb [64]; 
-         index_t accum; 
-         index_t a; 
-   
-         index_t idx; 
-         SQUARE x, y, z; 
-   
-         /* getting aaa_base */ 
-         comb [0] = 0; 
-         for (a = 1; a < 64; a++) { 
-                 comb [a] = a * (a-1) / 2; 
-         } 
-   
-         accum = 0; 
-         aaa_base [0] = accum; 
-         for (a = 0; a < (64-1); a++) { 
-                 accum += comb[a]; 
-                 aaa_base [a+1] = accum; 
-         } 
-   
-         assert ((- accum  +-  comb [63]) ==-  MAX_AAAINDEX );
 
-         /* end getting aaa_base */ 
-   
-   
-         /* initialize aaa_xyz [][] */ 
-         for (idx = 0; idx < MAX_AAAINDEX; idx++) { 
-                 IDX_set_empty (aaa_xyz[idx][0]); 
-                 IDX_set_empty (aaa_xyz[idx][1]); 
-                 IDX_set_empty (aaa_xyz[idx][2]); 
-         } 
-   
-         idx = 0; 
-         for (z = 0; z < 64; z++) { 
-                 for (y = 0; y < z; y++) { 
-                         for (x = 0; x < y; x++) { 
-   
-                                 assert (- idx  ==-  aaa_getsubi  (- x ,-  y ,-  z ));
 
-   
-                                 aaa_xyz [idx] [0] = x; 
-                                 aaa_xyz [idx] [1] = y; 
-                                 aaa_xyz [idx] [2] = z; 
-   
-                                 idx++; 
-                         } 
-                 } 
-         } 
-   
-   
-         return idx; 
- } 
-   
-   
- static index_t 
- aaa_getsubi (sq_t x, sq_t y, sq_t z) 
- /* uses aaa_base */ 
- { 
-         index_t calc_idx, base; 
-   
-         assert (- x  < 64 &&-  y  < 64 &&-  z  < 64);
 
-   
-         base = aaa_base[z]; 
-         calc_idx = (index_t)x + ((index_t)y - 1) * (index_t)y / 2 + base; 
-   
-         return calc_idx; 
- } 
-   
- /********************** KAAA/K ************************************/ 
-   
- static bool_t   test_kaaak (void); 
- static bool_t   kaaak_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); 
- static void             kaaak_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
-   
- static bool_t 
- test_kaaak (void) 
- { 
-   
-         enum  {MAXPC = 16+1}; 
-         char            str[] = "kaaak"; 
-         SQUARE          a, b, c, d, e; 
-         SQUARE          pw[MAXPC], pb[MAXPC]; 
-         SQUARE          px[MAXPC], py[MAXPC]; 
-   
-         index_t         i, j; 
-         bool_t          err = FALSE; 
-   
-   
-         for (a = 0; a < 64; a++) { 
-                 for (b = 0; b < 64; b++) { 
-                 for (c = 0; c < 64; c++) { 
-                 for (d = 0; d < 64; d++) { 
-                 for (e = 0; e < 64; e++) { 
-   
-                         pw[0] = a; 
-                         pw[1] = b; 
-                         pw[2] = c; 
-                         pw[3] = d; 
-                         pw[4] = NOSQUARE; 
-   
-                         pb[0] = e; 
-                         pb[1] = NOSQUARE; 
-   
-                         if (kaaak_pctoindex (pw, pb, &i)) { 
-                                                         kaaak_indextopc (i, px, py); 
-                                                         kaaak_pctoindex (px, py, &j); 
-                                                         if (i != j) { 
-                                                                 err = TRUE; 
-                                                         } 
-                         } 
-   
-                 } 
-                 } 
-                 } 
-                 } 
-   
-         if ((a&1)==0) { 
-         } 
-         } 
-   
-         if (err) 
-                 printf ("> %s NOT passed\n",-  str );
 
-         else 
-                 printf ("> %s PASSED\n",-  str );
 
-         return !err; 
- } 
-   
- static void 
- kaaak_indextopc (index_t i, SQUARE *pw, SQUARE *pb) 
- { 
-         enum  { 
-                         BLOCK_A = MAX_AAAINDEX 
-                 }; 
-         index_t a, b, r; 
-   
-         r = i; 
-         a  = r / BLOCK_A; 
-         r -= a * BLOCK_A; 
-   
-         b  = r; 
-   
-         assert (- i  == (- a  *-  BLOCK_A  +-  b ));
 
-   
-         pw[0] = wksq [a]; 
-         pb[0] = bksq [a]; 
-   
-         pw[1] = aaa_xyz [b] [0]; 
-         pw[2] = aaa_xyz [b] [1]; 
-         pw[3] = aaa_xyz [b] [2]; 
-         pw[4] = NOSQUARE; 
-   
-         pb[1] = NOSQUARE; 
-   
-         assert (- kaaak_pctoindex  (- pw ,-  pb , &- a ) &&-  a  ==-  i );
 
-   
-         return; 
- } 
-   
- static bool_t 
- kaaak_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out) 
- { 
-         enum  {N_WHITE = 4, N_BLACK = 1}; 
-         enum  { 
-                         BLOCK_A = MAX_AAAINDEX 
-                 }; 
-         SQUARE ws[MAX_LISTSIZE], bs[MAX_LISTSIZE]; 
-         index_t ki, ai; 
-         unsigned int ft; 
-         int i; 
-   
-         ft = flipt [inp_pb[0]] [inp_pw[0]]; 
-   
-   
-         for (i = 0; i < N_WHITE; i++) ws[i] = inp_pw[i]; ws[N_WHITE] = NOSQUARE; 
-         for (i = 0; i < N_BLACK; i++) bs[i] = inp_pb[i]; bs[N_BLACK] = NOSQUARE; 
-   
-         if ((ft & WE_FLAG) != 0) { 
-                 for (i = 0; i < N_WHITE; i++) ws[i] = flipWE (ws[i]); 
-                 for (i = 0; i < N_BLACK; i++) bs[i] = flipWE (bs[i]); 
-         } 
-   
-         if ((ft & NS_FLAG) != 0) { 
-                 for (i = 0; i < N_WHITE; i++) ws[i] = flipNS (ws[i]); 
-                 for (i = 0; i < N_BLACK; i++) bs[i] = flipNS (bs[i]); 
-         } 
-   
-         if ((ft & NW_SE_FLAG) != 0) { 
-                 for (i = 0; i < N_WHITE; i++) ws[i] = flipNW_SE (ws[i]); 
-                 for (i = 0; i < N_BLACK; i++) bs[i] = flipNW_SE (bs[i]); 
-         } 
-   
-   
-         { 
-                 SQUARE tmp; 
-                 if (ws[2] < ws[1]) { 
-             tmp = ws[1]; 
-             ws[1] = ws[2]; 
-             ws[2] = tmp; 
-                 } 
-                 if (ws[3] < ws[2]) { 
-             tmp = ws[2]; 
-             ws[2] = ws[3]; 
-             ws[3] = tmp; 
-                 } 
-                 if (ws[2] < ws[1]) { 
-             tmp = ws[1]; 
-             ws[1] = ws[2]; 
-             ws[2] = tmp; 
-                 } 
-         } 
-   
-         ki = kkidx [bs[0]] [ws[0]]; /* kkidx [black king] [white king] */ 
-   
- /*128 == (128 & (((ws[1]^ws[2])-1) | ((ws[1]^ws[3])-1) | ((ws[2]^ws[3])-1)) */ 
-   
-         if (ws[1] == ws[2] || ws[1] == ws[3] || ws[2] == ws[3]) { 
-                 *out = NOINDEX; 
-                 return FALSE; 
-         } 
-   
-         ai = aaa_getsubi ( ws[1], ws[2], ws[3] ); 
-   
-         if (IDX_is_empty(ki) || IDX_is_empty(ai)) { 
-                 *out = NOINDEX; 
-                 return FALSE; 
-         } 
-         *out = ki * BLOCK_A + ai; 
-         return TRUE; 
- } 
-   
- /****************** End KAAB/K *************************************/ 
-   
- /**********************  KAP/KB ************************************/ 
-   
- static bool_t   test_kapkb (void); 
- static bool_t   kapkb_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); 
- static void     kapkb_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
-   
- static bool_t 
- test_kapkb (void) 
- { 
-   
-         enum            {MAXPC = 16+1}; 
-         char            str[] = "kapkb"; 
-         SQUARE          a, b, c, d, e; 
-         SQUARE          pw[MAXPC], pb[MAXPC]; 
-         SQUARE          px[MAXPC], py[MAXPC]; 
-   
-         index_t         i, j; 
-         bool_t          err = FALSE; 
-   
-   
-         for (a = 0; a < 64; a++) { 
-                 for (b = 0; b < 64; b++) { 
-                 for (c = 0; c < 64; c++) { 
-                 for (d = 0; d < 64; d++) { 
-                 for (e = 0; e < 64; e++) { 
-   
-                         if (c <= H1 || c >= A8) 
-                                 continue; 
-   
-                         pw[0] = a; 
-                         pw[1] = b; 
-                         pw[2] = c; 
-                         pw[3] = NOSQUARE; 
-   
-                         pb[0] = e; 
-                         pb[1] = d; 
-                         pb[2] = NOSQUARE; 
-   
-                         if (kapkb_pctoindex (pw, pb, &i)) { 
-                                                         kapkb_indextopc (i, px, py); 
-                                                         kapkb_pctoindex (px, py, &j); 
-                                                         if (i != j) { 
-                                                                 err = TRUE; 
-                                                         } 
-                         } 
-   
-                 } 
-                 } 
-                 } 
-                 } 
-   
-         if ((a&1)==0) { 
-         } 
-         } 
-   
-         if (err) 
-                 printf ("> %s NOT passed\n",-  str );
 
-         else 
-                 printf ("> %s PASSED\n",-  str );
 
-         return !err; 
- } 
-   
- static void 
- kapkb_indextopc (index_t i, SQUARE *pw, SQUARE *pb) 
- { 
-         /*---------------------------------------------------------* 
-                 inverse work to make sure that the following is valid 
-                 index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d * BLOCK_D + e; 
-         *----------------------------------------------------------*/ 
-         enum  {B11100  = 7u << 2}; 
-         enum  {BLOCK_A = 64*64*64*64, BLOCK_B = 64*64*64, BLOCK_C = 64*64, BLOCK_D = 64}; 
-         index_t a, b, c, d, e, r; 
-         index_t x; 
-   
-         r = i; 
-         a  = r / BLOCK_A; 
-         r -= a * BLOCK_A; 
-         b  = r / BLOCK_B; 
-         r -= b * BLOCK_B; 
-         c  = r / BLOCK_C; 
-         r -= c * BLOCK_C; 
-         d  = r / BLOCK_D; 
-         r -= d * BLOCK_D; 
-         e  = r; 
-   
-         /* x is pslice */ 
-         x = a; 
-         x += x & B11100; /* get upper part and double it */ 
-         x += 8;          /* add extra row  */ 
-         x ^= 070;        /* flip NS */ 
-   
-         pw[0] = (SQUARE) b; 
-         pb[0] = (SQUARE) c; 
-         pw[1] = (SQUARE) d; 
-         pw[2] = (SQUARE) x; 
-         pw[3] = NOSQUARE; 
-         pb[1] = (SQUARE) e; 
-         pb[2] = NOSQUARE; 
-   
-         assert (- kapkb_pctoindex  (- pw ,-  pb , &- a ) &&-  a  ==-  i );
 
-   
-         return; 
- } 
-   
-   
- static bool_t 
- kapkb_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out) 
- { 
-         enum  {BLOCK_A = 64*64*64*64, BLOCK_B = 64*64*64, BLOCK_C = 64*64, BLOCK_D = 64}; 
-         index_t pslice; 
-         SQUARE sq; 
-         SQUARE pawn = pw[2]; 
-         SQUARE wa   = pw[1]; 
-         SQUARE wk   = pw[0]; 
-         SQUARE bk   = pb[0]; 
-         SQUARE ba   = pb[1]; 
-   
-         assert (- A2  <=-  pawn  &&-  pawn  <-  A8 );
 
-   
-         if (  !(A2 <= pawn && pawn < A8)) { 
-                 *out = NOINDEX; 
-                 return FALSE; 
-         } 
-   
-         if ((pawn & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */ 
-                 pawn = flipWE (pawn); 
-                 wk   = flipWE (wk); 
-                 bk   = flipWE (bk); 
-                 wa   = flipWE (wa); 
-                 ba   = flipWE (ba); 
-         } 
-   
-         sq = pawn; 
-         sq ^= 070; /* flipNS*/ 
-         sq -= 8;   /* down one row*/ 
-         pslice = (index_t) ((sq+(sq&3)) >> 1); 
-   
-         *out = pslice * BLOCK_A + (index_t)wk * BLOCK_B  + (index_t)bk * BLOCK_C + (index_t)wa * BLOCK_D + (index_t)ba; 
-   
-         return TRUE; 
- } 
- /********************** end KAP/KB ************************************/ 
-   
- /*************************  KAB/KP ************************************/ 
-   
- static bool_t   test_kabkp (void); 
- static bool_t   kabkp_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); 
- static void     kabkp_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
-   
- static bool_t 
- test_kabkp (void) 
- { 
-   
-         enum            {MAXPC = 16+1}; 
-         char            str[] = "kabkp"; 
-         SQUARE          a, b, c, d, e; 
-         SQUARE          pw[MAXPC], pb[MAXPC]; 
-         SQUARE          px[MAXPC], py[MAXPC]; 
-   
-         index_t         i, j; 
-         bool_t          err = FALSE; 
-   
-   
-         for (a = 0; a < 64; a++) { 
-                 for (b = 0; b < 64; b++) { 
-                 for (c = 0; c < 64; c++) { 
-                 for (d = 0; d < 64; d++) { 
-                 for (e = 0; e < 64; e++) { 
-   
-                         if (d <= H1 || d >= A8) 
-                                 continue; 
-   
-                         pw[0] = a; 
-                         pw[1] = b; 
-                         pw[2] = c; 
-                         pw[3] = NOSQUARE; 
-   
-                         pb[0] = e; 
-                         pb[1] = d; 
-                         pb[2] = NOSQUARE; 
-   
-                         if (kabkp_pctoindex (pw, pb, &i)) { 
-                                                         kabkp_indextopc (i, px, py); 
-                                                         kabkp_pctoindex (px, py, &j); 
-                                                         if (i != j) { 
-                                                                 err = TRUE; 
-                                                         } 
-                         } 
-   
-                 } 
-                 } 
-                 } 
-                 } 
-   
-         if ((a&1)==0) { 
-         } 
-         } 
-   
-         if (err) 
-                 printf ("> %s NOT passed\n",-  str );
 
-         else 
-                 printf ("> %s PASSED\n",-  str );
 
-         return !err; 
- } 
-   
- static void 
- kabkp_indextopc (index_t i, SQUARE *pw, SQUARE *pb) 
- { 
-         /*---------------------------------------------------------* 
-                 inverse work to make sure that the following is valid 
-                 index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d * BLOCK_D + e; 
-         *----------------------------------------------------------*/ 
-         enum  {B11100  = 7u << 2}; 
-         enum  {BLOCK_A = 64*64*64*64, BLOCK_B = 64*64*64, BLOCK_C = 64*64, BLOCK_D = 64}; 
-         index_t a, b, c, d, e, r; 
-         index_t x; 
-   
-         r = i; 
-         a  = r / BLOCK_A; 
-         r -= a * BLOCK_A; 
-         b  = r / BLOCK_B; 
-         r -= b * BLOCK_B; 
-         c  = r / BLOCK_C; 
-         r -= c * BLOCK_C; 
-         d  = r / BLOCK_D; 
-         r -= d * BLOCK_D; 
-         e  = r; 
-   
-         /* x is pslice */ 
-         x = a; 
-         x += x & B11100; /* get upper part and double it */ 
-         x += 8;          /* add extra row  */ 
-         /*x ^= 070;*/        /* do not flip NS */ 
-   
-         pw[0] = (SQUARE) b; 
-         pb[0] = (SQUARE) c; 
-         pw[1] = (SQUARE) d; 
-         pw[2] = (SQUARE) e; 
-         pw[3] = NOSQUARE; 
-         pb[1] = (SQUARE) x; 
-         pb[2] = NOSQUARE; 
-   
-         assert (- kabkp_pctoindex  (- pw ,-  pb , &- a ) &&-  a  ==-  i );
 
-   
-         return; 
- } 
-   
-   
- static bool_t 
- kabkp_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out) 
- { 
-         enum  {BLOCK_A = 64*64*64*64, BLOCK_B = 64*64*64, BLOCK_C = 64*64, BLOCK_D = 64}; 
-         index_t pslice; 
-         SQUARE sq; 
-         SQUARE pawn = pb[1]; 
-         SQUARE wa   = pw[1]; 
-         SQUARE wk   = pw[0]; 
-         SQUARE bk   = pb[0]; 
-         SQUARE wb   = pw[2]; 
-   
-         assert (- A2  <=-  pawn  &&-  pawn  <-  A8 );
 
-   
-         if (  !(A2 <= pawn && pawn < A8)) { 
-                 *out = NOINDEX; 
-                 return FALSE; 
-         } 
-   
-         if ((pawn & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */ 
-                 pawn = flipWE (pawn); 
-                 wk   = flipWE (wk); 
-                 bk   = flipWE (bk); 
-                 wa   = flipWE (wa); 
-                 wb   = flipWE (wb); 
-         } 
-   
-         sq = pawn; 
-         /*sq ^= 070;*/ /* do not flipNS*/ 
-         sq -= 8;   /* down one row*/ 
-         pslice = (index_t) ((sq+(sq&3)) >> 1); 
-   
-         *out = pslice * BLOCK_A + (index_t)wk * BLOCK_B  + (index_t)bk * BLOCK_C + (index_t)wa * BLOCK_D + (index_t)wb; 
-   
-         return TRUE; 
- } 
- /********************** end KAB/KP ************************************/ 
-   
-   
- static void 
- kpk_indextopc (index_t i, SQUARE *pw, SQUARE *pb) 
- { 
-         /*---------------------------------------------------------* 
-                 inverse work to make sure that the following is valid 
-                 index = a * BLOCK_A + b * BLOCK_B + c; 
-         *----------------------------------------------------------*/ 
-         enum  {B11100  = 7u << 2}; 
-         enum  {BLOCK_A = 64*64, BLOCK_B = 64}; 
-         index_t a, b, c, r; 
-         index_t x; 
-   
-         r = i; 
-         a  = r / BLOCK_A; 
-         r -= a * BLOCK_A; 
-         b  = r / BLOCK_B; 
-         r -= b * BLOCK_B; 
-         c  = r; 
-   
-         /* x is pslice */ 
-         x = a; 
-         x += x & B11100; /* get upper part and double it */ 
-         x += 8;          /* add extra row  */ 
-         x ^= 070;        /* flip NS */ 
-   
-         pw[1] = (SQUARE) x; 
-         pw[0] = (SQUARE) b; 
-         pb[0] = (SQUARE) c; 
-   
-         pw[2] = NOSQUARE; 
-         pb[1] = NOSQUARE; 
-   
-         assert (- kpk_pctoindex  (- pw ,-  pb , &- a ) &&-  a  ==-  i );
 
-   
-         return; 
- } 
-   
-   
- static bool_t 
- kpk_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out) 
- { 
-         enum  {BLOCK_A = 64*64, BLOCK_B = 64}; 
-         index_t pslice; 
-         SQUARE sq; 
-         SQUARE pawn = pw[1]; 
-         SQUARE wk   = pw[0]; 
-         SQUARE bk   = pb[0]; 
-   
-         #ifdef DEBUG 
-         if (  !(A2 <= pawn && pawn < A8)) { 
-                 SQ_CONTENT wp[MAX_LISTSIZE], bp[MAX_LISTSIZE]; 
-         bp [0] = wp[0] = KING; 
-         wp[1] = PAWN; 
-         wp[2] = bp[1] = NOPIECE; 
-                 output_state (0, pw, pb, wp, bp); 
-         } 
-         #endif 
-   
-         assert (- A2  <=-  pawn  &&-  pawn  <-  A8 );
 
-   
-         if (  !(A2 <= pawn && pawn < A8)) { 
-                 *out = NOINDEX; 
-                 return FALSE; 
-         } 
-   
-         if ((pawn & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */ 
-                 pawn = flipWE (pawn); 
-                 wk   = flipWE (wk); 
-                 bk   = flipWE (bk); 
-         } 
-   
-         sq = pawn; 
-         sq ^= 070; /* flipNS*/ 
-         sq -= 8;   /* down one row*/ 
-         pslice = (index_t) ((sq+(sq&3)) >> 1); 
-   
-         *out = pslice * BLOCK_A + (index_t)wk * BLOCK_B  + (index_t)bk; 
-   
-         return TRUE; 
- } 
-   
-   
- /**********************  KPP/K ************************************/ 
-   
- static bool_t   test_kppk (void); 
- static bool_t   kppk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); 
- static void             kppk_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
-   
- static bool_t 
- test_kppk (void) 
- { 
-   
-         enum            {MAXPC = 16+1}; 
-         char            str[] = "kppk"; 
-         SQUARE          a, b, c, d; 
-         SQUARE          pw[MAXPC], pb[MAXPC]; 
-         SQUARE          px[MAXPC], py[MAXPC]; 
-   
-         index_t         i, j; 
-         bool_t          err = FALSE; 
-   
-   
-         for (b = 0; b < 64; b++) { 
-                 for (c = 0; c < 64; c++) { 
-                         sq_t anchor1, anchor2, loosen1, loosen2; 
-                         if (c <= H1 || c >= A8) 
-                                 continue; 
-                         if (b <= H1 || b >= A8) 
-                                 continue; 
-   
-                         pp_putanchorfirst (b, c, &anchor1, &loosen1); 
-                         pp_putanchorfirst (c, b, &anchor2, &loosen2); 
-                         if (!(anchor1 == anchor2 && loosen1 == loosen2)) { 
-                                 printf ("Output depends on input in pp_outanchorfirst()\n input:%u, %u\n",(unsigned)- b ,(unsigned)- c );
 
-                                 fatal_error(); 
-                         } 
-                 } 
-         } 
-   
-   
-         for (a = 0; a < 64; a++) { 
-                 for (b = 0; b < 64; b++) { 
-                 for (c = 0; c < 64; c++) { 
-                 for (d = 0; d < 64; d++) { 
-   
-   
-                         if (c <= H1 || c >= A8) 
-                                 continue; 
-                         if (b <= H1 || b >= A8) 
-                                 continue; 
-   
-   
-                         pw[0] = a; 
-                         pw[1] = b; 
-                         pw[2] = c; 
-                         pw[3] = NOSQUARE; 
-   
-                         pb[0] = d; 
-                         pb[1] = NOSQUARE; 
-   
-                         if (kppk_pctoindex (pw, pb, &i)) { 
-                                                         kppk_indextopc (i, px, py); 
-                                                         kppk_pctoindex (px, py, &j); 
-                                                         if (i != j) { 
-                                                                 err = TRUE; 
-                                                         } 
-                         } 
-   
-   
-                 } 
-                 } 
-                 } 
-   
-         if ((a&1)==0) { 
-         } 
-         } 
-   
-         if (err) 
-                 printf ("> %s NOT passed\n",-  str );
 
-         else 
-                 printf ("> %s PASSED\n",-  str );
 
-         return !err; 
- } 
-   
- static void 
- kppk_indextopc (index_t i, SQUARE *pw, SQUARE *pb) 
- { 
-         /*---------------------------------------------------------* 
-                 inverse work to make sure that the following is valid 
-                 index = a * BLOCK_A + b * BLOCK_B + c; 
-         *----------------------------------------------------------*/ 
-         enum  {B11100  = 7u << 2}; 
-         enum  {BLOCK_A = 64*64, BLOCK_B = 64}; 
-         index_t a, b, c, r; 
-         index_t m, n; 
-   
-         r = i; 
-         a  = r / BLOCK_A; 
-         r -= a * BLOCK_A; 
-         b  = r / BLOCK_B; 
-         r -= b * BLOCK_B; 
-         c  = r; 
-   
-         m = pp_hi24 [a]; 
-         n = pp_lo48 [a]; 
-   
-         pw[0] = (SQUARE) b; 
-         pb[0] = (SQUARE) c; 
-         pb[1] = NOSQUARE; 
-   
-         pw[1] = pidx24_to_wsq (m); 
-         pw[2] = pidx48_to_wsq (n); 
-   
-         pw[3] = NOSQUARE; 
-   
-   
-         assert (- A2  <=-  pw [1] &&-  pw [1] <-  A8 );
 
-         assert (- A2  <=-  pw [2] &&-  pw [2] <-  A8 );
 
-   
- #ifdef DEBUG 
-         if (!(kppk_pctoindex (pw, pb, &a) && a == i)) { 
-                 pc_t wp[] = {KING, PAWN, PAWN, NOPIECE}; 
-                 pc_t bp[] = {KING, NOPIECE}; 
-                 printf("Indexes not matching: input:%d, output:%d\n",-  i ,-  a );
 
-                 print_pos (pw, pb, wp, bp); 
-         } 
- #endif 
-   
-         assert (- kppk_pctoindex  (- pw ,-  pb , &- a ) &&-  a  ==-  i );
 
-   
-         return; 
- } 
-   
-   
- static bool_t 
- kppk_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out) 
- { 
-         enum  {BLOCK_A = 64*64, BLOCK_B = 64}; 
-         index_t pp_slice; 
-         SQUARE anchor, loosen; 
-   
-         SQUARE wk     = pw[0]; 
-         SQUARE pawn_a = pw[1]; 
-         SQUARE pawn_b = pw[2]; 
-         SQUARE bk     = pb[0]; 
-         index_t i, j; 
-   
-         #ifdef DEBUG 
-         if (!(A2 <= pawn_a && pawn_a < A8)) { 
-                 printf ("\n\nsquare of pawn_a: %s\n",-  Square_str [- pawn_a ]);
 
-                 printf(" wk %s\n p1 %s\n p2 %s\n bk %s\n" 
-                         , Square_str[wk] 
-                         , Square_str[pawn_a] 
-                         , Square_str[pawn_b] 
-                         , Square_str[bk] 
-                         ); 
-         } 
-         #endif 
-   
-         assert (- A2  <=-  pawn_a  &&-  pawn_a  <-  A8 );
 
-         assert (- A2  <=-  pawn_b  &&-  pawn_b  <-  A8 );
 
-   
-         pp_putanchorfirst (pawn_a, pawn_b, &anchor, &loosen); 
-   
-         if ((anchor & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */ 
-                 anchor = flipWE (anchor); 
-                 loosen = flipWE (loosen); 
-                 wk     = flipWE (wk); 
-                 bk     = flipWE (bk); 
-         } 
-   
-         i = wsq_to_pidx24 (anchor); 
-         j = wsq_to_pidx48 (loosen); 
-   
-         pp_slice = ppidx [i] [j]; 
-   
-         if (IDX_is_empty(pp_slice)) { 
-                 *out = NOINDEX; 
-                 return FALSE; 
-         } 
-   
-         assert (- pp_slice  <-  MAX_PPINDEX  );
 
-   
-         *out = pp_slice * BLOCK_A + (index_t)wk * BLOCK_B  + (index_t)bk; 
-   
-         return TRUE; 
- } 
- /****************** end  KPP/K ************************************/ 
-   
- static void 
- kakp_indextopc (index_t i, SQUARE *pw, SQUARE *pb) 
- { 
-         /*---------------------------------------------------------* 
-                 inverse work to make sure that the following is valid 
-                 index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d; 
-         *----------------------------------------------------------*/ 
-         enum  {B11100  = 7u << 2}; 
-         enum  {BLOCK_A = 64*64*64, BLOCK_B = 64*64, BLOCK_C = 64}; 
-         index_t a, b, c, d, r; 
-         index_t x; 
-   
-         r = i; 
-         a  = r / BLOCK_A; 
-         r -= a * BLOCK_A; 
-         b  = r / BLOCK_B; 
-         r -= b * BLOCK_B; 
-         c  = r / BLOCK_C; 
-         r -= c * BLOCK_C; 
-         d  = r; 
-   
-         /* x is pslice */ 
-         x = a; 
-         x += x & B11100; /* get upper part and double it */ 
-         x += 8;          /* add extra row  */ 
- /*      x ^= 070;   */     /* flip NS */ 
-   
-         pw[0] = (SQUARE) b; 
-         pb[0] = (SQUARE) c; 
-         pw[1] = (SQUARE) d; 
-         pb[1] = (SQUARE) x; 
-         pw[2] = NOSQUARE; 
-         pb[2] = NOSQUARE; 
-   
-         assert (- kakp_pctoindex  (- pw ,-  pb , &- a ) &&-  a  ==-  i );
 
-   
-         return; 
- } 
-   
-   
- static bool_t 
- kakp_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out) 
- { 
-         enum  {BLOCK_A = 64*64*64, BLOCK_B = 64*64, BLOCK_C = 64}; 
-         index_t pslice; 
-         SQUARE sq; 
-         SQUARE pawn = pb[1]; 
-         SQUARE wa   = pw[1]; 
-         SQUARE wk   = pw[0]; 
-         SQUARE bk   = pb[0]; 
-   
-         assert (- A2  <=-  pawn  &&-  pawn  <-  A8 );
 
-   
-         if (  !(A2 <= pawn && pawn < A8)) { 
-                 *out = NOINDEX; 
-                 return FALSE; 
-         } 
-   
-         if ((pawn & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */ 
-                 pawn = flipWE (pawn); 
-                 wk   = flipWE (wk); 
-                 bk   = flipWE (bk); 
-                 wa   = flipWE (wa); 
-         } 
-   
-         sq = pawn; 
-         /*sq ^= 070;*/ /* flipNS*/ 
-         sq -= 8;   /* down one row*/ 
-         pslice = (index_t) ((sq+(sq&3)) >> 1); 
-   
-         *out = pslice * BLOCK_A + (index_t)wk * BLOCK_B  + (index_t)bk * BLOCK_C + (index_t)wa; 
-   
-         return TRUE; 
- } 
-   
-   
- static void 
- kapk_indextopc (index_t i, SQUARE *pw, SQUARE *pb) 
- { 
-         /*---------------------------------------------------------* 
-                 inverse work to make sure that the following is valid 
-                 index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d; 
-         *----------------------------------------------------------*/ 
-         enum  {B11100  = 7u << 2}; 
-         enum  {BLOCK_A = 64*64*64, BLOCK_B = 64*64, BLOCK_C = 64}; 
-         index_t a, b, c, d, r; 
-         index_t x; 
-   
-         r = i; 
-         a  = r / BLOCK_A; 
-         r -= a * BLOCK_A; 
-         b  = r / BLOCK_B; 
-         r -= b * BLOCK_B; 
-         c  = r / BLOCK_C; 
-         r -= c * BLOCK_C; 
-         d  = r; 
-   
-         /* x is pslice */ 
-         x = a; 
-         x += x & B11100; /* get upper part and double it */ 
-         x += 8;          /* add extra row  */ 
-         x ^= 070;        /* flip NS */ 
-   
-         pw[0] = (SQUARE) b; 
-         pb[0] = (SQUARE) c; 
-         pw[1] = (SQUARE) d; 
-         pw[2] = (SQUARE) x; 
-         pw[3] = NOSQUARE; 
-         pb[1] = NOSQUARE; 
-   
-         assert (- kapk_pctoindex  (- pw ,-  pb , &- a ) &&-  a  ==-  i );
 
-   
-         return; 
- } 
-   
-   
- static bool_t 
- kapk_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out) 
- { 
-         enum  {BLOCK_A = 64*64*64, BLOCK_B = 64*64, BLOCK_C = 64}; 
-         index_t pslice; 
-         SQUARE sq; 
-         SQUARE pawn = pw[2]; 
-         SQUARE wa   = pw[1]; 
-         SQUARE wk   = pw[0]; 
-         SQUARE bk   = pb[0]; 
-   
-         assert (- A2  <=-  pawn  &&-  pawn  <-  A8 );
 
-   
-         if (  !(A2 <= pawn && pawn < A8)) { 
-                 *out = NOINDEX; 
-                 return FALSE; 
-         } 
-   
-         if ((pawn & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */ 
-                 pawn = flipWE (pawn); 
-                 wk   = flipWE (wk); 
-                 bk   = flipWE (bk); 
-                 wa   = flipWE (wa); 
-         } 
-   
-         sq = pawn; 
-         sq ^= 070; /* flipNS*/ 
-         sq -= 8;   /* down one row*/ 
-         pslice = (index_t) ((sq+(sq&3)) >> 1); 
-   
-         *out = pslice * BLOCK_A + (index_t)wk * BLOCK_B  + (index_t)bk * BLOCK_C + (index_t)wa; 
-   
-         return TRUE; 
- } 
-   
-   
- static void 
- kaak_indextopc (index_t i, SQUARE *pw, SQUARE *pb) 
- { 
-         enum  {BLOCK_A = MAX_AAINDEX}; 
-         index_t a, b, r, x, y; 
-   
-         r = i; 
-         a  = r / BLOCK_A; 
-         r -= a * BLOCK_A; 
-         b  = r; 
-   
-         assert (- i  == (- a  *-  BLOCK_A  +-  b ));
 
-   
-         pw[0] = wksq [a]; 
-         pb[0] = bksq [a]; 
-   
-         x = aabase [b]; 
-         y = (b + 1) + x - (x * (127-x)/2); 
-   
-         pw[1] = (SQUARE) x; 
-         pw[2] = (SQUARE) y; 
-         pw[3] = NOSQUARE; 
-   
-         pb[1] = NOSQUARE; 
-   
-         assert (- kaak_pctoindex  (- pw ,-  pb , &- a ) &&-  a  ==-  i );
 
-   
-         return; 
- } 
-   
-   
- static bool_t 
- kaak_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out) 
- { 
-         enum  {N_WHITE = 3, N_BLACK = 1}; 
-         enum  {BLOCK_A = MAX_AAINDEX}; 
-         SQUARE ws[MAX_LISTSIZE], bs[MAX_LISTSIZE]; 
-         index_t ki, ai; 
-         unsigned int ft; 
-         SQUARE i; 
-   
-         ft = flipt [inp_pb[0]] [inp_pw[0]]; 
-   
-   
-     for (i = 0; i < N_WHITE; i++) ws[i] = inp_pw[i]; 
-     ws[N_WHITE] = NOSQUARE; 
-     for (i = 0; i < N_BLACK; i++) bs[i] = inp_pb[i]; 
-     bs[N_BLACK] = NOSQUARE; 
-   
-         if ((ft & WE_FLAG) != 0) { 
-                 for (i = 0; i < N_WHITE; i++) ws[i] = flipWE (ws[i]); 
-                 for (i = 0; i < N_BLACK; i++) bs[i] = flipWE (bs[i]); 
-         } 
-   
-         if ((ft & NS_FLAG) != 0) { 
-                 for (i = 0; i < N_WHITE; i++) ws[i] = flipNS (ws[i]); 
-                 for (i = 0; i < N_BLACK; i++) bs[i] = flipNS (bs[i]); 
-         } 
-   
-         if ((ft & NW_SE_FLAG) != 0) { 
-                 for (i = 0; i < N_WHITE; i++) ws[i] = flipNW_SE (ws[i]); 
-                 for (i = 0; i < N_BLACK; i++) bs[i] = flipNW_SE (bs[i]); 
-         } 
-   
-         ki = kkidx [bs[0]] [ws[0]]; /* kkidx [black king] [white king] */ 
-         ai = (index_t) aaidx [ws[1]] [ws[2]]; 
-   
-         if (IDX_is_empty(ki) || IDX_is_empty(ai)) { 
-                 *out = NOINDEX; 
-                 return FALSE; 
-         } 
-         *out = ki * BLOCK_A + ai; 
-         return TRUE; 
- } 
-   
- /**********************  KPP/KA ************************************/ 
-   
- static bool_t   test_kppka (void); 
- static bool_t   kppka_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); 
- static void             kppka_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
-   
- static bool_t 
- test_kppka (void) 
- { 
-   
-         enum            {MAXPC = 16+1}; 
-         char            str[] = "kppka"; 
-         SQUARE          a, b, c, d, e; 
-         SQUARE          pw[MAXPC], pb[MAXPC]; 
-         SQUARE          px[MAXPC], py[MAXPC]; 
-   
-         index_t         i, j; 
-         bool_t          err = FALSE; 
-   
-   
-         for (a = 0; a < 64; a++) { 
-                 for (b = 0; b < 64; b++) { 
-                 for (c = 0; c < 64; c++) { 
-                 for (d = 0; d < 64; d++) { 
-                 for (e = 0; e < 64; e++) { 
-   
-                         if (c <= H1 || c >= A8) 
-                                 continue; 
-                         if (b <= H1 || b >= A8) 
-                                 continue; 
-   
-   
-                         pw[0] = a; 
-                         pw[1] = b; 
-                         pw[2] = c; 
-                         pw[3] = NOSQUARE; 
-   
-                         pb[0] = e; 
-                         pb[1] = d; 
-                         pb[2] = NOSQUARE; 
-   
-                         if (kppka_pctoindex (pw, pb, &i)) { 
-                                                         kppka_indextopc (i, px, py); 
-                                                         kppka_pctoindex (px, py, &j); 
-                                                         if (i != j) { 
-                                                                 err = TRUE; 
-                                                         } 
-                         } 
-   
-                 } 
-                 } 
-                 } 
-                 } 
-   
-         if ((a&1)==0) { 
-         } 
-         } 
-   
-         if (err) 
-                 printf ("> %s NOT passed\n",-  str );
 
-         else 
-                 printf ("> %s PASSED\n",-  str );
 
-         return !err; 
- } 
-   
-   
- static void 
- kppka_indextopc (index_t i, SQUARE *pw, SQUARE *pb) 
- { 
-         /*---------------------------------------------------------* 
-                 inverse work to make sure that the following is valid 
-                 index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d; 
-         *----------------------------------------------------------*/ 
-   
-         enum  {BLOCK_A = 64*64*64, BLOCK_B = 64*64, BLOCK_C = 64}; 
-         index_t a, b, c, d, r; 
-         index_t m, n; 
-   
-         r = i; 
-         a  = r / BLOCK_A; 
-         r -= a * BLOCK_A; 
-         b  = r / BLOCK_B; 
-         r -= b * BLOCK_B; 
-         c  = r / BLOCK_C; 
-         r -= c * BLOCK_C; 
-         d  = r; 
-   
-         m = pp_hi24 [a]; 
-         n = pp_lo48 [a]; 
-   
-         pw[0] = (SQUARE) b; 
-         pw[1] = pidx24_to_wsq (m); 
-         pw[2] = pidx48_to_wsq (n); 
-         pw[3] = NOSQUARE; 
-   
-         pb[0] = (SQUARE) c; 
-         pb[1] = (SQUARE) d; 
-         pb[2] = NOSQUARE; 
-   
-   
-         assert (- A2  <=-  pw [1] &&-  pw [1] <-  A8 );
 
-         assert (- A2  <=-  pw [2] &&-  pw [2] <-  A8 );
 
-         assert (- kppka_pctoindex  (- pw ,-  pb , &- a ) &&-  a  ==-  i );
 
-   
-         return; 
- } 
-   
-   
- static bool_t 
- kppka_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out) 
- { 
-         enum  {BLOCK_A = 64*64*64, BLOCK_B = 64*64, BLOCK_C = 64}; 
-         index_t pp_slice; 
-         index_t i, j; 
-   
-         SQUARE anchor, loosen; 
-   
-         SQUARE wk     = pw[0]; 
-         SQUARE pawn_a = pw[1]; 
-         SQUARE pawn_b = pw[2]; 
-         SQUARE bk     = pb[0]; 
-         SQUARE ba         = pb[1]; 
-   
-   
-         assert (- A2  <=-  pawn_a  &&-  pawn_a  <-  A8 );
 
-         assert (- A2  <=-  pawn_b  &&-  pawn_b  <-  A8 );
 
-   
-         pp_putanchorfirst (pawn_a, pawn_b, &anchor, &loosen); 
-   
-         if ((anchor & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */ 
-                 anchor = flipWE (anchor); 
-                 loosen = flipWE (loosen); 
-                 wk     = flipWE (wk); 
-                 bk     = flipWE (bk); 
-                 ba         = flipWE (ba); 
-         } 
-   
-         i = wsq_to_pidx24 (anchor); 
-         j = wsq_to_pidx48 (loosen); 
-   
-         pp_slice = ppidx [i] [j]; 
-   
-         if (IDX_is_empty(pp_slice)) { 
-                 *out = NOINDEX; 
-                 return FALSE; 
-         } 
-   
-         assert (- pp_slice  <-  MAX_PPINDEX  );
 
-   
-         *out = pp_slice * (index_t)BLOCK_A + (index_t)wk * (index_t)BLOCK_B  + (index_t)bk * (index_t)BLOCK_C + (index_t)ba; 
-   
-         return TRUE; 
- } 
-   
- /********************** end KPP/KA ************************************/ 
-   
- /**********************  KAPP/K ************************************/ 
-   
- static bool_t   test_kappk (void); 
- static bool_t   kappk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); 
- static void             kappk_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
-   
- static bool_t 
- test_kappk (void) 
- { 
-   
-         enum            {MAXPC = 16+1}; 
-         char            str[] = "kappk"; 
-         SQUARE          a, b, c, d, e; 
-         SQUARE          pw[MAXPC], pb[MAXPC]; 
-         SQUARE          px[MAXPC], py[MAXPC]; 
-   
-         index_t         i, j; 
-         bool_t          err = FALSE; 
-   
-   
-         for (a = 0; a < 64; a++) { 
-                 for (b = 0; b < 64; b++) { 
-                 for (c = 0; c < 64; c++) { 
-                 for (d = 0; d < 64; d++) { 
-                 for (e = 0; e < 64; e++) { 
-   
-                         if (c <= H1 || c >= A8) 
-                                 continue; 
-                         if (b <= H1 || b >= A8) 
-                                 continue; 
-   
-   
-                         pw[0] = a; 
-                         pw[1] = d; 
-                         pw[2] = b; 
-                         pw[3] = c; 
-                         pw[4] = NOSQUARE; 
-   
-                         pb[0] = e; 
-                         pb[1] = NOSQUARE; 
-   
-                         if (kappk_pctoindex (pw, pb, &i)) { 
-                                                         kappk_indextopc (i, px, py); 
-                                                         kappk_pctoindex (px, py, &j); 
-                                                         if (i != j) { 
-                                                                 err = TRUE; 
-                                                         } 
-                         } 
-   
-                 } 
-                 } 
-                 } 
-                 } 
-   
-         if ((a&1)==0) { 
-         } 
-         } 
-   
-         if (err) 
-                 printf ("> %s NOT passed\n",-  str );
 
-         else 
-                 printf ("> %s PASSED\n",-  str );
 
-         return !err; 
- } 
-   
-   
- static void 
- kappk_indextopc (index_t i, SQUARE *pw, SQUARE *pb) 
- { 
-         /*---------------------------------------------------------* 
-                 inverse work to make sure that the following is valid 
-                 index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d; 
-         *----------------------------------------------------------*/ 
-   
-         enum  {BLOCK_A = 64*64*64, BLOCK_B = 64*64, BLOCK_C = 64}; 
-         index_t a, b, c, d, r; 
-         index_t m, n; 
-   
-         r = i; 
-         a  = r / BLOCK_A; 
-         r -= a * BLOCK_A; 
-         b  = r / BLOCK_B; 
-         r -= b * BLOCK_B; 
-         c  = r / BLOCK_C; 
-         r -= c * BLOCK_C; 
-         d  = r; 
-   
-         m = pp_hi24 [a]; 
-         n = pp_lo48 [a]; 
-   
-         pw[0] = (SQUARE) b; 
-         pw[1] = (SQUARE) d; 
-         pw[2] = pidx24_to_wsq (m); 
-         pw[3] = pidx48_to_wsq (n); 
-         pw[4] = NOSQUARE; 
-   
-         pb[0] = (SQUARE) c; 
-         pb[1] = NOSQUARE; 
-   
-   
-         assert (- A2  <=-  pw [3] &&-  pw [3] <-  A8 );
 
-         assert (- A2  <=-  pw [2] &&-  pw [2] <-  A8 );
 
-         assert (- kappk_pctoindex  (- pw ,-  pb , &- a ) &&-  a  ==-  i );
 
-   
-         return; 
- } 
-   
-   
- static bool_t 
- kappk_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out) 
- { 
-         enum  {BLOCK_A = 64*64*64, BLOCK_B = 64*64, BLOCK_C = 64}; 
-         index_t pp_slice; 
-         SQUARE anchor, loosen; 
-   
-         SQUARE wk     = pw[0]; 
-         SQUARE wa         = pw[1]; 
-         SQUARE pawn_a = pw[2]; 
-         SQUARE pawn_b = pw[3]; 
-         SQUARE bk     = pb[0]; 
-   
-         index_t i, j; 
-   
-         assert (- A2  <=-  pawn_a  &&-  pawn_a  <-  A8 );
 
-         assert (- A2  <=-  pawn_b  &&-  pawn_b  <-  A8 );
 
-   
-         pp_putanchorfirst (pawn_a, pawn_b, &anchor, &loosen); 
-   
-         if ((anchor & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */ 
-                 anchor = flipWE (anchor); 
-                 loosen = flipWE (loosen); 
-                 wk     = flipWE (wk); 
-                 bk     = flipWE (bk); 
-                 wa         = flipWE (wa); 
-         } 
-   
-         i = wsq_to_pidx24 (anchor); 
-         j = wsq_to_pidx48 (loosen); 
-   
-         pp_slice = ppidx [i] [j]; 
-   
-         if (IDX_is_empty(pp_slice)) { 
-                 *out = NOINDEX; 
-                 return FALSE; 
-         } 
-   
-         assert (- pp_slice  <-  MAX_PPINDEX  );
 
-   
-         *out = pp_slice * (index_t)BLOCK_A + (index_t)wk * (index_t)BLOCK_B  + (index_t)bk * (index_t)BLOCK_C + (index_t)wa; 
-   
-         return TRUE; 
- } 
-   
- /********************** end KAPP/K ************************************/ 
-   
- /**********************  KAPP/K ************************************/ 
-   
- static bool_t   test_kapkp (void); 
- static bool_t   kapkp_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); 
- static void             kapkp_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
-   
- static bool_t 
- test_kapkp (void) 
- { 
-   
-         enum            {MAXPC = 16+1}; 
-         char            str[] = "kapkp"; 
-         SQUARE          a, b, c, d, e; 
-         SQUARE          pw[MAXPC], pb[MAXPC]; 
-         SQUARE          px[MAXPC], py[MAXPC]; 
-   
-         index_t         i, j; 
-         bool_t          err = FALSE; 
-   
-   
-         for (a = 0; a < 64; a++) { 
-                 for (b = 0; b < 64; b++) { 
-                 for (c = 0; c < 64; c++) { 
-                 for (d = 0; d < 64; d++) { 
-                 for (e = 0; e < 64; e++) { 
-   
-                         if (c <= H1 || c >= A8) 
-                                 continue; 
-                         if (b <= H1 || b >= A8) 
-                                 continue; 
-   
-   
-                         pw[0] = a; 
-                         pw[1] = d; 
-                         pw[2] = b; 
-                         pw[3] = NOSQUARE; 
-   
-                         pb[0] = e; 
-                         pb[1] = c; 
-                         pb[2] = NOSQUARE; 
-   
-                         if (kapkp_pctoindex (pw, pb, &i)) { 
-                                                         kapkp_indextopc (i, px, py); 
-                                                         kapkp_pctoindex (px, py, &j); 
-                                                         if (i != j) { 
-                                                                 err = TRUE; 
-                                                         } 
-                         } 
-   
-                 } 
-                 } 
-                 } 
-                 } 
-   
-         if ((a&1)==0) { 
-         } 
-         } 
-   
-         if (err) 
-                 printf ("> %s NOT passed\n",-  str );
 
-         else 
-                 printf ("> %s PASSED\n",-  str );
 
-         return !err; 
- } 
-   
-   
- static bool_t 
- kapkp_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out) 
- { 
-         enum  {BLOCK_A = 64*64*64, BLOCK_B = 64*64, BLOCK_C = 64}; 
-         index_t pp_slice; 
-         SQUARE anchor, loosen; 
-   
-         SQUARE wk     = pw[0]; 
-         SQUARE wa         = pw[1]; 
-         SQUARE pawn_a = pw[2]; 
-         SQUARE bk     = pb[0]; 
-         SQUARE pawn_b = pb[1]; 
-         index_t m, n; 
-   
-         assert (- A2  <=-  pawn_a  &&-  pawn_a  <-  A8 );
 
-         assert (- A2  <=-  pawn_b  &&-  pawn_b  <-  A8 );
 
-         assert (- pw [3] ==-  NOSQUARE  &&-  pb [2] ==-  NOSQUARE );
 
-   
-         anchor = pawn_a; 
-         loosen = pawn_b; 
-   
-         if ((anchor & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */ 
-                 anchor = flipWE (anchor); 
-                 loosen = flipWE (loosen); 
-                 wk     = flipWE (wk); 
-                 bk     = flipWE (bk); 
-                 wa         = flipWE (wa); 
-         } 
-   
-         m = wsq_to_pidx24 (anchor); 
-         n = (index_t)loosen - 8; 
-   
-         pp_slice = m * 48 + n; 
-   
-         if (IDX_is_empty(pp_slice)) { 
-                 *out = NOINDEX; 
-                 return FALSE; 
-         } 
-   
-         assert (- pp_slice  < (64*- MAX_PpINDEX ) );
 
-   
-         *out = pp_slice * (index_t)BLOCK_A + (index_t)wk * (index_t)BLOCK_B  + (index_t)bk * (index_t)BLOCK_C + (index_t)wa; 
-   
-         return TRUE; 
- } 
-   
- static void 
- kapkp_indextopc (index_t i, SQUARE *pw, SQUARE *pb) 
- { 
-         /*---------------------------------------------------------* 
-                 inverse work to make sure that the following is valid 
-                 index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d; 
-         *----------------------------------------------------------*/ 
-         enum  {BLOCK_A = 64*64*64, BLOCK_B = 64*64, BLOCK_C = 64}; 
-         enum  {block_m = 48}; 
-         index_t a, b, c, d, r; 
-         index_t m, n; 
-         SQUARE sq_m, sq_n; 
-   
-         r = i; 
-         a  = r / BLOCK_A; 
-         r -= a * BLOCK_A; 
-         b  = r / BLOCK_B; 
-         r -= b * BLOCK_B; 
-         c  = r / BLOCK_C; 
-         r -= c * BLOCK_C; 
-         d  = r; 
-   
-         /* unpack a, which is pslice, into m and n */ 
-         r = a; 
-         m  = r / block_m; 
-         r -= m * block_m; 
-         n  = r ; 
-   
-         sq_m = pidx24_to_wsq (m); 
-         sq_n = (SQUARE) n + 8; 
-   
-         pw[0] = (SQUARE) b; 
-         pb[0] = (SQUARE) c; 
-         pw[1] = (SQUARE) d; 
-         pw[2] = sq_m; 
-         pb[1] = sq_n; 
-         pw[3] = NOSQUARE; 
-         pb[2] = NOSQUARE; 
-   
-         assert (- A2  <=-  sq_m  &&-  sq_m  <-  A8 );
 
-         assert (- A2  <=-  sq_n  &&-  sq_n  <-  A8 );
 
-         assert (- kapkp_pctoindex  (- pw ,-  pb , &- a ) &&-  a  ==-  i );
 
-   
-         return; 
- } 
-   
- /********************** end KAP/KP ************************************/ 
-   
- /**********************  KABP/K ************************************/ 
-   
- static bool_t   test_kabpk (void); 
- static bool_t   kabpk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); 
- static void             kabpk_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
-   
- static bool_t 
- test_kabpk (void) 
- { 
-   
-         enum            {MAXPC = 16+1}; 
-         char            str[] = "kabpk"; 
-         SQUARE          a, b, c, d, e; 
-         SQUARE          pw[MAXPC], pb[MAXPC]; 
-         SQUARE          px[MAXPC], py[MAXPC]; 
-   
-         index_t         i, j; 
-         bool_t          err = FALSE; 
-   
-   
-         for (a = 0; a < 64; a++) { 
-                 for (b = 0; b < 64; b++) { 
-                 for (c = 0; c < 64; c++) { 
-                 for (d = 0; d < 64; d++) { 
-                 for (e = 0; e < 64; e++) { 
-   
-                         if (d <= H1 || d >= A8) 
-                                 continue; 
-   
-                         pw[0] = a; 
-                         pw[1] = b; 
-                         pw[2] = c; 
-                         pw[3] = d; 
-                         pw[4] = NOSQUARE; 
-   
-                         pb[0] = e; 
-                         pb[1] = NOSQUARE; 
-   
-                         if (kabpk_pctoindex (pw, pb, &i)) { 
-                                                         kabpk_indextopc (i, px, py); 
-                                                         kabpk_pctoindex (px, py, &j); 
-                                                         if (i != j) { 
-                                                                 err = TRUE; 
-                                                         } 
-                         } 
-   
-                 } 
-                 } 
-                 } 
-                 } 
-   
-         if ((a&1)==0) { 
-         } 
-         } 
-   
-         if (err) 
-                 printf ("> %s NOT passed\n",-  str );
 
-         else 
-                 printf ("> %s PASSED\n",-  str );
 
-         return !err; 
- } 
-   
-   
- static void 
- kabpk_indextopc (index_t i, SQUARE *pw, SQUARE *pb) 
- { 
-   
-         /*---------------------------------------------------------* 
-                 inverse work to make sure that the following is valid 
-                 index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d * BLOCK_D + e; 
-         *----------------------------------------------------------*/ 
-         enum  {BLOCK_A = 64*64*64*64, BLOCK_B = 64*64*64, BLOCK_C = 64*64, BLOCK_D = 64}; 
-         index_t a, b, c, d, e, r; 
-         SQUARE x; 
-   
-         r = i; 
-         a  = r / BLOCK_A; 
-         r -= a * BLOCK_A; 
-         b  = r / BLOCK_B; 
-         r -= b * BLOCK_B; 
-         c  = r / BLOCK_C; 
-         r -= c * BLOCK_C; 
-         d  = r / BLOCK_D; 
-         r -= d * BLOCK_D; 
-         e  = r; 
-   
-         x = pidx24_to_wsq(a); 
-   
-         pw[0] = (SQUARE) b; 
-         pw[1] = (SQUARE) d; 
-         pw[2] = (SQUARE) e; 
-         pw[3] = x; 
-         pw[4] = NOSQUARE; 
-   
-         pb[0] = (SQUARE) c; 
-         pb[1] = NOSQUARE; 
-   
-         assert (- kabpk_pctoindex  (- pw ,-  pb , &- a ) &&-  a  ==-  i );
 
-   
-         return; 
- } 
-   
-   
- static bool_t 
- kabpk_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out) 
- { 
-         enum  {BLOCK_A = 64*64*64*64, BLOCK_B = 64*64*64, BLOCK_C = 64*64, BLOCK_D = 64}; 
-         index_t pslice; 
-   
-         SQUARE wk   = pw[0]; 
-         SQUARE wa   = pw[1]; 
-         SQUARE wb   = pw[2]; 
-         SQUARE pawn = pw[3]; 
-         SQUARE bk   = pb[0]; 
-   
-         assert (- A2  <=-  pawn  &&-  pawn  <-  A8 );
 
-   
-         if ((pawn & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */ 
-                 pawn = flipWE (pawn); 
-                 wk   = flipWE (wk); 
-                 bk   = flipWE (bk); 
-                 wa   = flipWE (wa); 
-                 wb   = flipWE (wb); 
-         } 
-   
-         pslice = wsq_to_pidx24 (pawn); 
-   
-         *out = pslice * (index_t)BLOCK_A + (index_t)wk * (index_t)BLOCK_B  + (index_t)bk * (index_t)BLOCK_C + (index_t)wa * (index_t)BLOCK_D + (index_t)wb; 
-   
-         return TRUE; 
- } 
-   
- /********************** end KABP/K ************************************/ 
-   
- /**********************  KAAP/K ************************************/ 
-   
- static bool_t   test_kaapk (void); 
- static bool_t   kaapk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); 
- static void             kaapk_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
-   
- static bool_t 
- test_kaapk (void) 
- { 
-   
-         enum            {MAXPC = 16+1}; 
-         char            str[] = "kaapk"; 
-         SQUARE          a, b, c, d, e; 
-         SQUARE          pw[MAXPC], pb[MAXPC]; 
-         SQUARE          px[MAXPC], py[MAXPC]; 
-   
-         index_t         i, j; 
-         bool_t          err = FALSE; 
-   
-   
-         for (a = 0; a < 64; a++) { 
-                 for (b = 0; b < 64; b++) { 
-                 for (c = 0; c < 64; c++) { 
-                 for (d = 0; d < 64; d++) { 
-                 for (e = 0; e < 64; e++) { 
-   
-                         if (d <= H1 || d >= A8) 
-                                 continue; 
-   
-                         pw[0] = a; 
-                         pw[1] = b; 
-                         pw[2] = c; 
-                         pw[3] = d; 
-                         pw[4] = NOSQUARE; 
-   
-                         pb[0] = e; 
-                         pb[1] = NOSQUARE; 
-   
-                         if (kaapk_pctoindex (pw, pb, &i)) { 
-                                                         kaapk_indextopc (i, px, py); 
-                                                         kaapk_pctoindex (px, py, &j); 
-                                                         if (i != j) { 
-                                                                 err = TRUE; 
-                                                         } 
-                         } 
-   
-                 } 
-                 } 
-                 } 
-                 } 
-   
-         if ((a&1)==0) { 
-         } 
-         } 
-   
-         if (err) 
-                 printf ("> %s NOT passed\n",-  str );
 
-         else 
-                 printf ("> %s PASSED\n",-  str );
 
-         return !err; 
- } 
-   
-   
- static void 
- kaapk_indextopc (index_t i, SQUARE *pw, SQUARE *pb) 
- { 
-         /*---------------------------------------------------------* 
-                 inverse work to make sure that the following is valid 
-                 index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d; 
-         *----------------------------------------------------------*/ 
-         enum    {BLOCK_C = MAX_AAINDEX 
-                         ,BLOCK_B = 64*BLOCK_C 
-                         ,BLOCK_A = 64*BLOCK_B 
-         }; 
-         index_t a, b, c, d, r; 
-         index_t x, y, z; 
-   
-   
-         r = i; 
-         a  = r / BLOCK_A; 
-         r -= a * BLOCK_A; 
-         b  = r / BLOCK_B; 
-         r -= b * BLOCK_B; 
-         c  = r / BLOCK_C; 
-         r -= c * BLOCK_C; 
-         d  = r; 
-   
-         z = (index_t) pidx24_to_wsq(a); 
-   
-         /* split d into x, y*/ 
-         x = aabase [d]; 
-         y = (d + 1) + x - (x * (127-x)/2); 
-   
-         assert (- aaidx [- x ][- y ] ==-  aaidx [- y ][- x ]);
 
-   
-   
-         pw[0] = (SQUARE) b; 
-         pw[1] = (SQUARE) x; 
-         pw[2] = (SQUARE) y; 
-         pw[3] = (SQUARE) z; 
-         pw[4] = NOSQUARE; 
-   
-         pb[0] = (SQUARE) c; 
-         pb[1] = NOSQUARE; 
-   
-         assert (- kaapk_pctoindex  (- pw ,-  pb , &- a ) &&-  a  ==-  i );
 
-   
-         return; 
- } 
-   
-   
- static bool_t 
- kaapk_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out) 
- { 
-         enum    {BLOCK_C = MAX_AAINDEX 
-                         ,BLOCK_B = 64*BLOCK_C 
-                         ,BLOCK_A = 64*BLOCK_B 
-         }; 
-         index_t aa_combo, pslice; 
-   
-         SQUARE wk   = pw[0]; 
-         SQUARE wa   = pw[1]; 
-         SQUARE wa2  = pw[2]; 
-         SQUARE pawn = pw[3]; 
-         SQUARE bk   = pb[0]; 
-   
-         assert (- A2  <=-  pawn  &&-  pawn  <-  A8 );
 
-   
-         if ((pawn & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */ 
-                 pawn = flipWE (pawn); 
-                 wk   = flipWE (wk); 
-                 bk   = flipWE (bk); 
-                 wa   = flipWE (wa); 
-                 wa2  = flipWE (wa2); 
-         } 
-   
-         pslice = wsq_to_pidx24 (pawn); 
-   
-         aa_combo = (index_t) aaidx [wa] [wa2]; 
-   
-         if (IDX_is_empty(aa_combo)) { 
-                 *out = NOINDEX; 
-                 return FALSE; 
-         } 
-   
-         *out = pslice * (index_t)BLOCK_A + (index_t)wk * (index_t)BLOCK_B  + (index_t)bk * (index_t)BLOCK_C + aa_combo; 
-   
-   
-         return TRUE; 
- } 
-   
- /********************** end KAAP/K ************************************/ 
-   
- /**********************  KAA/KP ************************************/ 
-   
- static bool_t   test_kaakp (void); 
- static bool_t   kaakp_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); 
- static void             kaakp_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
-   
- static bool_t 
- test_kaakp (void) 
- { 
-   
-         enum            {MAXPC = 16+1}; 
-         char            str[] = "kaakp"; 
-         SQUARE          a, b, c, d, e; 
-         SQUARE          pw[MAXPC], pb[MAXPC]; 
-         SQUARE          px[MAXPC], py[MAXPC]; 
-   
-         index_t         i, j; 
-         bool_t          err = FALSE; 
-   
-   
-         for (a = 0; a < 64; a++) { 
-                 for (b = 0; b < 64; b++) { 
-                 for (c = 0; c < 64; c++) { 
-                 for (d = 0; d < 64; d++) { 
-                 for (e = 0; e < 64; e++) { 
-   
-                         if (d <= H1 || d >= A8) 
-                                 continue; 
-   
-                         pw[0] = a; 
-                         pw[1] = b; 
-                         pw[2] = c; 
-                         pw[3] = NOSQUARE; 
-   
-                         pb[0] = e; 
-                         pb[1] = d; 
-                         pb[2] = NOSQUARE; 
-   
-                         if (kaakp_pctoindex (pw, pb, &i)) { 
-                                                         kaakp_indextopc (i, px, py); 
-                                                         kaakp_pctoindex (px, py, &j); 
-                                                         if (i != j) { 
-                                                                 err = TRUE; 
-                                                         } 
-                         } 
-   
-                 } 
-                 } 
-                 } 
-                 } 
-   
-         if ((a&1)==0) { 
-         } 
-         } 
-   
-         if (err) 
-                 printf ("> %s NOT passed\n",-  str );
 
-         else 
-                 printf ("> %s PASSED\n",-  str );
 
-         return !err; 
- } 
-   
-   
- static void 
- kaakp_indextopc (index_t i, SQUARE *pw, SQUARE *pb) 
- { 
-         /*---------------------------------------------------------* 
-                 inverse work to make sure that the following is valid 
-                 index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d; 
-         *----------------------------------------------------------*/ 
-         enum    {BLOCK_C = MAX_AAINDEX 
-                         ,BLOCK_B = 64*BLOCK_C 
-                         ,BLOCK_A = 64*BLOCK_B 
-         }; 
-         index_t a, b, c, d, r; 
-         index_t x, y, z; 
-         SQUARE zq; 
-   
-   
-         r = i; 
-         a  = r / BLOCK_A; 
-         r -= a * BLOCK_A; 
-         b  = r / BLOCK_B; 
-         r -= b * BLOCK_B; 
-         c  = r / BLOCK_C; 
-         r -= c * BLOCK_C; 
-         d  = r; 
-   
-         zq = pidx24_to_wsq(a); 
-         z  = (index_t)flipNS(zq); 
-   
-   
-         /* split d into x, y*/ 
-         x = aabase [d]; 
-         y = (d + 1) + x - (x * (127-x)/2); 
-   
-         assert (- aaidx [- x ][- y ] ==-  aaidx [- y ][- x ]);
 
-   
-   
-         pw[0] = (SQUARE)b; 
-         pw[1] = (SQUARE)x; 
-         pw[2] = (SQUARE)y; 
-         pw[3] = NOSQUARE; 
-   
-         pb[0] = (SQUARE)c; 
-         pb[1] = (SQUARE)z; 
-         pb[2] = NOSQUARE; 
-   
-         assert (- kaakp_pctoindex  (- pw ,-  pb , &- a ) &&-  a  ==-  i );
 
-   
-         return; 
- } 
-   
-   
- static bool_t 
- kaakp_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out) 
- { 
-         enum    {BLOCK_C = MAX_AAINDEX 
-                         ,BLOCK_B = 64*BLOCK_C 
-                         ,BLOCK_A = 64*BLOCK_B 
-         }; 
-         index_t aa_combo, pslice; 
-   
-         SQUARE wk   = pw[0]; 
-         SQUARE wa   = pw[1]; 
-         SQUARE wa2  = pw[2]; 
-         SQUARE bk   = pb[0]; 
-         SQUARE pawn = pb[1]; 
-   
-         assert (- A2  <=-  pawn  &&-  pawn  <-  A8 );
 
-   
-         if ((pawn & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */ 
-                 pawn = flipWE (pawn); 
-                 wk   = flipWE (wk); 
-                 bk   = flipWE (bk); 
-                 wa   = flipWE (wa); 
-                 wa2  = flipWE (wa2); 
-         } 
-   
-         pawn = flipNS(pawn); 
-         pslice = wsq_to_pidx24 (pawn); 
-   
-         aa_combo = (index_t)aaidx [wa] [wa2]; 
-   
-         if (IDX_is_empty(aa_combo)) { 
-                 *out = NOINDEX; 
-                 return FALSE; 
-         } 
-   
-         *out = pslice * (index_t)BLOCK_A + (index_t)wk * (index_t)BLOCK_B  + (index_t)bk * (index_t)BLOCK_C + aa_combo; 
-   
-   
-         return TRUE; 
- } 
-   
- /********************** end KAA/KP ************************************/ 
-   
- /**********************  KPP/KP ************************************/ 
- /* 
- index_t         pp48_idx[48][48]; 
- sq_t            pp48_sq_x[MAX_PP48_INDEX]; 
- sq_t            pp48_sq_y[MAX_PP48_INDEX]; 
- */ 
- static bool_t   test_kppkp (void); 
- static bool_t   kppkp_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); 
- static void             kppkp_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
-   
- static sq_t map24_b   (sq_t s); 
- static sq_t unmap24_b (index_t i); 
-   
- static index_t 
- init_pp48_idx (void) 
- /* modifies pp48_idx[][], pp48_sq_x[], pp48_sq_y[] */ 
- { 
-         enum  {MAX_I = 48, MAX_J = 48}; 
-         SQUARE i, j; 
-         index_t idx = 0; 
-         SQUARE a, b; 
-   
-         /* default is noindex */ 
-         for (i = 0; i < MAX_I; i++) { 
-                 for (j = 0; j < MAX_J; j++) { 
-                         IDX_set_empty (pp48_idx [i][j]); 
-                 } 
-         } 
-   
-         for (idx = 0; idx < MAX_PP48_INDEX; idx++) { 
-                 pp48_sq_x [idx] = NOSQUARE; 
-                 pp48_sq_y [idx] = NOSQUARE; 
-         } 
-   
-         idx = 0; 
-         for (a = H7; a >= A2; a--) { 
-   
-                 for (b = a - 1; b >= A2; b--) { 
-   
-                         i = flipWE( flipNS (a) ) - 8; 
-                         j = flipWE( flipNS (b) ) - 8; 
-   
-                         if (IDX_is_empty(pp48_idx [i] [j])) { 
-   
-                                 pp48_idx   [- i ][- j ]=-  idx ;  assert (- idx  <-  MAX_PP48_INDEX );
-                                 pp48_idx  [j][i]= idx; 
-                                 pp48_sq_x  [- idx ] =-  i ;    assert (- i  <-  MAX_I );
-                                 pp48_sq_y  [- idx ] =-  j ;    assert (- j  <-  MAX_J );
-                                 idx++; 
-                         } 
-                 } 
-         } 
-         assert (- idx  ==-  MAX_PP48_INDEX );
 
-         return idx; 
- } 
-   
-   
-   
- static bool_t 
- test_kppkp (void) 
- { 
-   
-         enum            {MAXPC = 16+1}; 
-         char            str[] = "kppkp"; 
-         SQUARE          a, b, c, d, e; 
-         SQUARE          pw[MAXPC], pb[MAXPC]; 
-         SQUARE          px[MAXPC], py[MAXPC]; 
-   
-         index_t         i, j; 
-         bool_t          err = FALSE; 
-   
-   
-         for (a = 0; a < 64; a++) { 
-                 for (b = 0; b < 64; b++) { 
-                 for (c = 0; c < 64; c++) { 
-                 for (d = 0; d < 64; d++) { 
-                 for (e = 0; e < 64; e++) { 
-   
-                         if (c <= H1 || c >= A8) 
-                                 continue; 
-                         if (b <= H1 || b >= A8) 
-                                 continue; 
-                         if (d <= H1 || d >= A8) 
-                                 continue; 
-   
-                         pw[0] = a; 
-                         pw[1] = b; 
-                         pw[2] = c; 
-                         pw[3] = NOSQUARE; 
-   
-                         pb[0] = e; 
-                         pb[1] = d; 
-                         pb[2] = NOSQUARE; 
-   
-                         if (kppkp_pctoindex (pw, pb, &i)) { 
-                                                         kppkp_indextopc (i, px, py); 
-                                                         kppkp_pctoindex (px, py, &j); 
-                                                         if (i != j) { 
-                                                                 err = TRUE; 
-                                                         } 
-                         } 
-   
-                 } 
-                 } 
-                 } 
-                 } 
-   
-         if ((a&1)==0) { 
-         } 
-         } 
-   
-         if (err) 
-                 printf ("> %s NOT passed\n",-  str );
 
-         else 
-                 printf ("> %s PASSED\n",-  str );
 
-         return !err; 
- } 
-   
-   
- static void 
- kppkp_indextopc (index_t i, SQUARE *pw, SQUARE *pb) 
- { 
-         /*---------------------------------------------------------* 
-                 inverse work to make sure that the following is valid 
-                 index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d; 
-         *----------------------------------------------------------*/ 
-   
-         enum  {BLOCK_A = MAX_PP48_INDEX*64*64, BLOCK_B = 64*64, BLOCK_C = 64}; 
-         index_t a, b, c, d, r; 
-         SQUARE m, n; 
-   
-         r = i; 
-         a  = r / BLOCK_A; 
-         r -= a * BLOCK_A; 
-         b  = r / BLOCK_B; 
-         r -= b * BLOCK_B; 
-         c  = r / BLOCK_C; 
-         r -= c * BLOCK_C; 
-         d  = r; 
-   
-         m = pp48_sq_x [b]; 
-         n = pp48_sq_y [b]; 
-   
-         pw[0] = (SQUARE)c; 
-         pw[1] = flipWE(flipNS(m+8)); 
-         pw[2] = flipWE(flipNS(n+8)); 
-         pw[3] = NOSQUARE; 
-   
-         pb[0] = (SQUARE)d; 
-         pb[1] = (SQUARE)unmap24_b (a); 
-         pb[2] = NOSQUARE; 
-   
-   
-         assert (- A2  <=-  pw [1] &&-  pw [1] <-  A8 );
 
-         assert (- A2  <=-  pw [2] &&-  pw [2] <-  A8 );
 
-         assert (- A2  <=-  pb [1] &&-  pb [1] <-  A8 );
 
-         assert (- kppkp_pctoindex  (- pw ,-  pb , &- a ) &&-  a  ==-  i );
 
-   
-         return; 
- } 
-   
-   
- static bool_t 
- kppkp_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out) 
- { 
-         enum  {BLOCK_A = MAX_PP48_INDEX*64*64, BLOCK_B = 64*64, BLOCK_C = 64}; 
-         index_t pp48_slice; 
-   
-         SQUARE wk     = pw[0]; 
-         SQUARE pawn_a = pw[1]; 
-         SQUARE pawn_b = pw[2]; 
-         SQUARE bk     = pb[0]; 
-         SQUARE pawn_c = pb[1]; 
-         SQUARE i, j, k; 
-   
-         assert (- A2  <=-  pawn_a  &&-  pawn_a  <-  A8 );
 
-         assert (- A2  <=-  pawn_b  &&-  pawn_b  <-  A8 );
 
-         assert (- A2  <=-  pawn_c  &&-  pawn_c  <-  A8 );
 
-   
-         if ((pawn_c & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */ 
-                 wk     = flipWE (wk); 
-                 pawn_a = flipWE (pawn_a); 
-                 pawn_b = flipWE (pawn_b); 
-                 bk     = flipWE (bk); 
-                 pawn_c = flipWE (pawn_c); 
-         } 
-   
-         i = flipWE( flipNS (pawn_a) ) - 8; 
-         j = flipWE( flipNS (pawn_b) ) - 8; 
-         k = map24_b (pawn_c); /* black pawn, so low indexes mean more advanced 0 == A2 */ 
-   
-         pp48_slice = pp48_idx [i] [j]; 
-   
-         if (IDX_is_empty(pp48_slice)) { 
-                 *out = NOINDEX; 
-                 return FALSE; 
-         } 
-   
-         assert (- pp48_slice  <-  MAX_PP48_INDEX  );
 
-   
-         *out = (index_t)k * (index_t)BLOCK_A + pp48_slice * (index_t)BLOCK_B + (index_t)wk * (index_t)BLOCK_C  + (index_t)bk; 
-   
-         return TRUE; 
- } 
-   
- static sq_t 
- map24_b (sq_t s) 
- { 
-         s -= 8; 
-         return ((s&3)+s)>>1; 
- } 
-   
- static sq_t 
- unmap24_b (index_t i) 
- { 
-         return (sq_t) ((i&(4+8+16)) + i + 8); 
- } 
-   
- /********************** end KPP/KP ************************************/ 
-   
- /**********************  KPPP/K ************************************/ 
-   
- static const sq_t itosq[48] = { 
-         H7,G7,F7,E7, 
-         H6,G6,F6,E6, 
-         H5,G5,F5,E5, 
-         H4,G4,F4,E4, 
-         H3,G3,F3,E3, 
-         H2,G2,F2,E2, 
-         D7,C7,B7,A7, 
-         D6,C6,B6,A6, 
-         D5,C5,B5,A5, 
-         D4,C4,B4,A4, 
-         D3,C3,B3,A3, 
-         D2,C2,B2,A2 
- }; 
-   
- static bool_t   test_kpppk (void); 
- static bool_t   kpppk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); 
- static void             kpppk_indextopc (index_t i, SQUARE *pw, SQUARE *pb); 
-   
- static index_t 
- init_ppp48_idx (void) 
- /* modifies ppp48_idx[][], ppp48_sq_x[], ppp48_sq_y[], ppp48_sq_z[] */ 
- { 
-         enum  {MAX_I = 48, MAX_J = 48, MAX_K = 48}; 
-         SQUARE i, j, k; 
-         index_t idx = 0; 
-         SQUARE a, b, c; 
-         int x, y, z; 
-   
-         /* default is noindex */ 
-         for (i = 0; i < MAX_I; i++) { 
-                 for (j = 0; j < MAX_J; j++) { 
-                         for (k = 0; k < MAX_K; k++) { 
-                                 IDX_set_empty(ppp48_idx [i][j][k]); 
-                         } 
-                 } 
-         } 
-   
-         for (idx = 0; idx < MAX_PPP48_INDEX; idx++) { 
-                 ppp48_sq_x [idx] = (uint8_t)NOSQUARE; 
-                 ppp48_sq_y [idx] = (uint8_t)NOSQUARE; 
-                 ppp48_sq_z [idx] = (uint8_t)NOSQUARE; 
-         } 
-   
-         idx = 0; 
-         for (x = 0; x < 48; x++) { 
-                 for (y = x+1; y < 48; y++) { 
-                         for (z = y+1; z < 48; z++) { 
-   
-                                 a = itosq [x]; 
-                                 b = itosq [y]; 
-                                 c = itosq [z]; 
-   
-                                 if (!in_queenside(b) || !in_queenside(c)) 
-                                                 continue; 
-   
-                                 i = a - 8; 
-                                 j = b - 8; 
-                                 k = c - 8; 
-   
-                                 if (IDX_is_empty(ppp48_idx [i] [j] [k])) { 
-   
-                                         ppp48_idx  [i][j][k] = idx; 
-                                         ppp48_idx  [i][k][j] = idx; 
-                                         ppp48_idx  [j][i][k] = idx; 
-                                         ppp48_idx  [j][k][i] = idx; 
-                                         ppp48_idx  [k][i][j] = idx; 
-                                         ppp48_idx  [k][j][i] = idx; 
-                                         ppp48_sq_x  [- idx ] = (uint8_t)-  i ;         assert (- i  <-  MAX_I );
-                                         ppp48_sq_y  [- idx ] = (uint8_t)-  j ;         assert (- j  <-  MAX_J );
-                                         ppp48_sq_z  [- idx ] = (uint8_t)-  k ;         assert (- k  <-  MAX_K );
-                                         idx++; 
-                                 } 
-                         } 
-                 } 
-         } 
-   
- /*      assert (idx == MAX_PPP48_INDEX);*/ 
-         return idx; 
- } 
-   
- static bool_t 
- test_kpppk (void) 
- { 
-   
-         enum            {MAXPC = 16+1}; 
-         char            str[] = "kpppk"; 
-         SQUARE          a, b, c, d, e; 
-         SQUARE          pw[MAXPC], pb[MAXPC]; 
-         SQUARE          px[MAXPC], py[MAXPC]; 
-   
-         index_t         i, j; 
-         bool_t          err = FALSE; 
-   
-   
-         for (a = 0; a < 64; a++) { 
-                 for (b = 0; b < 64; b++) { 
-                 for (c = 0; c < 64; c++) { 
-                 for (d = 0; d < 64; d++) { 
-                 for (e = 0; e < 64; e++) { 
-   
-                         if (c <= H1 || c >= A8) 
-                                 continue; 
-                         if (b <= H1 || b >= A8) 
-                                 continue; 
-                         if (d <= H1 || d >= A8) 
-                                 continue; 
-   
-                         pw[0] = a; 
-                         pw[1] = b; 
-                         pw[2] = c; 
-                         pw[3] = d; 
-                         pw[4] = NOSQUARE; 
-   
-                         pb[0] = e; 
-                         pb[1] = NOSQUARE; 
-   
-                         if (kpppk_pctoindex (pw, pb, &i)) { 
-                                                         kpppk_indextopc (i, px, py); 
-                                                         kpppk_pctoindex (px, py, &j); 
-                                                         if (i != j) { 
-                                                                 err = TRUE; 
-                                                         } 
-                         } 
-   
-                 } 
-                 } 
-                 } 
-                 } 
-   
-         if ((a&1)==0) { 
-         } 
-         } 
-   
-         if (err) 
-                 printf ("> %s NOT passed\n",-  str );
 
-         else 
-                 printf ("> %s PASSED\n",-  str );
 
-         return !err; 
- } 
-   
-   
- static void 
- kpppk_indextopc (index_t i, SQUARE *pw, SQUARE *pb) 
- { 
-         /*---------------------------------------------------------* 
-                 inverse work to make sure that the following is valid 
-                 index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d; 
-         *----------------------------------------------------------*/ 
-   
-         enum  {BLOCK_A = 64*64, BLOCK_B = 64}; 
-         index_t a, b, c, r; 
-         SQUARE m, n, o; 
-   
-         r  = i; 
-         a  = r / BLOCK_A; 
-         r -= a * BLOCK_A; 
-         b  = r / BLOCK_B; 
-         r -= b * BLOCK_B; 
-         c  = r; 
-   
-         m = ppp48_sq_x [a]; 
-         n = ppp48_sq_y [a]; 
-         o = ppp48_sq_z [a]; 
-   
-   
-         pw[0] = (SQUARE)b; 
-         pw[1] = m + 8; 
-         pw[2] = n + 8; 
-         pw[3] = o + 8; 
-         pw[4] = NOSQUARE; 
-   
-         pb[0] = (SQUARE)c; 
-         pb[1] = NOSQUARE; 
-   
-   
-         assert (- A2  <=-  pw [1] &&-  pw [1] <-  A8 );
 
-         assert (- A2  <=-  pw [2] &&-  pw [2] <-  A8 );
 
-         assert (- A2  <=-  pw [3] &&-  pw [3] <-  A8 );
 
-         assert (- kpppk_pctoindex  (- pw ,-  pb , &- a ) &&-  a  ==-  i );
 
-   
-         return; 
- } 
-   
-   
- static bool_t 
- kpppk_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out) 
- { 
-         enum  {BLOCK_A = 64*64, BLOCK_B = 64}; 
-         index_t ppp48_slice; 
-   
-         SQUARE wk     = pw[0]; 
-         SQUARE pawn_a = pw[1]; 
-         SQUARE pawn_b = pw[2]; 
-         SQUARE pawn_c = pw[3]; 
-   
-         SQUARE bk     = pb[0]; 
-   
-         SQUARE i, j, k; 
-   
-         assert (- A2  <=-  pawn_a  &&-  pawn_a  <-  A8 );
 
-         assert (- A2  <=-  pawn_b  &&-  pawn_b  <-  A8 );
 
-         assert (- A2  <=-  pawn_c  &&-  pawn_c  <-  A8 );
 
-   
-         i = pawn_a - 8; 
-         j = pawn_b - 8; 
-         k = pawn_c - 8; 
-   
-         ppp48_slice = ppp48_idx [i] [j] [k]; 
-   
-         if (IDX_is_empty(ppp48_slice)) { 
-                 wk     = flipWE (wk); 
-                 pawn_a = flipWE (pawn_a); 
-                 pawn_b = flipWE (pawn_b); 
-                 pawn_c = flipWE (pawn_c); 
-                 bk     = flipWE (bk); 
-         } 
-   
-         i = pawn_a - 8; 
-         j = pawn_b - 8; 
-         k = pawn_c - 8; 
-   
-         ppp48_slice = ppp48_idx [i] [j] [k]; 
-   
-         if (IDX_is_empty(ppp48_slice)) { 
-                 *out = NOINDEX; 
-                 return FALSE; 
-         } 
-   
-         assert (- ppp48_slice  <-  MAX_PPP48_INDEX  );
 
-   
-         *out = (index_t)ppp48_slice * BLOCK_A + (index_t)wk * BLOCK_B  + (index_t)bk; 
-   
-         return TRUE; 
- } 
-   
-   
- /********************** end KPPP/K ************************************/ 
-   
-   
- static bool_t 
- kpkp_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out) 
- { 
-         enum  {BLOCK_A = 64*64, BLOCK_B = 64}; 
-         SQUARE pp_slice; 
-         SQUARE anchor, loosen; 
-   
-         SQUARE wk     = pw[0]; 
-         SQUARE bk     = pb[0]; 
-         SQUARE pawn_a = pw[1]; 
-         SQUARE pawn_b = pb[1]; 
-   
-         SQUARE m, n; 
-   
-         #ifdef DEBUG 
-         if (!(A2 <= pawn_a && pawn_a < A8)) { 
-                 printf ("\n\nsquare of pawn_a: %s\n",-  Square_str [- pawn_a ]);
 
-                 printf(" wk %s\n p1 %s\n p2 %s\n bk %s\n" 
-                         , Square_str[wk] 
-                         , Square_str[pawn_a] 
-                         , Square_str[pawn_b] 
-                         , Square_str[bk] 
-                         ); 
-         } 
-         #endif 
-   
-         assert (- A2  <=-  pawn_a  &&-  pawn_a  <-  A8 );
 
-         assert (- A2  <=-  pawn_b  &&-  pawn_b  <-  A8 );
 
-         assert (- pw [2] ==-  NOSQUARE  &&-  pb [2] ==-  NOSQUARE );
 
-   
-         /*pp_putanchorfirst (pawn_a, pawn_b, &anchor, &loosen);*/ 
-         anchor = pawn_a; 
-         loosen = pawn_b; 
-   
-         if ((anchor & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */ 
-                 anchor = flipWE (anchor); 
-                 loosen = flipWE (loosen); 
-                 wk     = flipWE (wk); 
-                 bk     = flipWE (bk); 
-         } 
-   
-         m = (SQUARE)wsq_to_pidx24 (anchor); 
-         n = loosen - 8; 
-   
-         pp_slice = m * 48 + n; 
-   
-         if (IDX_is_empty(pp_slice)) { 
-                 *out = NOINDEX; 
-                 return FALSE; 
-         } 
-   
-         assert (- pp_slice  <-  MAX_PpINDEX  );
 
-   
-         *out = (index_t) (pp_slice * BLOCK_A + wk * BLOCK_B  + bk); 
-   
-         return TRUE; 
- } 
-   
-   
- static void 
- kpkp_indextopc (index_t i, SQUARE *pw, SQUARE *pb) 
- { 
-         /*---------------------------------------------------------* 
-                 inverse work to make sure that the following is valid 
-                 index = a * BLOCK_A + b * BLOCK_B + c; 
-         *----------------------------------------------------------*/ 
-         enum  {B11100  = 7u << 2}; 
-         enum  {BLOCK_A = 64*64, BLOCK_B = 64}; 
-         enum  {block_m = 48}; 
-         index_t a, b, c, r; 
-         index_t m, n; 
-         SQUARE sq_m, sq_n; 
-   
-         r = i; 
-         a  = r / BLOCK_A; 
-         r -= a * BLOCK_A; 
-         b  = r / BLOCK_B; 
-         r -= b * BLOCK_B; 
-         c  = r; 
-   
-         /* unpack a, which is pslice, into m and n */ 
-         r = a; 
-         m  = r / block_m; 
-         r -= m * block_m; 
-         n  = r ; 
-   
-         sq_m  = pidx24_to_wsq (m); 
-         sq_n  = (SQUARE)n + 8; 
-   
-         pw[0] = (SQUARE)b; 
-         pb[0] = (SQUARE)c; 
-         pw[1] = sq_m; 
-         pb[1] = sq_n; 
-         pw[2] = NOSQUARE; 
-         pb[2] = NOSQUARE; 
-   
-         assert (- A2  <=-  pw [1] &&-  pw [1] <-  A8 );
 
-         assert (- A2  <=-  pb [1] &&-  pb [1] <-  A8 );
 
-   
-         return; 
- } 
-   
-   
- /****************************************************************************\ 
-  * 
-  * 
-  *                                                              DEBUG ZONE 
-  * 
-  * 
-  ****************************************************************************/ 
-   
- #if defined(DEBUG) 
- static void 
- print_pos (const sq_t *ws, const sq_t *bs, const pc_t *wp, const pc_t *bp) 
- { 
-         int i; 
-         for (i = 0; ws[i] != NOSQUARE; i++) { 
-                 printf ("%s%s ",-  P_str [- wp [- i ]],-  Square_str [- ws [- i ]]);
 
-         } 
-         for (i = 0; bs[i] != NOSQUARE; i++) { 
-                 printf ("%s%s ",-  P_str [- bp [- i ]],-  Square_str [- bs [- i ]]);
 
-         } 
- } 
- #endif 
-   
- #if defined(DEBUG) || defined(FOLLOW_EGTB) 
- static void 
- output_state (unsigned stm, const SQUARE *wSQ, const SQUARE *bSQ, 
-                                                                 const SQ_CONTENT *wPC, const SQ_CONTENT *bPC) 
- { 
-         int i; 
-         assert (- stm  ==-  WH  ||-  stm  ==-  BL );
 
-   
-         printf("\n%s to move\n",-  stm ==- WH ?"White":"Black");
 
-         for (i = 0; wSQ[i] != NOSQUARE; i++) { 
-                 printf("%s%s ",-  P_str [- wPC [- i ]],-  Square_str [- wSQ [- i ]]);
 
-         } 
-         for (i = 0; bSQ[i] != NOSQUARE; i++) { 
-                 printf("%s%s ",-  P_str [- bPC [- i ]],-  Square_str [- bSQ [- i ]]);
 
-         } 
- } 
- #endif 
-   
- static void 
- list_index (void) 
- { 
-         enum  {START_GTB = 0, END_GTB = (MAX_EGKEYS)}; 
-         int i; 
-         index_t accum = 0; 
-         printf ("\nIndex for each GTB\n"); 
-                 printf ("%3s: %7s  %7s   %7s   %7s\n" , "i", "TB", "RAM-slice", "RAM-max", "HD-cumulative"); 
-         for (i = START_GTB; i < END_GTB; i++) { 
-                 index_t indiv_k  = egkey[i].maxindex * (index_t)sizeof(dtm_t) * 2/1024; 
-                 accum += indiv_k; 
-                 printf ("%3d: %7s %8luk %8luk %8luM\n",-  i ,-  egkey [- i ]- . str, (long unsigned)(- indiv_k /- egkey [- i ]- . slice_n),
 
-                                                                                                         (long unsigned)indiv_k, (long unsigned)accum/1024/2); 
-         } 
-         return; 
- } 
-   
- /************************************************************************************************************** 
-   
-  NEW_WDL 
-   
- **************************************************************************************************************/ 
-   
- /*---------------------------------------------------------------------*\ 
- |                       WDL CACHE Implementation  ZONE 
- \*---------------------------------------------------------------------*/ 
-   
- /* 
- |                       WDL CACHE Statics 
- \*---------------------------------------------------------------------*/ 
-   
- /*--------------------------------------------------------------------------*/ 
- static unsigned int             wdl_extract (unit_t *uarr, index_t x); 
- static wdl_block_t *    wdl_point_block_to_replace (void); 
- static void                             wdl_movetotop (wdl_block_t *t); 
-   
- #if 0 
- static bool_t                   wdl_cache_init (size_t cache_mem); 
- static void                             wdl_cache_flush (void); 
- static bool_t                   get_WDL (tbkey_t key, unsigned side, index_t idx, unsigned int *info_out, bool_t probe_hard_flag); 
- #endif 
-   
- static bool_t                   wdl_cache_is_on (void); 
- static void                             wdl_cache_reset_counters (void); 
- static void                             wdl_cache_done (void); 
-   
- static wdl_block_t *    wdl_point_block_to_replace (void); 
- static bool_t                   get_WDL_from_cache (tbkey_t key, unsigned side, index_t idx, unsigned int *out); 
- static void                             wdl_movetotop (wdl_block_t *t); 
- static bool_t                   wdl_preload_cache (tbkey_t key, unsigned side, index_t idx); 
-   
- /*--------------------------------------------------------------------------*/ 
-   
- /*---------------------------------------------------------------------*\ 
- |                       WDL CACHE Maintainance 
- \*---------------------------------------------------------------------*/ 
-   
-   
- static size_t 
- wdl_cache_init (size_t cache_mem) 
- { 
-         unsigned int    i; 
-         wdl_block_t     *p; 
-         size_t                  entries_per_block; 
-         size_t                  max_blocks; 
-         size_t                  block_mem; 
-   
-         if (WDL_CACHE_INITIALIZED) 
-                 wdl_cache_done(); 
-   
-         entries_per_block       = 16 * 1024;  /* fixed, needed for the compression schemes */ 
-   
-         WDL_units_per_block     = entries_per_block / WDL_entries_per_unit; 
-         block_mem                       = WDL_units_per_block * sizeof(unit_t); 
-   
-         max_blocks                      = cache_mem / block_mem; 
-         cache_mem                       = max_blocks * block_mem; 
-   
-   
-         wdl_cache_reset_counters (); 
-   
-         wdl_cache.entries_per_block = entries_per_block; 
-         wdl_cache.max_blocks            = max_blocks; 
-         wdl_cache.cached                        = TRUE; 
-         wdl_cache.top                           = NULL; 
-         wdl_cache.bot                           = NULL; 
-         wdl_cache.n                             = 0; 
-   
-         if (0 ==-  cache_mem  ||-  NULL  == (- wdl_cache. buffer = (- unit_t  *) malloc (- cache_mem ))) {
 
-                 wdl_cache.cached = FALSE; 
-                 return 0; 
-         } 
-   
-         if (0 ==-  max_blocks ||-  NULL  == (- wdl_cache. blocks = (- wdl_block_t  *) malloc (- max_blocks  * sizeof(- wdl_block_t )))) {
 
-                 wdl_cache.cached = FALSE; 
-                 return 0; 
-         } 
-   
-         for (i = 0; i < max_blocks; i++) { 
-                 p = &wdl_cache.blocks[i]; 
-                 p->key          = -1; 
-                 p->side         = gtbNOSIDE; 
-                 p->offset       = gtbNOINDEX; 
-                 p->p_arr        = wdl_cache.buffer + i * WDL_units_per_block; 
-                 p->prev         = NULL; 
-                 p->next         = NULL; 
-         } 
-   
-         wdl_cache.ht_size = 1; 
-         while (wdl_cache.ht_size < max_blocks * 4) 
-                 wdl_cache.ht_size *= 2; 
-         wdl_cache.ht_used = 0; 
-         wdl_cache. hash_table = (- wdl_block_t **) malloc (- wdl_cache. ht_size * sizeof(- wdl_block_t *));;
-         if (wdl_cache.hash_table == NULL) { 
-                 wdl_cache.cached = FALSE; 
-                 wdl_cache.blocks = NULL; 
-                 wdl_cache.buffer = NULL; 
-                 return 0; 
-         } 
-   
-         for (i = 0; i < wdl_cache.ht_size; i++) { 
-                 wdl_cache.hash_table[i] = NULL; 
-         } 
-   
-         WDL_CACHE_INITIALIZED = TRUE; 
-   
-         return cache_mem; 
- } 
-   
-   
- static void 
- wdl_cache_done (void) 
- { 
-         assert(- WDL_CACHE_INITIALIZED );
 
-   
-         wdl_cache.cached = FALSE; 
-         wdl_cache.hard = 0; 
-         wdl_cache.soft = 0; 
-         wdl_cache.hardmisses = 0; 
-         wdl_cache.hits = 0; 
-         wdl_cache.softmisses = 0; 
-         wdl_cache.comparisons = 0; 
-         wdl_cache.max_blocks = 0; 
-         wdl_cache.entries_per_block = 0; 
-   
-         wdl_cache.top = NULL; 
-         wdl_cache.bot = NULL; 
-         wdl_cache.n = 0; 
-   
-         if (wdl_cache.buffer != NULL) 
-         wdl_cache.buffer = NULL; 
-   
-         if (wdl_cache.blocks != NULL) 
-         wdl_cache.blocks = NULL; 
-   
-         if (wdl_cache.hash_table != NULL) 
-                 free (- wdl_cache. hash_table);
 
-         wdl_cache.hash_table = NULL; 
-   
-         WDL_CACHE_INITIALIZED = FALSE; 
-         return; 
- } 
-   
-   
- static void 
- wdl_cache_flush (void) 
- { 
-         unsigned int    i; 
-         wdl_block_t     *p; 
-         size_t max_blocks = wdl_cache.max_blocks; 
-   
-         wdl_cache.top                           = NULL; 
-         wdl_cache.bot                           = NULL; 
-         wdl_cache.n                             = 0; 
-   
-         for (i = 0; i < max_blocks; i++) { 
-                 p = &wdl_cache.blocks[i]; 
-                 p->key          = -1; 
-                 p->side         = gtbNOSIDE; 
-                 p->offset       = gtbNOINDEX; 
-                 p->p_arr        = wdl_cache.buffer + i * WDL_units_per_block; 
-                 p->prev         = NULL; 
-                 p->next         = NULL; 
-         } 
-   
-         wdl_cache_reset_counters  (); 
-   
-         return; 
- } 
-   
-   
- static void 
- wdl_cache_reset_counters (void) 
- { 
-         wdl_cache.hard = 0; 
-         wdl_cache.soft = 0; 
-         wdl_cache.hardmisses = 0; 
-         wdl_cache.hits = 0; 
-         wdl_cache.softmisses = 0; 
-         wdl_cache.comparisons = 0; 
-         return; 
- } 
-   
-   
- static bool_t 
- wdl_cache_is_on (void) 
- { 
-         return wdl_cache.cached; 
- } 
-   
- /****************************************************************************\ 
- |                                               Replacement 
- \****************************************************************************/ 
-   
- static wdl_block_t * 
- wdl_point_block_to_replace (void) 
- { 
-         wdl_block_t *p, *t, *s; 
-   
-         assert (0 ==-  wdl_cache. n ||-  wdl_cache. top !=-  NULL );
 
-         assert (0 ==-  wdl_cache. n ||-  wdl_cache. bot !=-  NULL );
 
-         assert (0 ==-  wdl_cache. n ||-  wdl_cache. bot->- prev  ==-  NULL );
 
-         assert (0 ==-  wdl_cache. n ||-  wdl_cache. top->- next  ==-  NULL );
 
-   
-         if (wdl_cache.n > 0 && -1 == wdl_cache.top->key) { 
-   
-                 /* top blocks is unusable, should be the one to replace*/ 
-                 p = wdl_cache.top; 
-   
-         } else 
-         if (wdl_cache.n == 0) { 
-   
-                 p = &wdl_cache.blocks[wdl_cache.n++]; 
-                 wdl_cache.top = p; 
-                 wdl_cache.bot = p; 
-   
-                 p->prev = NULL; 
-                 p->next = NULL; 
-   
-         } else 
-         if (wdl_cache.n < wdl_cache.max_blocks) { /* add */ 
-   
-                 s = wdl_cache.top; 
-                 p = &wdl_cache.blocks[wdl_cache.n++]; 
-                 wdl_cache.top = p; 
-   
-                 s->next = p; 
-                 p->prev = s; 
-                 p->next = NULL; 
-   
-         } else {                       /* replace*/ 
-   
-                 t = wdl_cache.bot; 
-                 s = wdl_cache.top; 
-                 wdl_cache.bot = t->next; 
-                 wdl_cache.top = t; 
-   
-                 s->next = t; 
-                 t->prev = s; 
-                 wdl_cache.top->next = NULL; 
-                 wdl_cache.bot->prev = NULL; 
-   
-                 p = t; 
-         } 
-   
-         /* make the information content unusable, it will be replaced */ 
-         p->key    = -1; 
-         p->side   = gtbNOSIDE; 
-         p->offset = gtbNOINDEX; 
-   
-         return p; 
- } 
-   
- /****************************************************************************\ 
- | 
- |                                               NEW PROBING ZONE 
- | 
- \****************************************************************************/ 
-   
- static unsigned int     wdl_extract (unit_t *uarr, index_t x); 
- static bool_t           get_WDL_from_cache (tbkey_t key, unsigned side, index_t idx, unsigned int *info_out); 
- static unsigned         dtm2WDL(dtm_t dtm); 
- static void                     wdl_movetotop (wdl_block_t *t); 
- static bool_t           wdl_preload_cache (tbkey_t key, unsigned side, index_t idx); 
- static void                     dtm_block_2_wdl_block(dtm_block_t *g, wdl_block_t *w, size_t n); 
-   
- static bool_t 
- get_WDL (tbkey_t key, unsigned side, index_t idx, unsigned int *info_out, bool_t probe_hard_flag) 
- { 
-         dtm_t dtm; 
-         bool_t found; 
-   
-         found = get_WDL_from_cache (key, side, idx, info_out); 
-   
-         if (found) { 
-                 wdl_cache.hits++; 
-         } else { 
-                 /* may probe soft */ 
-                 found = get_dtm (key, side, idx, &dtm, probe_hard_flag); 
-                 if (found) { 
-                         *info_out = dtm2WDL(dtm); 
-                         /* move cache info from dtm_cache to WDL_cache */ 
-                         if (wdl_cache_is_on()) 
-                                 wdl_preload_cache (key, side, idx); 
-                 } 
-         } 
-   
-         if (probe_hard_flag) { 
-                 wdl_cache.hard++; 
-                 if (!found) { 
-                         wdl_cache.hardmisses++; 
-                 } 
-         } else { 
-                 wdl_cache.soft++; 
-                 if (!found) { 
-                         wdl_cache.softmisses++; 
-                 } 
-         } 
-   
-         return found; 
- } 
-   
- static void wdl_hash_insert (wdl_block_t * e); 
-   
- static void 
- wdl_hash_rebuild (void) 
- { 
-         wdl_block_t     * p; 
-         size_t i; 
-   
-         for (i = 0; i < wdl_cache.ht_size; i++) 
-                 wdl_cache.hash_table[i] = NULL; 
-         wdl_cache.ht_used = 0; 
-   
-         for (p = wdl_cache.top; p != NULL; p = p->prev) 
-                 wdl_hash_insert (p); 
- } 
-   
- static void 
- wdl_hash_insert (wdl_block_t * e) 
- { 
-         size_t h1, h2; 
-   
-         if (wdl_cache.ht_used > wdl_cache.ht_size * 3 / 4) 
-                 wdl_hash_rebuild(); 
-   
-     h1 = hash_func_1 (e->key, e->side, e->offset) & (wdl_cache.ht_size - 1); 
-     h2 = hash_func_2 (e->key, e->side, e->offset); 
-     while (wdl_cache.hash_table[h1]) 
-         h1 = (h1 + h2) & (wdl_cache.ht_size - 1); 
-     wdl_cache.hash_table[h1] = e; 
-     wdl_cache.ht_used++; 
- } 
-   
- static bool_t 
- get_WDL_from_cache (tbkey_t key, unsigned side, index_t idx, unsigned int *out) 
- { 
-         index_t         offset; 
-         index_t         remainder; 
-         wdl_block_t     *p; 
-         wdl_block_t     *ret; 
-         size_t          h1, h2; 
-   
-         if (!wdl_cache_is_on()) 
-                 return FALSE; 
-   
-         split_index (wdl_cache.entries_per_block, idx, &offset, &remainder); 
-   
-         ret = NULL; 
-   
-         h1 = hash_func_1 (key, side, offset) & (wdl_cache.ht_size - 1); 
-         h2 = hash_func_2 (key, side, offset); 
-         while (1) { 
-                 p = wdl_cache.hash_table[h1]; 
-                 if (!p) 
-                         break; 
-   
-                 wdl_cache.comparisons++; 
-   
-                 if (key == p->key && side == p->side && offset  == p->offset) { 
-                         ret = p; 
-                         break; 
-                 } 
-   
-                 h1 = (h1 + h2) & (wdl_cache.ht_size - 1); 
-         } 
-   
-         if (ret != NULL) { 
-                 *out = wdl_extract (ret->p_arr, remainder); 
-                 wdl_movetotop(ret); 
-         } 
-   
-         FOLLOW_LU("get_wdl_from_cache ok?",(ret != NULL)) 
-   
-         return ret != NULL; 
- } 
-   
- static unsigned int 
- wdl_extract (unit_t *uarr, index_t x) 
- { 
-         index_t width = 2; 
-         index_t nu = x/WDL_entries_per_unit; 
-         index_t y  = x - (nu * WDL_entries_per_unit); 
-         return (uarr[nu] >> (y*width)) & WDL_entry_mask; 
- } 
-   
- static void 
- wdl_movetotop (wdl_block_t *t) 
- { 
-         wdl_block_t *s, *nx, *pv; 
-   
-   
-         if (t->next == NULL) /* at the top already */ 
-                 return; 
-   
-         /* detach */ 
-         pv = t->prev; 
-         nx = t->next; 
-   
-         if (pv == NULL)  /* at the bottom */ 
-                 wdl_cache.bot = nx; 
-         else 
-                 pv->next = nx; 
-   
-         if (nx == NULL) /* at the top */ 
-                 wdl_cache.top = pv; 
-         else 
-                 nx->prev = pv; 
-   
-         /* relocate */ 
-         s = wdl_cache.top; 
-         if (s == NULL) 
-                 wdl_cache.bot = t; 
-         else 
-                 s->next = t; 
-   
-         t->next = NULL; 
-         t->prev = s; 
-         wdl_cache.top = t; 
-   
-         return; 
- } 
-   
- /****************************************************************************************************/ 
-   
- static bool_t 
- wdl_preload_cache (tbkey_t key, unsigned side, index_t idx) 
- /* output to the least used block of the cache */ 
- { 
-         dtm_block_t             *dtm_block; 
-         wdl_block_t     *to_modify; 
-         bool_t                  ok; 
-   
-         FOLLOW_label("wdl preload_cache starts") 
-   
-         if (idx >= egkey[key].maxindex) { 
-                 FOLLOW_LULU("Wrong index", __LINE__, idx) 
-                 return FALSE; 
-         } 
-   
-         /* find fresh block in dtm cache */ 
-         dtm_block = dtm_cache_pointblock (key, side, idx); 
-   
-         /* find aged blocked in wdl cache */ 
-         to_modify = wdl_point_block_to_replace (); 
-   
-         ok = !(NULL == dtm_block || NULL == to_modify); 
-   
-         if (!ok) 
-                 return FALSE; 
-   
-         /* transform and move a block */ 
-         dtm_block_2_wdl_block(dtm_block, to_modify, dtm_cache.entries_per_block); 
-   
-         if (ok) { 
-                 index_t                 offset; 
-                 index_t                 remainder; 
-                 split_index (wdl_cache.entries_per_block, idx, &offset, &remainder); 
-   
-                 to_modify->key    = key; 
-                 to_modify->side   = side; 
-                 to_modify->offset = offset; 
-                 wdl_hash_insert (to_modify); 
-         } else { 
-                 /* make it unusable */ 
-                 to_modify->key    = -1; 
-                 to_modify->side   = gtbNOSIDE; 
-                 to_modify->offset = gtbNOINDEX; 
-         } 
-   
-         FOLLOW_LU("wdl preload_cache?", ok) 
-   
-         return ok; 
- } 
-   
- /****************************************************************************************************/ 
-   
- static void 
- dtm_block_2_wdl_block(dtm_block_t *g, wdl_block_t *w, size_t n) 
- { 
-         int width = 2; 
-         int shifting; 
-         size_t i; 
-         int j; 
-         unsigned int x ,y; 
-          dtm_t *s = g->p_arr; 
-         unit_t *d = w->p_arr; 
-   
-         for (i = 0, y = 0; i < n; i++) { 
-                 j =  i & 3; /* modulo WDL_entries_per_unit */ 
-                 x = dtm2WDL(s[i]); 
-                 shifting = j * width; 
-                 y |= (x << shifting); 
-   
-                 if (j == 3) { 
-                         d[i/WDL_entries_per_unit] = (unit_t) y; 
-                         y = 0; 
-                 } 
-         } 
-   
-         if (0 != (n & 3)) { /* not multiple of 4 */ 
-                 d[(n-1)/WDL_entries_per_unit] = (unit_t) y; /* save the rest     */ 
-                 y = 0; 
-         } 
-   
-         return; 
- } 
-   
- static unsigned 
- dtm2WDL(dtm_t dtm) 
- { 
-         return (unsigned) dtm & 3; 
- } 
-   
-   
- /**************************/ 
- #ifdef WDL_PROBE 
-   
- static unsigned int     inv_wdl(unsigned w); 
- static bool_t   egtb_get_wdl (tbkey_t k, unsigned stm, const SQUARE *wS, const SQUARE *bS, bool_t probe_hard_flag, unsigned int *wdl); 
-   
- static bool_t 
- tb_probe_wdl 
-                         (unsigned stm, 
-                          const SQUARE *inp_wSQ, 
-                          const SQUARE *inp_bSQ, 
-                          const SQ_CONTENT *inp_wPC, 
-                          const SQ_CONTENT *inp_bPC, 
-                          bool_t probingtype, 
-                          /*@out@*/ unsigned *res) 
- { 
-         tbkey_t id = -1; 
-         unsigned int wdl = iUNKNOWN; 
-   
-         SQUARE          storage_ws [MAX_LISTSIZE], storage_bs [MAX_LISTSIZE]; 
-         SQ_CONTENT  storage_wp [MAX_LISTSIZE], storage_bp [MAX_LISTSIZE]; 
-   
-         SQUARE     *ws = storage_ws; 
-         SQUARE     *bs = storage_bs; 
-         SQ_CONTENT *wp = storage_wp; 
-         SQ_CONTENT *bp = storage_bp; 
-         SQUARE          tmp_ws [MAX_LISTSIZE], tmp_bs [MAX_LISTSIZE]; 
-         SQ_CONTENT  tmp_wp [MAX_LISTSIZE], tmp_bp [MAX_LISTSIZE]; 
-   
-         SQUARE *temps; 
-         bool_t straight = FALSE; 
-   
-         bool_t  okcall  = TRUE; 
-         unsigned ply_; 
-         unsigned *ply = &ply_; 
-   
-         /************************************/ 
-   
-         assert (- stm  ==-  WH  ||-  stm  ==-  BL );
 
-   
-         /* VALID ONLY FOR KK!! */ 
-         if (inp_wPC[1] == NOPIECE && inp_bPC[1] == NOPIECE) { 
-                 index_t dummy_i; 
-                 bool_t b = kxk_pctoindex (inp_wSQ, inp_bSQ, &dummy_i); 
-                 *res = b? iDRAW: iFORBID; 
-                 *ply = 0; 
-                 return TRUE; 
-         } 
-   
-         /* copy input */ 
-         list_pc_copy (inp_wPC, wp); 
-         list_pc_copy (inp_bPC, bp); 
-         list_sq_copy (inp_wSQ, ws); 
-         list_sq_copy (inp_bSQ, bs); 
-   
-         sortlists (ws, wp); 
-         sortlists (bs, bp); 
-   
-         FOLLOW_label("EGTB_PROBE") 
-   
-         if (egtb_get_id (wp, bp, &id)) { 
-                 FOLLOW_LU("got ID",id) 
-                 straight = TRUE; 
-         } else if (egtb_get_id (bp, wp, &id)) { 
-                 FOLLOW_LU("rev ID",id) 
-                 straight = FALSE; 
-                 list_sq_flipNS (ws); 
-                 list_sq_flipNS (bs); 
-         temps = ws; 
-         ws = bs; 
-         bs = temps; 
-                 stm = Opp(stm); 
-                 /* no enpassant in this fuction, so no adjustment */ 
-                 {SQ_CONTENT *tempp = wp; wp = bp; bp = tempp;}  /* added */ 
-         } else { 
-                 #if defined(DEBUG) 
-                 printf("did not get id...\n"); 
-                 output_state (stm, ws, bs, wp, bp); 
-                 #endif 
-                 unpackdist (iFORBID, res, ply); 
-                 return FALSE; 
-         } 
-   
-         /* store position... */ 
-         list_pc_copy (wp, tmp_wp); 
-         list_pc_copy (bp, tmp_bp); 
-         list_sq_copy (ws, tmp_ws); 
-         list_sq_copy (bs, tmp_bs); 
-   
-         /* x will be stm and y will be stw */ 
- /* 
-         if (stm == WH) { 
-         xs = ws; 
-         xp = wp; 
-         ys = bs; 
-         yp = bp; 
-     } else { 
-         xs = bs; 
-         xp = bp; 
-         ys = ws; 
-         yp = wp; 
-         } 
- */ 
-         okcall = egtb_get_wdl (id, stm, ws, bs, probingtype, &wdl); 
-   
-         FOLLOW_LU("dtmok?",okcall) 
-         FOLLOW_DTM("wdl", wdl) 
-   
-         if (okcall) { 
-   
-                 /*assert(epsq == NOSQUARE); */ 
-   
-                 if (straight) { 
-                         *res = wdl; 
-                 } else { 
-                         *res = inv_wdl (wdl); 
-                 } 
-         } else { 
-                         unpackdist (iFORBID, res, ply); 
-         } 
-   
-         return okcall; 
- } 
-   
- static unsigned int 
- inv_wdl(unsigned w) 
- { 
-         unsigned r = tb_UNKNOWN; 
-         switch (w) { 
-                 case tb_DRAW:    r = tb_DRAW;    break; 
-                 case tb_WMATE:   r = tb_BMATE;   break; 
-                 case tb_BMATE:   r = tb_WMATE;   break; 
-                 case tb_FORBID:  r = tb_FORBID;  break; 
-                 case tb_UNKNOWN: r = tb_UNKNOWN; break; 
-                 default:         r = tb_UNKNOWN; break; 
-         } 
-         return r; 
- } 
-   
- static bool_t 
- egtb_get_wdl (tbkey_t k, unsigned stm, const SQUARE *wS, const SQUARE *bS, bool_t probe_hard_flag, unsigned int *wdl) 
- { 
-         bool_t idxavail; 
-         index_t idx; 
-         dtm_t *tab[2]; 
-         bool_t (*pc2idx) (const SQUARE *, const SQUARE *, index_t *); 
-   
-         FOLLOW_label("egtb_get_wdl --> starts") 
-   
-         if (egkey[k].status == STATUS_MALLOC || egkey[k].status == STATUS_STATICRAM) { 
-   
-                 tab[WH] = egkey[k].egt_w; 
-                 tab[BL] = egkey[k].egt_b; 
-                 pc2idx  = egkey[k].pctoi; 
-   
-                 idxavail = pc2idx (wS, bS, &idx); 
-   
-                 FOLLOW_LU("indexavail (RAM)",idxavail) 
-   
-                 if (idxavail) { 
-                         *wdl = dtm2WDL(tab[stm][idx]); 
-                 } else { 
-                         *wdl = dtm2WDL(iFORBID); 
-                 } 
-   
-                 return FALSE; 
-   
-         } else if (egkey[k].status == STATUS_ABSENT) { 
-   
-                 pc2idx   = egkey[k].pctoi; 
-                 idxavail = pc2idx (wS, bS, &idx); 
-   
-                 FOLLOW_LU("indexavail (HD)",idxavail) 
-   
-                 if (idxavail) { 
-                         bool_t success; 
-   
-                         /* 
-                         |               LOCK 
-                         *-------------------------------*/ 
-                         mythread_mutex_lock (&Egtb_lock); 
-   
-                         success = get_WDL (k, stm, idx, wdl, probe_hard_flag); 
-                         FOLLOW_LU("get_wld (succ)",success) 
-                         FOLLOW_LU("get_wld (wdl )",*wdl) 
-   
-                         /* this may not be needed */ 
-                         if (!success) { 
-                                 dtm_t dtm; 
-                                 unsigned res, ply; 
-                                 if (probe_hard_flag && Uncompressed) { 
-                                         success = egtb_filepeek (k, stm, idx, &dtm); 
-                                         unpackdist (dtm, &res, &ply); 
-                                         *wdl = res; 
-                                 } 
-                                 else 
-                                         success = FALSE; 
-                         } 
-   
-                         mythread_mutex_unlock (&Egtb_lock); 
-                         /*------------------------------*\ 
-                         |               UNLOCK 
-                         */ 
-   
-                         if (success) { 
-                                 return TRUE; 
-                         } else { 
-                                 if (probe_hard_flag) /* after probing hard and failing, no chance to succeed later */ 
-                                         egkey[k].status = STATUS_REJECT; 
-                                 *wdl = dtm2WDL(iUNKNOWN); 
-                                 return FALSE; 
-                         } 
-   
-                 } else { 
-                         *wdl = dtm2WDL(iFORBID); 
-                         return  TRUE; 
-                 } 
-         } else if (egkey[k].status == STATUS_REJECT) { 
-                 FOLLOW_label("STATUS_REJECT") 
-                 *wdl = dtm2WDL(iFORBID); 
-                 return  FALSE; 
-         } else { 
-                 FOLLOW_label("STATUS_WRONG!") 
-                 *wdl = dtm2WDL(iFORBID); 
-                 return  FALSE; 
-         } 
-   
- } 
- #endif 
-   
-   
-   
-