home *** CD-ROM | disk | FTP | other *** search
/ Dream 57 / Amiga_Dream_57.iso / Amiga / Jeux / Reflexion / Crafty-15.19.lha / crafty-15.19 / src / init.c < prev    next >
C/C++ Source or Header  |  1998-09-26  |  51KB  |  1,605 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "chess.h"
  5. #include "data.h"
  6. #if defined(UNIX) || defined(AMIGA)
  7. #  include <unistd.h>
  8. #endif
  9. #include "epdglue.h"
  10. #if defined(NT_i386) || defined(NT_AXP)
  11. #  include <fcntl.h>  /* needed for definition of "_O_BINARY" */
  12. #endif
  13. #if defined(AMIGA)
  14. #include <proto/exec.h>
  15. #include <exec/memory.h>
  16. static unsigned long largest_chunk ;
  17. #endif
  18.  
  19. #if defined(COMPACT_ATTACKS)
  20. extern unsigned char init_l90[];
  21. extern unsigned char init_l45[];
  22. extern unsigned char init_r45[];
  23. #else
  24. int init_r90[64] = { 56, 48, 40, 32, 24, 16,  8,  0,
  25.                      57, 49, 41, 33, 25, 17,  9,  1,
  26.                      58, 50, 42, 34, 26, 18, 10,  2,
  27.                      59, 51, 43, 35, 27, 19, 11,  3,
  28.                      60, 52, 44, 36, 28, 20, 12,  4,
  29.                      61, 53, 45, 37, 29, 21, 13,  5,
  30.                      62, 54, 46, 38, 30, 22, 14,  6,
  31.                      63, 55, 47, 39, 31, 23, 15,  7 };
  32.  
  33. int init_l90[64] = {  7, 15, 23, 31, 39, 47, 55, 63,
  34.                       6, 14, 22, 30, 38, 46, 54, 62,
  35.                       5, 13, 21, 29, 37, 45, 53, 61,
  36.                       4, 12, 20, 28, 36, 44, 52, 60,
  37.                       3, 11, 19, 27, 35, 43, 51, 59,
  38.                       2, 10, 18, 26, 34, 42, 50, 58,
  39.                       1,  9, 17, 25, 33, 41, 49, 57,
  40.                       0,  8, 16, 24, 32, 40, 48, 56 };
  41.  
  42. int init_l45[64] = {                0,
  43.                                   2,  5,
  44.                                 9, 14, 20,
  45.                              27, 35,  1,  4,
  46.                             8, 13, 19, 26, 34,
  47.                          42,  3,  7, 12, 18, 25,
  48.                        33, 41, 48,  6, 11, 17, 24,
  49.                      32, 40, 47, 53, 10, 16, 23, 31,
  50.                        39, 46, 52, 57, 15, 22, 30,
  51.                          38, 45, 51, 56, 60, 21,
  52.                            29, 37, 44, 50, 55,
  53.                              59, 62, 28, 36,
  54.                                43, 49, 54,
  55.                                  58, 61,
  56.                                    63 };
  57.  
  58. int init_ul45[64] = {               0,
  59.                                   8,  1,
  60.                                16,  9,  2,
  61.                              24, 17, 10,  3,
  62.                            32, 25, 18, 11,  4,
  63.                          40, 33, 26, 19, 12,  5,
  64.                        48, 41, 34, 27, 20, 13,  6,
  65.                      56, 49, 42, 35, 28, 21, 14,  7,
  66.                        57, 50, 43, 36, 29, 22, 15,
  67.                          58, 51, 44, 37, 30, 23,
  68.                            59, 52, 45, 38, 31,
  69.                              60, 53, 46, 39,
  70.                                61, 54, 47,
  71.                                  62, 55,
  72.                                    63 };
  73.  
  74. int init_r45[64] = {               28,
  75.                                  21, 15,
  76.                                10,  6,  3,
  77.                               1,  0, 36, 29,
  78.                            22, 16, 11,  7,  4,
  79.                           2, 43, 37, 30, 23, 17,
  80.                        12,  8,  5, 49, 44, 38, 31,
  81.                      24, 18, 13,  9, 54, 50, 45, 39,
  82.                        32, 25, 19, 14, 58, 55, 51,
  83.                          46, 40, 33, 26, 20, 61,
  84.                            59, 56, 52, 47, 41,
  85.                              34, 27, 63, 62,
  86.                                60, 57, 53,
  87.                                  48, 42,
  88.                                    35  };
  89.  
  90. int init_ur45[64] = {               7,
  91.                                   6, 15,
  92.                                 5, 14, 23,
  93.                               4, 13, 22, 31,
  94.                             3, 12, 21, 30, 39,
  95.                           2, 11, 20, 29, 38, 47,
  96.                         1, 10, 19, 28, 37, 46, 55,
  97.                       0,  9, 18, 27, 36, 45, 54, 63,
  98.                         8, 17, 26, 35, 44, 53, 62,
  99.                          16, 25, 34, 43, 52, 61,
  100.                            24, 33, 42, 51, 60,
  101.                              32, 41, 50, 59,
  102.                                40, 49, 58,
  103.                                  48, 57,
  104.                                    56 };
  105.  
  106. int diagonal_length[64] = {         1,
  107.                                   2,  2,
  108.                                 3,  3,  3,
  109.                               4,  4,  4,  4,
  110.                             5,  5,  5,  5,  5,
  111.                           6,  6,  6,  6,  6,  6,
  112.                         7,  7,  7,  7,  7,  7,  7,
  113.                       8,  8,  8,  8,  8,  8,  8,  8,
  114.                         7,  7,  7,  7,  7,  7,  7,
  115.                           6,  6,  6,  6,  6,  6,
  116.                             5,  5,  5,  5,  5,
  117.                               4,  4,  4,  4,
  118.                                 3,  3,  3,
  119.                                   2,  2,
  120.                                     1 };
  121. #endif
  122.  
  123. void Initialize(int continuing) {
  124. /*
  125.  ----------------------------------------------------------
  126. |                                                          |
  127. |   perform routine initialization.                        |
  128. |                                                          |
  129.  ----------------------------------------------------------
  130. */
  131.   int i, j, major, minor;
  132.   TREE *tree;
  133.  
  134. #if defined(SMP)
  135.   for (i=1;i<MAX_BLOCKS+1;i++) {
  136.     local[i]=(TREE*) malloc(sizeof(TREE));
  137.     local[i]->used=0;
  138.   }
  139.   local[0]->parent=(TREE*)-1;
  140. #endif
  141.  
  142.   tree=local[0];
  143.   i=0;
  144.   InitializeZeroMasks();
  145. #if defined(SMP)
  146.   InitializeSMP();
  147. #endif
  148.   InitializeMasks();
  149.   InitializeRandomHash();
  150.   InitializeAttackBoards();
  151.   InitializePawnMasks();
  152.   InitializePieceMasks();
  153.   InitializeChessBoard(&tree->position[0]);
  154. #if defined(NT_i386) || defined(NT_AXP)
  155.   _fmode = _O_BINARY;  /* set global file mode to binary to avoid text translation */
  156. #endif
  157.  
  158.   EGInit();
  159.  
  160.   tree->last[0]=tree->move_list;
  161.  
  162. #if defined(MACOS)
  163.   sprintf(log_filename,":%s:book.bin",book_path);
  164. #else
  165.   sprintf(log_filename,"%s/book.bin",book_path);
  166. #endif
  167.   book_file=fopen(log_filename,"rb+");
  168.   if (!book_file) {
  169.     book_file=fopen(log_filename,"rb");
  170.     if (!book_file) {
  171. #if defined(MACOS)
  172.       printf("unable to open book file [:%s:book.bin].\n",book_path);
  173. #else
  174.       printf("unable to open book file [%s/book.bin].\n",book_path);
  175. #endif
  176.       printf("book is disabled\n");
  177.     }
  178.     else {
  179. #if defined(MACOS)
  180.       printf("unable to open book file [:%s:book.bin] for \"write\".\n",book_path);
  181. #else
  182.       printf("unable to open book file [%s/book.bin] for \"write\".\n",book_path);
  183. #endif
  184.       printf("learning is disabled\n");
  185.     }
  186.   }
  187. #if defined(MACOS)
  188.   sprintf(log_filename,":%s:books.bin",book_path);
  189. #else
  190.   sprintf(log_filename,"%s/books.bin",book_path);
  191. #endif
  192.   books_file=fopen(log_filename,"rb");
  193. #if defined(MACOS)
  194.   if (!books_file) printf("unable to open book file [:%s:books.bin].\n",book_path);
  195. #else
  196.   if (!books_file) printf("unable to open book file [%s/books.bin].\n",book_path);
  197. #endif
  198.   if (book_file) {
  199.     fseek(book_file,-sizeof(int),SEEK_END);
  200.     fread(&major,sizeof(int),1,book_file);
  201.     minor=major&65535;
  202.     major=major>>16;
  203.     if (major<15 || (major==15 && minor<15)) {
  204.       Print(4095,"\nERROR!  book.bin not made by version 15.15 or later\n");
  205.       book_file=0;
  206.       books_file=0;
  207.     }
  208.   }
  209. #if defined(MACOS)
  210.   sprintf(log_filename,":%s:book.lrn",book_path);
  211. #else
  212.   sprintf(log_filename,"%s/book.lrn",book_path);
  213. #endif
  214.   book_lrn_file=fopen(log_filename,"a");
  215.   if (!book_lrn_file) {
  216. #if defined(MACOS)
  217.     printf("unable to open book learning file [:%s:book.lrn].\n",book_path);
  218. #else
  219.     printf("unable to open book learning file [%s/book.lrn].\n",book_path);
  220. #endif
  221.     printf("learning disabled.\n");
  222.     learning&=~(book_learning+result_learning);
  223.   }
  224.   if (learning&position_learning) {
  225. #if defined(MACOS)
  226.     sprintf(log_filename,":%s:position.bin",book_path);
  227. #else
  228.     sprintf(log_filename,"%s/position.bin",book_path);
  229. #endif
  230.     position_file=fopen(log_filename,"rb+");
  231.     if (position_file) {
  232.       fseek(position_file,0,SEEK_END);
  233.       if (ftell(position_file) == 0) {
  234.         fclose(position_file);
  235.         position_file=0;
  236.       }
  237.     }
  238.     if (!position_file) {
  239.       position_file=fopen(log_filename,"wb+");
  240.       if (position_file) {
  241.         fseek(position_file,0,SEEK_SET);
  242.         fwrite(&i,sizeof(int),1,position_file);
  243.         i--;
  244.         fwrite(&i,sizeof(int),1,position_file);
  245.       }
  246.       else {
  247. #if defined(MACOS)
  248.         printf("unable to open position learning file [:%s:position.bin].\n",book_path);
  249. #else
  250.         printf("unable to open position learning file [%s/position.bin].\n",book_path);
  251. #endif
  252.         printf("learning disabled.\n");
  253.         learning&=~position_learning;
  254.       }
  255.     }
  256. #if defined(MACOS)
  257.     sprintf(log_filename,":%s:position.lrn",book_path);
  258. #else
  259.     sprintf(log_filename,"%s/position.lrn",book_path);
  260. #endif
  261.     position_lrn_file=fopen(log_filename,"r");
  262.     if (!position_lrn_file) {
  263.       position_lrn_file=fopen(log_filename,"a");
  264.       fprintf(position_lrn_file,"position\n");
  265.     }
  266.     else {
  267.       fclose(position_lrn_file);
  268.       position_lrn_file=fopen(log_filename,"a");
  269.     }
  270.   }
  271.  
  272.   for (log_id=1;log_id <300;log_id++) {
  273. #if defined(MACOS)
  274.     sprintf(log_filename,":%s:log.%03d",log_path,log_id);
  275.     sprintf(history_filename,":%s:game.%03d",log_path,log_id);
  276. #else
  277.     sprintf(log_filename,"%s/log.%03d",log_path,log_id);
  278.     sprintf(history_filename,"%s/game.%03d",log_path,log_id);
  279. #endif
  280.     log_file=fopen(log_filename,"r");
  281.     if (!log_file) break;
  282.     fclose(log_file);
  283.   }
  284.   if (continuing) {
  285.     log_id--;
  286.     sprintf(log_filename,"%s/log.%03d",log_path,log_id);
  287.     sprintf(history_filename,"%s/game.%03d",log_path,log_id);
  288.     log_file=fopen(log_filename,"r+");
  289.     history_file=fopen(history_filename,"r+");
  290.     if (!log_file || !history_file) {
  291.       printf("\nsorry.  nothing to continue.\n\n");
  292.       sprintf(log_filename,"%s/log.%03d",log_path,1);
  293.       sprintf(history_filename,"%s/game.%03d",log_path,1);
  294.       log_file=fopen("log_filename","w");
  295.       history_file=fopen("history_filename","w+");
  296.     }
  297.     else {
  298.       sprintf(buffer,"read %s/game.%03d", log_path, log_id);
  299.       (void) Option(tree);
  300.     }
  301.   }
  302.   else {
  303.     log_file=fopen(log_filename,"w");
  304.     history_file=fopen(history_filename,"w+");
  305.   }
  306. #if defined( AMIGA )
  307.   largest_chunk = AvailMem(MEMF_LARGEST) / 2 ;
  308.   if (hash_table_size > (largest_chunk / (16*6))) {
  309.     hash_table_size = largest_chunk / (16 * 6) ;
  310.   }
  311. #endif /* AMIGA */
  312.   trans_ref_wa=malloc(16*hash_table_size);
  313.   trans_ref_wb=malloc(16*2*hash_table_size);
  314.   trans_ref_ba=malloc(16*hash_table_size);
  315.   trans_ref_bb=malloc(16*2*hash_table_size);
  316. #if defined( AMIGA )
  317.     largest_chunk = AvailMem(MEMF_LARGEST) / 2 ;
  318.     if (pawn_hash_table_size > (largest_chunk / sizeof(PAWN_HASH_ENTRY))) {
  319.         pawn_hash_table_size = largest_chunk / sizeof(PAWN_HASH_ENTRY) ;
  320.     }
  321. #endif /* AMIGA */
  322.   pawn_hash_table=malloc(sizeof(PAWN_HASH_ENTRY)*pawn_hash_table_size);
  323.   if (!trans_ref_wa || !trans_ref_wb || !trans_ref_ba || !trans_ref_bb ) {
  324.     printf("malloc() failed, not enough memory.\n");
  325.     free(trans_ref_wa);
  326.     free(trans_ref_wb);
  327.     free(trans_ref_ba);
  328.     free(trans_ref_bb);
  329.     free(pawn_hash_table);
  330.     hash_table_size=0;
  331.     pawn_hash_table_size=0;
  332.     log_hash=0;
  333.     log_pawn_hash=0;
  334.     trans_ref_wa=0;
  335.     trans_ref_wb=0;
  336.     trans_ref_ba=0;
  337.     trans_ref_bb=0;
  338.     pawn_hash_table=0;
  339.   }
  340.   else
  341.       InitializeHashTables();
  342.   hash_maska=(1<<log_hash)-1;
  343.   hash_maskb=(1<<(log_hash+1))-1;
  344.   pawn_hash_mask=((unsigned int) 037777777777)>>(32-log_pawn_hash);
  345.  
  346.   for (i=0;i<8;i++)
  347.     for (j=0;j<8;j++) {
  348.       pawn_value_b[i*8+j]=  pawn_value_w[(7-i)*8+j];
  349.       knight_value_b[i*8+j]=knight_value_w[(7-i)*8+j];
  350.       bishop_value_b[i*8+j]=bishop_value_w[(7-i)*8+j];
  351.       rook_value_b[i*8+j]=  rook_value_w[(7-i)*8+j];
  352.       queen_value_b[i*8+j]= queen_value_w[(7-i)*8+j];
  353.       king_value_b[i*8+j]=  king_value_w[(7-i)*8+j];
  354.     }
  355. }
  356.  
  357. void InitializeAttackBoards(void)
  358. {
  359.  
  360.   int i, j, frank, ffile, trank, tfile;
  361.   int sq, lastsq;
  362.   int knightsq[8]={-17,-15,-10,-6,6,10,15,17};
  363.   int bishopsq[4]={-9,-7,7,9};
  364.   int rooksq[4]={-8,-1,1,8};
  365.   BITBOARD sqs;
  366. /*
  367.    initialize pawn attack boards
  368. */
  369.   for(i=0;i<64;i++) {
  370.     w_pawn_attacks[i]=0;
  371.     if (i < 56)
  372.       for(j=2;j<4;j++) {
  373.         sq=i+bishopsq[j];
  374.         if((abs(sq/8-i/8)==1) &&
  375.            (abs((sq&7) - (i&7))==1) &&
  376.               (sq < 64) && (sq > -1))
  377.           w_pawn_attacks[i]=Or(w_pawn_attacks[i],Shiftr(mask_1,sq));
  378.       }
  379.     b_pawn_attacks[i]=0;
  380.     if (i > 7)
  381.       for(j=0;j<2;j++) {
  382.         sq=i+bishopsq[j];
  383.         if((abs(sq/8-i/8)==1) &&
  384.            (abs((sq&7)-(i&7))==1) &&
  385.               (sq < 64) && (sq > -1))
  386.           b_pawn_attacks[i]=Or(b_pawn_attacks[i],Shiftr(mask_1,sq));
  387.       }
  388.   }
  389. /*
  390.    initialize knight attack board
  391. */
  392.   for(i=0;i<64;i++) {
  393.     knight_attacks[i]=0;
  394.     frank=i/8;
  395.     ffile=i&7;
  396.     for(j=0;j<8;j++) {
  397.       sq=i+knightsq[j];
  398.       if((sq < 0) || (sq > 63)) continue;
  399.       trank=sq/8;
  400.       tfile=sq&7;
  401.       if((abs(frank-trank) > 2) ||
  402.          (abs(ffile-tfile) > 2)) continue;
  403.       knight_attacks[i]=Or(knight_attacks[i],Shiftr(mask_1,sq));
  404.     }
  405.   }
  406. /*
  407.    initialize bishop/queen attack boards and masks
  408. */
  409.   for(i=0;i<64;i++) {
  410.     bishop_attacks[i]=0;
  411.     for(j=0;j<4;j++) {
  412.       sq=i;
  413.       lastsq=sq;
  414.       sq=sq+bishopsq[j];
  415.       while((abs(sq/8-lastsq/8)==1) &&
  416.             (abs((sq&7)-(lastsq&7))==1) &&
  417.             (sq < 64) && (sq > -1)) {
  418.         bishop_attacks[i]=Or(bishop_attacks[i],Shiftr(mask_1,sq));
  419.         queen_attacks[i]=Or(queen_attacks[i],Shiftr(mask_1,sq));
  420.         if(bishopsq[j]==7)
  421.           plus7dir[i]=Or(plus7dir[i],Shiftr(mask_1,sq));
  422.         else if(bishopsq[j]==9)
  423.           plus9dir[i]=Or(plus9dir[i],Shiftr(mask_1,sq));
  424.         else if(bishopsq[j]==-7)
  425.           minus7dir[i]=Or(minus7dir[i],Shiftr(mask_1,sq));
  426.         else
  427.           minus9dir[i]=Or(minus9dir[i],Shiftr(mask_1,sq));
  428.         lastsq=sq;
  429.         sq=sq+bishopsq[j];
  430.       }
  431.     }
  432.   }
  433.   plus1dir[64]=0;
  434.   plus7dir[64]=0;
  435.   plus8dir[64]=0;
  436.   plus9dir[64]=0;
  437.   minus1dir[64]=0;
  438.   minus7dir[64]=0;
  439.   minus8dir[64]=0;
  440.   minus9dir[64]=0;
  441. /*
  442.    initialize rook/queen attack boards
  443. */
  444.   for(i=0;i<64;i++) {
  445.     rook_attacks[i]=0;
  446.     for(j=0;j<4;j++) {
  447.       sq=i;
  448.       lastsq=sq;
  449.       sq=sq+rooksq[j];
  450.       while((((abs(sq/8-lastsq/8)==1) &&
  451.              (abs((sq&7)-(lastsq&7))==0)) ||
  452.             ((abs(sq/8-lastsq/8)==0) &&
  453.              (abs((sq&7)-(lastsq&7))==1))) &&
  454.             (sq < 64) && (sq > -1)) {
  455.         rook_attacks[i]=Or(rook_attacks[i],Shiftr(mask_1,sq));
  456.         queen_attacks[i]=Or(queen_attacks[i],Shiftr(mask_1,sq));
  457.         if(rooksq[j]==1)
  458.           plus1dir[i]=Or(plus1dir[i],Shiftr(mask_1,sq));
  459.         else if(rooksq[j]==8)
  460.           plus8dir[i]=Or(plus8dir[i],Shiftr(mask_1,sq));
  461.         else if(rooksq[j]==-1)
  462.           minus1dir[i]=Or(minus1dir[i],Shiftr(mask_1,sq));
  463.         else
  464.           minus8dir[i]=Or(minus8dir[i],Shiftr(mask_1,sq));
  465.         lastsq=sq;
  466.         sq=sq+rooksq[j];
  467.       }
  468.     }
  469.   }
  470. /*
  471.    initialize king attack board
  472. */
  473.   for(i=0;i<64;i++) {
  474.     king_attacks[i]=0;
  475.     king_attacks_1[i]=0;
  476.     king_attacks_2[i]=0;
  477.     for (j=0;j<64;j++) {
  478.       if (Distance(i,j) == 1)
  479.         king_attacks[i]=Or(king_attacks[i],set_mask[j]);
  480.       if (Distance(i,j) <= 1)
  481.         king_attacks_1[i]=Or(king_attacks_1[i],set_mask[j]);
  482.       if (Distance(i,j) <= 2)
  483.         king_attacks_2[i]=Or(king_attacks_2[i],set_mask[j]);
  484.     }
  485.   }
  486. /*
  487.   direction[sq1][sq2] gives the "move direction" to move from
  488.   sq1 to sq2.  obstructed[sq1][sq2] gives a bit vector that indicates
  489.   which squares must be unoccupied in order for <sq1> to attack <sq2>,
  490.   assuming a sliding piece is involved.  to use this, you simply have
  491.   to Or(obstructed[sq1][sq2],occupied_squares) and if the result is
  492.   "0" then a sliding piece on sq1 would attack sq2 and vice-versa.
  493. */
  494.   for (i=0;i<64;i++) {
  495.     for (j=0;j<64;j++)
  496.       obstructed[i][j]=(BITBOARD) -1;
  497.     sqs=plus1dir[i];
  498.     while (sqs) {
  499.       j=FirstOne(sqs);
  500.       directions[i][j]=1;
  501.       obstructed[i][j]=Xor(plus1dir[i],plus1dir[j-1]);
  502.       Clear(j,sqs);
  503.     }
  504.     sqs=plus7dir[i];
  505.     while (sqs) {
  506.       j=FirstOne(sqs);
  507.       directions[i][j]=7;
  508.       obstructed[i][j]=Xor(plus7dir[i],plus7dir[j-7]);
  509.       Clear(j,sqs);
  510.     }
  511.     sqs=plus8dir[i];
  512.     while (sqs) {
  513.       j=FirstOne(sqs);
  514.       directions[i][j]=8;
  515.       obstructed[i][j]=Xor(plus8dir[i],plus8dir[j-8]);
  516.       Clear(j,sqs);
  517.     }
  518.     sqs=plus9dir[i];
  519.     while (sqs) {
  520.       j=FirstOne(sqs);
  521.       directions[i][j]=9;
  522.       obstructed[i][j]=Xor(plus9dir[i],plus9dir[j-9]);
  523.       Clear(j,sqs);
  524.     }
  525.     sqs=minus1dir[i];
  526.     while (sqs) {
  527.       j=FirstOne(sqs);
  528.       directions[i][j]=-1;
  529.       obstructed[i][j]=Xor(minus1dir[i],minus1dir[j+1]);
  530.       Clear(j,sqs);
  531.     }
  532.     sqs=minus7dir[i];
  533.     while (sqs) {
  534.       j=FirstOne(sqs);
  535.       directions[i][j]=-7;
  536.       obstructed[i][j]=Xor(minus7dir[i],minus7dir[j+7]);
  537.       Clear(j,sqs);
  538.     }
  539.     sqs=minus8dir[i];
  540.     while (sqs) {
  541.       j=FirstOne(sqs);
  542.       directions[i][j]=-8;
  543.       obstructed[i][j]=Xor(minus8dir[i],minus8dir[j+8]);
  544.       Clear(j,sqs);
  545.     }
  546.     sqs=minus9dir[i];
  547.     while (sqs) {
  548.       j=FirstOne(sqs);
  549.       directions[i][j]=-9;
  550.       obstructed[i][j]=Xor(minus9dir[i],minus9dir[j+9]);
  551.       Clear(j,sqs);
  552.     }
  553.   }
  554. #if defined(COMPACT_ATTACKS)
  555.   ComputeAttacksAndMobility();
  556. #else
  557.   {
  558.     int diag_sq[64] = {                0,
  559.                                      1,  0,
  560.                                    2,  1,  0,
  561.                                  3,  2,  1,  0,
  562.                                4,  3,  2,  1,  0,
  563.                              5,  4,  3,  2,  1,  0,
  564.                            6,  5,  4,  3,  2,  1,  0,
  565.                          7,  6,  5,  4,  3,  2,  1,  0,
  566.                            6,  5,  4,  3,  2,  1,  0,
  567.                              5,  4,  3,  2,  1,  0,
  568.                                4,  3,  2,  1,  0,
  569.                                  3,  2,  1,  0,
  570.                                    2,  1,  0,
  571.                                      1,  0,
  572.                                        0 };
  573.  
  574.     int bias_rl45[64] = {              0,
  575.                                      1,  1,
  576.                                    3,  3,  3,
  577.                                  6,  6,  6,  6,
  578.                               10, 10, 10, 10, 10,
  579.                             15, 15, 15, 15, 15, 15,
  580.                           21, 21, 21, 21, 21, 21, 21,
  581.                         28, 28, 28, 28, 28, 28, 28, 28,
  582.                           36, 36, 36, 36, 36, 36, 36,
  583.                             43, 43, 43, 43, 43, 43,
  584.                               49, 49, 49, 49, 49,
  585.                                 54, 54, 54, 54,
  586.                                   58, 58, 58,
  587.                                     61, 61,
  588.                                       63 };
  589.     int square, pcs, attacks;
  590.     int rsq, tsq;
  591.     int mask;
  592.  
  593. /*
  594.   initialize the rotated attack board that is based on the
  595.   normal chess
  596. */
  597.     for (square=0;square<64;square++) {
  598.       for (i=0;i<256;i++) {
  599.         rook_attacks_r0[square][i]=0;
  600.         rook_mobility_r0[square][i]=0;
  601.       }
  602.       for (pcs=0;pcs<256;pcs++) {
  603.         attacks=InitializeFindAttacks(7-File(square),pcs,8);
  604.         while (attacks) {
  605.           sq=first_ones_8bit[attacks];
  606.           rook_attacks_r0[square][pcs]=
  607.             Or(rook_attacks_r0[square][pcs],set_mask[(square&56)+sq]);
  608.           attacks=attacks&(~(1<<(7-sq)));
  609.         }
  610.         rook_mobility_r0[square][pcs]=PopCnt(rook_attacks_r0[square][pcs]);
  611.       }
  612.     }
  613. /*
  614.   initialize the rotated attack board that is based on one that
  615.   rotated left 90 degrees (which lines up a file horizontally,
  616.   rather than its normal vertical orientation.)
  617. */
  618.     for (square=0;square<64;square++) {
  619.       for (i=0;i<256;i++) {
  620.         rook_attacks_rl90[square][i]=0;
  621.         rook_mobility_rl90[square][i]=0;
  622.       }
  623.       for (pcs=0;pcs<256;pcs++) {
  624.         attacks=InitializeFindAttacks(Rank(square),pcs,8);
  625.         while (attacks) {
  626.           sq=first_ones_8bit[attacks];
  627.           rook_attacks_rl90[square][pcs]=
  628.             Or(rook_attacks_rl90[square][pcs],
  629.                set_mask[init_r90[((square&7)<<3)+sq]]);
  630.           attacks=attacks&(~(1<<(7-sq)));
  631.         }
  632.         rook_mobility_rl90[square][pcs]=PopCnt(rook_attacks_rl90[square][pcs]);
  633.       }
  634.     }
  635. /*
  636.   initialize the rotated attack board that is based on one that is
  637.   rotated left 45 degrees (which lines up the (a8-h1) diagonal
  638.   horizontally.
  639. */
  640.     for (square=0;square<64;square++) {
  641.       for (i=0;i<256;i++) {
  642.         bishop_attacks_rl45[square][i]=0;
  643.         bishop_mobility_rl45[square][i]=0;
  644.       }
  645.       for (pcs=0;pcs<(1<<diagonal_length[init_l45[square]]);pcs++) {
  646.         rsq=init_l45[square];
  647.         tsq=diag_sq[rsq];
  648.         attacks=InitializeFindAttacks(tsq,pcs,diagonal_length[rsq])<<
  649.                           (8-diagonal_length[rsq]);
  650.         while (attacks) {
  651.           sq=first_ones_8bit[attacks];
  652.           bishop_attacks_rl45[square][pcs]=
  653.             Or(bishop_attacks_rl45[square][pcs],
  654.                set_mask[init_ul45[sq+bias_rl45[rsq]]]);
  655.           attacks=attacks&(~(1<<(7-sq)));
  656.         }
  657.       }
  658.       mask=(1<<diagonal_length[init_l45[square]])-1;
  659.       for (pcs=0;pcs<256;pcs++) {
  660.         if ((pcs&mask) != pcs)
  661.           bishop_attacks_rl45[square][pcs]=
  662.             bishop_attacks_rl45[square][pcs&mask];
  663.         bishop_mobility_rl45[square][pcs]=
  664.           PopCnt(bishop_attacks_rl45[square][pcs]);
  665.       }
  666.     }
  667. /*
  668.   initialize the rotated attack board that is based on one that is
  669.   rotated right 45 degrees (which lines up the (a1-h8) diagonal
  670.   horizontally,
  671. */
  672.     for (square=0;square<64;square++) {
  673.       for (i=0;i<256;i++) {
  674.         bishop_attacks_rr45[square][i]=0;
  675.         bishop_mobility_rr45[square][i]=0;
  676.       }
  677.       for (pcs=0;pcs<(1<<diagonal_length[init_r45[square]]);pcs++) {
  678.         rsq=init_r45[square];
  679.         tsq=diag_sq[rsq];
  680.         attacks=InitializeFindAttacks(tsq,pcs,diagonal_length[rsq])<<
  681.                           (8-diagonal_length[rsq]);
  682.         while (attacks) {
  683.           sq=first_ones_8bit[attacks];
  684.           bishop_attacks_rr45[square][pcs]=
  685.             Or(bishop_attacks_rr45[square][pcs],
  686.                set_mask[init_ur45[sq+bias_rl45[rsq]]]);
  687.           attacks=attacks&(~(1<<(7-sq)));
  688.         }
  689.       }
  690.       mask=(1<<diagonal_length[init_r45[square]])-1;
  691.       for (pcs=0;pcs<256;pcs++) {
  692.         if ((pcs&mask) != pcs)
  693.           bishop_attacks_rr45[square][pcs]=
  694.             bishop_attacks_rr45[square][pcs&mask];
  695.         bishop_mobility_rr45[square][pcs]=
  696.           PopCnt(bishop_attacks_rr45[square][pcs]);
  697.       }
  698.     }
  699.   }
  700. #endif
  701. }
  702.  
  703. void InitializeChessBoard(SEARCH_POSITION *new_pos)
  704. {
  705.   int i;
  706.   TREE *tree=local[0];
  707.  
  708.   if (strlen(initial_position)) {
  709.     static char a1[80], a2[16], a3[16], a4[16], a5[16];
  710.     static char *args[16]={a1,a2,a3,a4,a5,a5,a5,a5,a5,a5,a5,a5,a5,a5,a5,a5};
  711.     int nargs;
  712.  
  713.     nargs=ReadParse(initial_position,args," ;");
  714.     SetBoard(nargs,args,1);
  715.   }
  716.   else {
  717.     for(i=0;i<64;i++) tree->pos.board[i]=empty;
  718.     new_pos->rule_50_moves=0;
  719.     opening=1;
  720.     middle_game=0;
  721.     end_game=0;
  722.     largest_positional_score=100;
  723. /*
  724.    place pawns
  725. */
  726.     for (i=0;i<8;i++) {
  727.       tree->pos.board[i+8]=pawn;
  728.       tree->pos.board[i+48]=-pawn;
  729.     }
  730. /*
  731.    place knights
  732. */
  733.     tree->pos.board[B1]=knight;
  734.     tree->pos.board[G1]=knight;
  735.     tree->pos.board[B8]=-knight;
  736.     tree->pos.board[G8]=-knight;
  737. /*
  738.    place bishops
  739. */
  740.     tree->pos.board[C1]=bishop;
  741.     tree->pos.board[F1]=bishop;
  742.     tree->pos.board[C8]=-bishop;
  743.     tree->pos.board[F8]=-bishop;
  744. /*
  745.    place rooks
  746. */
  747.     tree->pos.board[A1]=rook;
  748.     tree->pos.board[H1]=rook;
  749.     tree->pos.board[A8]=-rook;
  750.     tree->pos.board[H8]=-rook;
  751. /*
  752.    place queens
  753. */
  754.     tree->pos.board[D1]=queen;
  755.     tree->pos.board[D8]=-queen;
  756. /*
  757.    place kings
  758. */
  759.     tree->pos.board[E1]=king;
  760.     tree->pos.board[E8]=-king;
  761. /*
  762.    initialize castling status so all castling is legal.
  763. */
  764.     new_pos->w_castle=3;
  765.     new_pos->b_castle=3;
  766. /*
  767.    initialize 50 move counter.
  768. */
  769.     new_pos->rule_50_moves=0;
  770. /*
  771.    initialize enpassant status.
  772. */
  773.     new_pos->enpassant_target=0;
  774. /*
  775.    now, set the bit-boards.
  776. */
  777.     SetChessBitBoards(new_pos);
  778.   }
  779. }
  780.  
  781. void SetChessBitBoards(SEARCH_POSITION *new_pos)
  782. {
  783.   int i;
  784.   TREE *tree=local[0];
  785.   tree->pos.hash_key=0;
  786.   tree->pos.pawn_hash_key=0;
  787. /*
  788.    place pawns
  789. */
  790.   tree->pos.w_pawn=0;
  791.   tree->pos.b_pawn=0;
  792.   for (i=0;i<64;i++) {
  793.     if(tree->pos.board[i]==pawn) {
  794.       tree->pos.w_pawn=Or(tree->pos.w_pawn,set_mask[i]);
  795.       tree->pos.hash_key=Xor(tree->pos.hash_key,w_pawn_random[i]);
  796.       tree->pos.pawn_hash_key=tree->pos.pawn_hash_key^w_pawn_random32[i];
  797.     }
  798.     if(tree->pos.board[i]==-pawn) {
  799.       tree->pos.b_pawn=Or(tree->pos.b_pawn,set_mask[i]);
  800.       tree->pos.hash_key=Xor(tree->pos.hash_key,b_pawn_random[i]);
  801.       tree->pos.pawn_hash_key=tree->pos.pawn_hash_key^b_pawn_random32[i];
  802.     }
  803.   }
  804. /*
  805.    place knights
  806. */
  807.   tree->pos.w_knight=0;
  808.   tree->pos.b_knight=0;
  809.   for (i=0;i<64;i++) {
  810.     if(tree->pos.board[i] == knight) {
  811.       tree->pos.w_knight=Or(tree->pos.w_knight,set_mask[i]);
  812.       tree->pos.hash_key=Xor(tree->pos.hash_key,w_knight_random[i]);
  813.     }
  814.     if(tree->pos.board[i] == -knight) {
  815.       tree->pos.b_knight=Or(tree->pos.b_knight,set_mask[i]);
  816.       tree->pos.hash_key=Xor(tree->pos.hash_key,b_knight_random[i]);
  817.     }
  818.   }
  819. /*
  820.    place bishops
  821. */
  822.   tree->pos.w_bishop=0;
  823.   tree->pos.b_bishop=0;
  824.   for (i=0;i<64;i++) {
  825.     if(tree->pos.board[i] == bishop) {
  826.       tree->pos.w_bishop=Or(tree->pos.w_bishop,set_mask[i]);
  827.       tree->pos.hash_key=Xor(tree->pos.hash_key,w_bishop_random[i]);
  828.     }
  829.     if(tree->pos.board[i] == -bishop) {
  830.       tree->pos.b_bishop=Or(tree->pos.b_bishop,set_mask[i]);
  831.       tree->pos.hash_key=Xor(tree->pos.hash_key,b_bishop_random[i]);
  832.     }
  833.   }
  834. /*
  835.    place rooks
  836. */
  837.   tree->pos.w_rook=0;
  838.   tree->pos.b_rook=0;
  839.   for (i=0;i<64;i++) {
  840.     if(tree->pos.board[i] == rook) {
  841.       tree->pos.w_rook=Or(tree->pos.w_rook,set_mask[i]);
  842.       tree->pos.hash_key=Xor(tree->pos.hash_key,w_rook_random[i]);
  843.     }
  844.     if(tree->pos.board[i] == -rook) {
  845.       tree->pos.b_rook=Or(tree->pos.b_rook,set_mask[i]);
  846.       tree->pos.hash_key=Xor(tree->pos.hash_key,b_rook_random[i]);
  847.     }
  848.   }
  849. /*
  850.    place queens
  851. */
  852.   tree->pos.w_queen=0;
  853.   tree->pos.b_queen=0;
  854.   for (i=0;i<64;i++) {
  855.     if(tree->pos.board[i] == queen) {
  856.       tree->pos.w_queen=Or(tree->pos.w_queen,set_mask[i]);
  857.       tree->pos.hash_key=Xor(tree->pos.hash_key,w_queen_random[i]);
  858.     }
  859.     if(tree->pos.board[i] == -queen) {
  860.       tree->pos.b_queen=Or(tree->pos.b_queen,set_mask[i]);
  861.       tree->pos.hash_key=Xor(tree->pos.hash_key,b_queen_random[i]);
  862.     }
  863.   }
  864. /*
  865.    place kings
  866. */
  867.   for (i=0;i<64;i++) {
  868.     if(tree->pos.board[i] == king) {
  869.       tree->pos.white_king=i;
  870.       tree->pos.hash_key=Xor(tree->pos.hash_key,w_king_random[i]);
  871.     }
  872.     if(tree->pos.board[i] == -king) {
  873.       tree->pos.black_king=i;
  874.       tree->pos.hash_key=Xor(tree->pos.hash_key,b_king_random[i]);
  875.     }
  876.   }
  877.   if (new_pos->enpassant_target)
  878.     HashEP(new_pos->enpassant_target,tree->pos.hash_key);
  879.   if (!(new_pos->w_castle&1)) HashCastleW(0,tree->pos.hash_key);
  880.   if (!(new_pos->w_castle&2)) HashCastleW(1,tree->pos.hash_key);
  881.   if (!(new_pos->b_castle&1)) HashCastleB(0,tree->pos.hash_key);
  882.   if (!(new_pos->b_castle&2)) HashCastleB(1,tree->pos.hash_key);
  883. /*
  884.    initialize combination boards that show multiple pieces.
  885. */
  886.   tree->pos.bishops_queens=Or(Or(Or(tree->pos.w_bishop,tree->pos.w_queen),tree->pos.b_bishop),tree->pos.b_queen);
  887.   tree->pos.rooks_queens=Or(Or(Or(tree->pos.w_rook,tree->pos.w_queen),tree->pos.b_rook),tree->pos.b_queen);
  888.   tree->pos.w_occupied=Or(Or(Or(Or(Or(tree->pos.w_pawn,tree->pos.w_knight),tree->pos.w_bishop),tree->pos.w_rook),
  889.                                    tree->pos.w_queen),set_mask[tree->pos.white_king]);
  890.   tree->pos.b_occupied=Or(Or(Or(Or(Or(tree->pos.b_pawn,tree->pos.b_knight),tree->pos.b_bishop),tree->pos.b_rook),
  891.                                    tree->pos.b_queen),set_mask[tree->pos.black_king]);
  892. /*
  893.   now initialize rotated occupied bitboards.
  894. */
  895.   tree->pos.occupied_rl90=0;
  896.   tree->pos.occupied_rl45=0;
  897.   tree->pos.occupied_rr45=0;
  898.   for (i=0;i<64;i++) {
  899.     if (tree->pos.board[i]) {
  900.       tree->pos.occupied_rl90=Or(tree->pos.occupied_rl90,set_mask_rl90[i]);
  901.       tree->pos.occupied_rl45=Or(tree->pos.occupied_rl45,set_mask_rl45[i]);
  902.       tree->pos.occupied_rr45=Or(tree->pos.occupied_rr45,set_mask_rr45[i]);
  903.     }
  904.   }
  905. /*
  906.    initialize black/white piece counts.
  907. */
  908.   tree->pos.white_pieces=0;
  909.   tree->pos.white_majors=0;
  910.   tree->pos.white_minors=0;
  911.   tree->pos.white_pawns=0;
  912.   tree->pos.black_pieces=0;
  913.   tree->pos.black_majors=0;
  914.   tree->pos.black_minors=0;
  915.   tree->pos.black_pawns=0;
  916.   tree->pos.material_evaluation=0;
  917.   for (i=0;i<64;i++) {
  918.     switch (tree->pos.board[i]) {
  919.       case pawn:
  920.         tree->pos.material_evaluation+=PAWN_VALUE;
  921.         tree->pos.white_pawns+=pawn_v;
  922.         break;
  923.       case knight:
  924.         tree->pos.material_evaluation+=KNIGHT_VALUE;
  925.         tree->pos.white_pieces+=knight_v;
  926.         tree->pos.white_minors++;
  927.         break;
  928.       case bishop:
  929.         tree->pos.material_evaluation+=BISHOP_VALUE;
  930.         tree->pos.white_pieces+=bishop_v;
  931.         tree->pos.white_minors++;
  932.         break;
  933.       case rook:
  934.         tree->pos.material_evaluation+=ROOK_VALUE;
  935.         tree->pos.white_pieces+=rook_v;
  936.         tree->pos.white_majors++;
  937.         break;
  938.       case queen:
  939.         tree->pos.material_evaluation+=QUEEN_VALUE;
  940.         tree->pos.white_pieces+=queen_v;
  941.         tree->pos.white_majors+=2;
  942.         break;
  943.       case -pawn:
  944.         tree->pos.material_evaluation-=PAWN_VALUE;
  945.         tree->pos.black_pawns+=pawn_v;
  946.         break;
  947.       case -knight:
  948.         tree->pos.material_evaluation-=KNIGHT_VALUE;
  949.         tree->pos.black_pieces+=knight_v;
  950.         tree->pos.black_minors++;
  951.         break;
  952.       case -bishop:
  953.         tree->pos.material_evaluation-=BISHOP_VALUE;
  954.         tree->pos.black_pieces+=bishop_v;
  955.         tree->pos.black_minors++;
  956.         break;
  957.       case -rook:
  958.         tree->pos.material_evaluation-=ROOK_VALUE;
  959.         tree->pos.black_pieces+=rook_v;
  960.         tree->pos.black_majors++;
  961.         break;
  962.       case -queen:
  963.         tree->pos.material_evaluation-=QUEEN_VALUE;
  964.         tree->pos.black_pieces+=queen_v;
  965.         tree->pos.black_majors+=2;
  966.         break;
  967.       default:
  968.         ;
  969.     }
  970.   }
  971.   TotalPieces=PopCnt(Occupied);
  972.   if (new_pos == &tree->position[0]) {
  973.     tree->rephead_b=tree->replist_b;
  974.     tree->rephead_w=tree->replist_w;
  975.   }
  976. }
  977.  
  978. /*
  979. ********************************************************************************
  980. *                                                                              *
  981. *   Initlialize_Find_Attacks() is used to find the attacks from <square> that  *
  982. *   exist on the 8-bit vector supplied as <pieces>.  <pieces> represents a     *
  983. *   rank, file or diagonal, based on the rotated bit-boards.                   *
  984. *                                                                              *
  985. ********************************************************************************
  986. */
  987. int InitializeFindAttacks(int square, int pieces, int length)
  988. {
  989.   int result, start;
  990.   result=0;
  991. /*
  992.  ----------------------------------------------------------
  993. |                                                          |
  994. |   find attacks to left of <square>.                      |
  995. |                                                          |
  996.  ----------------------------------------------------------
  997. */
  998.   if (square < 7) {
  999.     start=1<<(square+1);
  1000.     while (start < 256) {
  1001.       result=result | start;
  1002.       if (pieces & start) break;
  1003.       start=start<<1;
  1004.     }
  1005.   }
  1006. /*
  1007.  ----------------------------------------------------------
  1008. |                                                          |
  1009. |   find attacks to left of <square>.                      |
  1010. |                                                          |
  1011.  ----------------------------------------------------------
  1012. */
  1013.   if (square > 0) {
  1014.     start=1<<(square-1);
  1015.     while (start > 0) {
  1016.       result=result | start;
  1017.       if (pieces & start) break;
  1018.       start=start>>1;
  1019.     }
  1020.   }
  1021. /*
  1022.   printf("square=%d  pieces=%d\n",square,pieces);
  1023.   printf("result=%d\n",result);
  1024.   printf("length=%d  result=%d\n",length,result&(1<<length)-1);
  1025. */
  1026.   return(result&((1<<length)-1));
  1027. }
  1028.  
  1029. void InitializeHashTables(void)
  1030. {
  1031.   int i;
  1032.   transposition_id=0;
  1033.   for (i=0;i<hash_table_size;i++) {
  1034.     (trans_ref_wa+i)->word1=Shiftl((BITBOARD) 7,61);
  1035.     (trans_ref_wa+i)->word2=0;
  1036.     (trans_ref_ba+i)->word1=Shiftl((BITBOARD) 7,61);
  1037.     (trans_ref_ba+i)->word2=0;
  1038.   }
  1039.   for (i=0;i<2*hash_table_size;i++) {
  1040.     (trans_ref_wb+i)->word1=Shiftl((BITBOARD) 7,61);
  1041.     (trans_ref_wb+i)->word2=0;
  1042.     (trans_ref_bb+i)->word1=Shiftl((BITBOARD) 7,61);
  1043.     (trans_ref_bb+i)->word2=0;
  1044.   }
  1045.   for (i=0;i<pawn_hash_table_size;i++) {
  1046.     (pawn_hash_table+i)->key=0;
  1047.     (pawn_hash_table+i)->p_score=0;
  1048.     (pawn_hash_table+i)->black_protected=0;
  1049.     (pawn_hash_table+i)->white_protected=0;
  1050.     (pawn_hash_table+i)->black_pof=0;
  1051.     (pawn_hash_table+i)->white_pof=0;
  1052.     (pawn_hash_table+i)->weak_b=0;
  1053.     (pawn_hash_table+i)->weak_w=0;
  1054.     (pawn_hash_table+i)->black_defects_k=0;
  1055.     (pawn_hash_table+i)->black_defects_q=0;
  1056.     (pawn_hash_table+i)->white_defects_k=0;
  1057.     (pawn_hash_table+i)->white_defects_q=0;
  1058.     (pawn_hash_table+i)->passed_w=0;
  1059.     (pawn_hash_table+i)->passed_w=0;
  1060.     (pawn_hash_table+i)->outside=0;
  1061.   }
  1062. }
  1063.  
  1064. void InitializeMasks(void) {
  1065.   int i, j;
  1066. /*
  1067.   specific masks to avoid Mask() procedure call if possible.
  1068. */
  1069. #  if !defined(CRAY1)
  1070.     mask_1=Mask(1);
  1071.     mask_2=Mask(2);
  1072.     mask_3=Mask(3);
  1073.     mask_4=Mask(4);
  1074.     mask_8=Mask(8);
  1075.     mask_16=Mask(16);
  1076.     mask_32=Mask(32);
  1077.     mask_72=Mask(72);
  1078.     mask_80=Mask(80);
  1079.     mask_85=Mask(85);
  1080.     mask_96=Mask(96);
  1081.     mask_107=Mask(107);
  1082.     mask_108=Mask(108);
  1083.     mask_112=Mask(112);
  1084.     mask_118=Mask(118);
  1085.     mask_120=Mask(120);
  1086.     mask_121=Mask(121);
  1087.     mask_127=Mask(127);
  1088. #  endif
  1089.   mask_clear_entry=Compl(Or(Shiftl(Mask(109),21),Shiftr(Mask(3),3)));
  1090. /*
  1091.   masks to set/clear a bit on a specific square
  1092. */
  1093.   for (i=0;i<64;i++) {
  1094.     clear_mask[i]=Compl(Shiftr(mask_1,i));
  1095.     clear_mask_rl45[i]=Compl(Shiftr(mask_1,init_l45[i]));
  1096.     clear_mask_rr45[i]=Compl(Shiftr(mask_1,init_r45[i]));
  1097.     clear_mask_rl90[i]=Compl(Shiftr(mask_1,init_l90[i]));
  1098.     set_mask[i]=Shiftr(mask_1,i);
  1099.     set_mask_rl45[i]=Shiftr(mask_1,init_l45[i]);
  1100.     set_mask_rr45[i]=Shiftr(mask_1,init_r45[i]);
  1101.     set_mask_rl90[i]=Shiftr(mask_1,init_l90[i]);
  1102.   }
  1103.   clear_mask[BAD_SQUARE]=0;
  1104.   clear_mask_rl45[BAD_SQUARE]=0;
  1105.   clear_mask_rr45[BAD_SQUARE]=0;
  1106.   clear_mask_rl90[BAD_SQUARE]=0;
  1107.   set_mask[BAD_SQUARE]=0;
  1108.   set_mask_rl45[BAD_SQUARE]=0;
  1109.   set_mask_rr45[BAD_SQUARE]=0;
  1110.   set_mask_rl90[BAD_SQUARE]=0;
  1111. /*
  1112.   masks to select bits on a specific rank or file
  1113. */
  1114.   rank_mask[0]=mask_8;
  1115.   for (i=1;i<8;i++) rank_mask[i]=Shiftr(rank_mask[i-1],8);
  1116.   file_mask[FILEA]=mask_1;
  1117.   for (i=1;i<8;i++) file_mask[FILEA]=Or(file_mask[FILEA],Shiftr(file_mask[FILEA],8));
  1118.   for (i=1;i<8;i++) file_mask[i]=Shiftr(file_mask[i-1],1);
  1119. /*
  1120.   masks to determine if a pawn is protected by another pawn or not.
  1121. */
  1122.   for (i=8;i<56;i++) {
  1123.    mask_pawn_protected_w[i]=Or(set_mask[i-1],set_mask[i+1]);
  1124.    if (i > 15) mask_pawn_protected_w[i]|=Or(set_mask[i-7],set_mask[i-9]);
  1125.    mask_pawn_protected_b[i]=Or(set_mask[i-1],set_mask[i+1]);
  1126.    if (i < 48) mask_pawn_protected_b[i]|=Or(set_mask[i+7],set_mask[i+9]);
  1127.   }
  1128. /*
  1129.   masks to select bits on either half of board
  1130. */
  1131.   for (i=0;i<8;i++) {
  1132.     right_side_mask[i]=0;
  1133.     for (j=i+2;j<8;j++)
  1134.       right_side_mask[i]=Or(right_side_mask[i],file_mask[j]);
  1135.     left_side_mask[i]=0;
  1136.     for (j=i-2;j>=0;j--)
  1137.       left_side_mask[i]=Or(left_side_mask[i],file_mask[j]);
  1138.   }
  1139.   for (i=0;i<8;i++) {
  1140.     right_side_empty_mask[i]=0;
  1141.     for (j=i+1;j<8;j++)
  1142.       right_side_empty_mask[i]=Or(right_side_empty_mask[i],file_mask[j]);
  1143.     left_side_empty_mask[i]=0;
  1144.     for (j=i-1;j>=0;j--)
  1145.       left_side_empty_mask[i]=Or(left_side_empty_mask[i],file_mask[j]);
  1146.   }
  1147.   right_half_mask=Or(Or(Or(file_mask[FILEE],file_mask[FILEF]),file_mask[FILEG]),file_mask[FILEH]);
  1148.   left_half_mask=Or(Or(Or(file_mask[FILEA],file_mask[FILEB]),file_mask[FILEC]),file_mask[FILED]);
  1149.   mask_kr_trapped_w[0]=set_mask[H2];
  1150.   mask_kr_trapped_w[1]=Or(set_mask[H1],set_mask[H2]);
  1151.   mask_kr_trapped_w[2]=Or(Or(set_mask[G1],set_mask[H1]),set_mask[H2]);
  1152.   mask_qr_trapped_w[0]=set_mask[A2];
  1153.   mask_qr_trapped_w[1]=Or(set_mask[A1],set_mask[A2]);
  1154.   mask_qr_trapped_w[2]=Or(Or(set_mask[A1],set_mask[B1]),set_mask[A2]);
  1155.   mask_kr_trapped_b[0]=set_mask[H7];
  1156.   mask_kr_trapped_b[1]=Or(set_mask[H8],set_mask[H7]);
  1157.   mask_kr_trapped_b[2]=Or(Or(set_mask[H8],set_mask[G8]),set_mask[H7]);
  1158.   mask_qr_trapped_b[0]=set_mask[A7];
  1159.   mask_qr_trapped_b[1]=Or(set_mask[A8],set_mask[A7]);
  1160.   mask_qr_trapped_b[2]=Or(Or(set_mask[A8],set_mask[B8]),set_mask[A7]);
  1161.  
  1162.   mask_abs7_w=Xor(rank_mask[RANK7],Or(set_mask[H7],set_mask[A7]));
  1163.   mask_abs7_b=Xor(rank_mask[RANK2],Or(set_mask[H2],set_mask[A2]));
  1164.  
  1165.   mask_not_rank8=~rank_mask[RANK8];
  1166.   mask_not_rank1=~rank_mask[RANK1];
  1167.  
  1168.   mask_A7H7=Or(set_mask[A7],set_mask[H7]);
  1169.   mask_A2H2=Or(set_mask[A2],set_mask[H2]);
  1170.   center=Or(Or(set_mask[D4],set_mask[E4]),
  1171.             Or(set_mask[D5],set_mask[E5]));
  1172.   threat_flag=Shiftl((BITBOARD) 1, 58);
  1173. }
  1174.  
  1175. void InitializePawnMasks(void)
  1176. {
  1177.   int i;
  1178.   BITBOARD m1,m2;
  1179. /*
  1180.     initialize isolated pawn masks, which are nothing more than 1's on
  1181.     the files adjacent to the pawn file.
  1182. */
  1183.   for (i=0;i<64;i++) {
  1184.     if (!(i&7)) mask_pawn_isolated[i]=file_mask[(i&7)+1];
  1185.     else if ((i&7) == 7) mask_pawn_isolated[i]=file_mask[(i&7)-1];
  1186.     else mask_pawn_isolated[i]=Or(file_mask[(i&7)-1],file_mask[(i&7)+1]);
  1187.   }
  1188. /*
  1189.     initialize connected pawn masks, which are nothing more than 1's on
  1190.     files adjacent to the pawn and ranks that are within 1 rank of the
  1191.     pawn.
  1192. */
  1193.   for (i=8;i<56;i++) {
  1194.     if (((i&7)>0) && ((i&7)<7))
  1195.       mask_pawn_connected[i]=Or(Or(Or(Or(Or(set_mask[i-9],set_mask[i-7]),
  1196.                                          set_mask[i-1]),
  1197.                                       set_mask[i+1]),
  1198.                                    set_mask[i+7]),
  1199.                                 set_mask[i+9]);
  1200.     else if ((i&7)==0)
  1201.       mask_pawn_connected[i]=Or(Or(set_mask[i-7],set_mask[i+1]),
  1202.                                 set_mask[i+9]);
  1203.     else if ((i&7)==7)
  1204.       mask_pawn_connected[i]=Or(Or(set_mask[i-9],set_mask[i-1]),
  1205.                                 set_mask[i+7]);
  1206.   }
  1207. /*
  1208.     initialize passed pawn masks, which are nothing more than 1's on
  1209.     the pawn's file and the adjacent files, but only on ranks that are
  1210.     in "front" of the pawn.
  1211. */
  1212.   for (i=0;i<64;i++) {
  1213.     if (!(i&7)) {
  1214.       mask_pawn_passed_w[i]=Or(plus8dir[i],plus8dir[i+1]);
  1215.       mask_pawn_passed_b[i]=Or(minus8dir[i],minus8dir[i+1]);
  1216.     }
  1217.     else if ((i&7) == 7) {
  1218.       mask_pawn_passed_w[i]=Or(plus8dir[i-1],plus8dir[i]);
  1219.       mask_pawn_passed_b[i]=Or(minus8dir[i-1],minus8dir[i]);
  1220.     }
  1221.     else {
  1222.       mask_pawn_passed_w[i]=Or(Or(plus8dir[i-1],plus8dir[i]),
  1223.                                plus8dir[i+1]);
  1224.       mask_pawn_passed_b[i]=Or(Or(minus8dir[i-1],minus8dir[i]),
  1225.                                minus8dir[i+1]);
  1226.     }
  1227.   }
  1228. /*
  1229.     these masks are used to determine if the other side has any pawns
  1230.     that can attack [square].
  1231. */
  1232.   for (i=8;i<56;i++) {
  1233.     if (!(i&7)) {
  1234.       mask_no_pawn_attacks_w[i]=minus8dir[i+1];
  1235.       mask_no_pawn_attacks_b[i]=plus8dir[i+1];
  1236.     }
  1237.     else if ((i&7) == 7) {
  1238.       mask_no_pawn_attacks_w[i]=minus8dir[i-1];
  1239.       mask_no_pawn_attacks_b[i]=plus8dir[i-1];
  1240.     }
  1241.     else {
  1242.       mask_no_pawn_attacks_w[i]=Or(minus8dir[i-1],minus8dir[i+1]);
  1243.       mask_no_pawn_attacks_b[i]=Or(plus8dir[i+1],plus8dir[i-1]);
  1244.     }
  1245.   }
  1246. /*
  1247.     enpassant pawns are on either file adjacent to the current file, and
  1248.     on the same rank.
  1249. */
  1250.   for (i=0;i<64;i++) mask_eptest[i]=0;
  1251.   for (i=25;i<31;i++) mask_eptest[i]=Or(set_mask[i-1],set_mask[i+1]);
  1252.   for (i=33;i<39;i++) mask_eptest[i]=Or(set_mask[i-1],set_mask[i+1]);
  1253.   mask_eptest[A4]=set_mask[B4];
  1254.   mask_eptest[H4]=set_mask[G4];
  1255.   mask_eptest[A5]=set_mask[B5];
  1256.   mask_eptest[H5]=set_mask[G5];
  1257.  
  1258. /*
  1259.   masks to detect pawns bearing down on the king
  1260. */
  1261.   mask_kingside_attack_w1=Or(Or(minus8dir[F5],minus8dir[G5]),
  1262.                              minus8dir[H5]);
  1263.   mask_kingside_attack_w2=Or(Or(minus8dir[F4],minus8dir[G4]),
  1264.                              minus8dir[H4]);
  1265.   mask_queenside_attack_w1=Or(Or(minus8dir[A5],minus8dir[B5]),
  1266.                               minus8dir[C5]);
  1267.   mask_queenside_attack_w2=Or(Or(minus8dir[A4],minus8dir[B4]),
  1268.                               minus8dir[C4]);
  1269.   mask_kingside_attack_b1=Or(Or(plus8dir[F4],plus8dir[G4]),
  1270.                              plus8dir[H4]);
  1271.   mask_kingside_attack_b2=Or(Or(plus8dir[F5],plus8dir[G5]),
  1272.                              plus8dir[H5]);
  1273.   mask_queenside_attack_b1=Or(Or(plus8dir[A4],plus8dir[B4]),
  1274.                               plus8dir[C4]);
  1275.   mask_queenside_attack_b2=Or(Or(plus8dir[A5],plus8dir[B5]),
  1276.                               plus8dir[C5]);
  1277. /*
  1278.   pawns at d5/e5/f5 cramp black, and pawns at d4/e4/f4 cramp
  1279.   white, especially if there are no pawns that can attack
  1280.   these pawns.
  1281. */
  1282.   pawns_cramp_black=Or(Or(set_mask[D5],set_mask[E5]),
  1283.                        set_mask[F5]);
  1284.   pawns_cramp_white=Or(Or(set_mask[D4],set_mask[E4]),
  1285.                        set_mask[F4]);
  1286. /*
  1287.   these two masks have 1's on dark squares and light squares
  1288.   to test to see if pawns/bishops are on them.
  1289. */
  1290.   m1=Mask(1);
  1291.   m2=Shiftr(m1,1);
  1292.   for (i=1;i<4;i++) {
  1293.     m1=Or(m1,Shiftr(m1,2));
  1294.     m2=Or(m2,Shiftr(m2,2));
  1295.   }
  1296.   for (i=0;i<64;i+=8) {
  1297.     if ((i/8)&1) {
  1298.       dark_squares=Or(dark_squares,Shiftr(m2,i));
  1299.       light_squares=Or(light_squares,Shiftr(m1,i));
  1300.     }
  1301.     else {
  1302.       dark_squares=Or(dark_squares,Shiftr(m1,i));
  1303.       light_squares=Or(light_squares,Shiftr(m2,i));
  1304.     }
  1305.   }
  1306. /*
  1307.   this mask is used to detect that one side has pawns, but all
  1308.   are rook pawns.
  1309. */
  1310.   not_rook_pawns=Or(Or(Or(file_mask[FILEB],file_mask[FILEC]),
  1311.                        Or(file_mask[FILED],file_mask[FILEE])),
  1312.                     Or(file_mask[FILEF],file_mask[FILEG]));
  1313. /*
  1314.   these two masks have 1's on everywhere but the left or right
  1315.   files, used to prevent pawns from capturing off the edge of
  1316.   the board and wrapping around.rom capturing off the edge of
  1317. */
  1318.   mask_left_edge=Compl(file_mask[FILEA]);
  1319.   mask_right_edge=Compl(file_mask[FILEH]);
  1320.   mask_advance_2_w=rank_mask[RANK3];
  1321.   mask_advance_2_b=rank_mask[RANK6];
  1322. /*
  1323.   this mask has 1's on the 4 corner squares, and is used to detect
  1324.   the king sitting right in the corner where it's easier to get
  1325.   mated.
  1326. */
  1327.   mask_corner_squares=Or(Or(set_mask[A1],set_mask[H1]),
  1328.                          Or(set_mask[A8],set_mask[H8]));
  1329. /*
  1330.   these masks have 1's on the squares where it is useful to have a bishop
  1331.   when the b or g pawn is missing or pushed one square.
  1332. */
  1333.   good_bishop_kw=Or(Or(set_mask[F1],set_mask[H1]),set_mask[G2]);
  1334.   good_bishop_qw=Or(Or(set_mask[A1],set_mask[C1]),set_mask[B2]);
  1335.   good_bishop_kb=Or(Or(set_mask[G7],set_mask[F8]),set_mask[H8]);
  1336.   good_bishop_qb=Or(Or(set_mask[B7],set_mask[A8]),set_mask[C8]);
  1337. /*
  1338.     these masks are used to detect when a passed pawn reaches the 6th or
  1339.     7th rank with a connected neighboring pawn also on the 6th or 7th rank
  1340.     so that the threat to promote is really significant.
  1341. */
  1342.   for (i=0;i<64;i++) {
  1343.     mask_promotion_threat_w[i]=0;
  1344.     mask_promotion_threat_b[i]=0;
  1345.   }
  1346.   for (i=8;i<24;i++) {
  1347.     if (!(i&7)) {
  1348.       mask_promotion_threat_b[i]=Or(set_mask[B2],set_mask[B3]);
  1349.     }
  1350.     else if ((i&7) == 7) {
  1351.       mask_promotion_threat_b[i]=Or(set_mask[G2],set_mask[G3]);
  1352.     }
  1353.     else {
  1354.       mask_promotion_threat_b[i]=Or(Or(set_mask[(i&7)+7],set_mask[(i&7)+9]),
  1355.                                     Or(set_mask[(i&7)+15],set_mask[(i&7)+17]));
  1356.     }
  1357.   }
  1358.   for (i=40;i<56;i++) {
  1359.     if (!(i&7)) {
  1360.       mask_promotion_threat_w[i]=Or(set_mask[B6],set_mask[B7]);
  1361.     }
  1362.     else if ((i&7) == 7) {
  1363.       mask_promotion_threat_w[i]=Or(set_mask[G6],set_mask[G7]);
  1364.     }
  1365.     else {
  1366.       mask_promotion_threat_w[i]=Or(Or(set_mask[(i&7)+39],set_mask[(i&7)+47]),
  1367.                                     Or(set_mask[(i&7)+41],set_mask[(i&7)+49]));
  1368.     }
  1369.   }
  1370. /*
  1371.   these two masks are for generating passed pawn pushes and are used to
  1372.   select the 6th-7th rank squares as targets.
  1373. */
  1374.   promote_mask_w=Compl(Or(rank_mask[5],rank_mask[6]));
  1375.   promote_mask_b=Compl(Or(rank_mask[1],rank_mask[2]));
  1376. /*
  1377.   these masks are used to test for the presence of a pawn at g2/g3, etc.
  1378.   and are used in evaluating a bishop potentially trapped at h2, etc.
  1379. */
  1380.   mask_G2G3=Or(set_mask[G2],set_mask[G3]);
  1381.   mask_B2B3=Or(set_mask[B2],set_mask[B3]);
  1382.   mask_G6G7=Or(set_mask[G6],set_mask[G7]);
  1383.   mask_B6B7=Or(set_mask[B6],set_mask[B7]);
  1384. /*
  1385.   these masks are used to detect that opponent pawns are getting very
  1386.   close to the king.
  1387. */
  1388.   mask_wq_4th=Or(Or(set_mask[A4],set_mask[B4]),
  1389.                  set_mask[C4]);
  1390.   mask_wq_5th=Or(Or(set_mask[A5],set_mask[B5]),
  1391.                  set_mask[C5]);
  1392.   mask_wk_4th=Or(Or(set_mask[F4],set_mask[G4]),
  1393.                  set_mask[H4]);
  1394.   mask_wk_5th=Or(Or(set_mask[F5],set_mask[G5]),
  1395.                  set_mask[H5]);
  1396.   mask_bk_4th=mask_wk_5th;
  1397.   mask_bq_4th=mask_wq_5th;
  1398.   mask_bk_5th=mask_wk_4th;
  1399.   mask_bq_5th=mask_wq_4th;
  1400.  
  1401. /*
  1402.   these masks are used to detect that the opponent is trying to set up
  1403.   a stonewall type pawn formation.
  1404. */
  1405.   stonewall_white=Or(Or(set_mask[D4],set_mask[E3]),set_mask[F4]);
  1406.   stonewall_black=Or(Or(set_mask[D5],set_mask[E6]),set_mask[F5]);
  1407. }
  1408.  
  1409. void InitializePieceMasks(void)
  1410. {
  1411.   int i, j;
  1412. /*
  1413.     initialize king corner masks, which are 1's on the four squares in
  1414.     each corner.
  1415. */
  1416.   mask_a1_corner=Or(mask_2,Shiftr(mask_2,8));
  1417.   mask_h1_corner=Or(Shiftr(mask_2,6),Shiftr(mask_2,14));
  1418.   mask_a8_corner=Or(Shiftr(mask_2,48),Shiftr(mask_2,56));
  1419.   mask_h8_corner=Or(Shiftr(mask_2,54),Shiftr(mask_2,62));
  1420. /*
  1421.     initialize masks used to evaluate development, which includes
  1422.     minor piece squares and center pawn squares.
  1423. */
  1424.   white_minor_pieces=Or(Shiftr(mask_2,1),Shiftr(mask_2,5));
  1425.   black_minor_pieces=Or(Shiftr(mask_2,57),Shiftr(mask_2,61));
  1426.   white_center_pawns=Shiftr(mask_2,11);
  1427.   black_center_pawns=Shiftr(mask_2,51);
  1428. /*
  1429.     initialize masks used to evaluate pawn races.  these masks are
  1430.     used to determine if the opposing king is in a position to stop a
  1431.     passed pawn from racing down and queening.
  1432. */
  1433.   for (i=0;i<64;i++) {
  1434.     white_pawn_race_wtm[i]=0;
  1435.     white_pawn_race_btm[i]=0;
  1436.     black_pawn_race_wtm[i]=0;
  1437.     black_pawn_race_btm[i]=0;
  1438.   }
  1439.   for (j=8;j<56;j++) {
  1440.     for (i=0;i<64;i++) {
  1441. /* white pawn, wtm */
  1442.       if (j < 16) {
  1443.         if (KingPawnSquare(j+8,i,(j&7)+56,1))
  1444.           white_pawn_race_wtm[j]=Or(white_pawn_race_wtm[j],set_mask[i]);
  1445.       }
  1446.       else {
  1447.         if (KingPawnSquare(j,i,(j&7)+56,1))
  1448.           white_pawn_race_wtm[j]=Or(white_pawn_race_wtm[j],set_mask[i]);
  1449.       }
  1450. /* white pawn, ChangeSide(wtm) */
  1451.       if (j < 16) {
  1452.         if (KingPawnSquare(j+8,i,(j&7)+56,0))
  1453.           white_pawn_race_btm[j]=Or(white_pawn_race_btm[j],set_mask[i]);
  1454.       }
  1455.       else {
  1456.         if (KingPawnSquare(j,i,(j&7)+56,0))
  1457.           white_pawn_race_btm[j]=Or(white_pawn_race_btm[j],set_mask[i]);
  1458.       }
  1459. /* black pawn, wtm */
  1460.       if (j > 47) {
  1461.         if (KingPawnSquare(j-8,i,j&7,0))
  1462.           black_pawn_race_wtm[j]=Or(black_pawn_race_wtm[j],set_mask[i]);
  1463.       }
  1464.       else {
  1465.         if (KingPawnSquare(j,i,j&7,0))
  1466.           black_pawn_race_wtm[j]=Or(black_pawn_race_wtm[j],set_mask[i]);
  1467.       }
  1468. /* black pawn, ChangeSide(wtm) */
  1469.       if (j > 47) {
  1470.         if (KingPawnSquare(j-8,i,j&7,1))
  1471.           black_pawn_race_btm[j]=Or(black_pawn_race_btm[j],set_mask[i]);
  1472.       }
  1473.       else {
  1474.         if (KingPawnSquare(j,i,j&7,1))
  1475.           black_pawn_race_btm[j]=Or(black_pawn_race_btm[j],set_mask[i]);
  1476.       }
  1477.     }
  1478.   }
  1479. }
  1480.  
  1481. /*
  1482. ********************************************************************************
  1483. *                                                                              *
  1484. *   InitializeRandomHash() is called to initialize the tables of random      *
  1485. *   numbers used to produce the incrementally-updated hash keys.  note that    *
  1486. *   this uses a treendom number generator rather than the C library one    *
  1487. *   since there is no uniformity in the number of bits returned by the         *
  1488. *   standard library routines, it varies from 16 bits to 64.                   *
  1489. *                                                                              *
  1490. ********************************************************************************
  1491. */
  1492. void InitializeRandomHash(void)
  1493. {
  1494.   int i;
  1495.   for (i=0;i<64;i++) {
  1496.     w_pawn_random[i]=Random64();
  1497.     b_pawn_random[i]=Random64();
  1498.     w_knight_random[i]=Random64();
  1499.     b_knight_random[i]=Random64();
  1500.     w_bishop_random[i]=Random64();
  1501.     b_bishop_random[i]=Random64();
  1502.     w_rook_random[i]=Random64();
  1503.     b_rook_random[i]=Random64();
  1504.     w_queen_random[i]=Random64();
  1505.     b_queen_random[i]=Random64();
  1506.     w_king_random[i]=Random64();
  1507.     b_king_random[i]=Random64();
  1508.   }
  1509.   for (i=0;i<2;i++) {
  1510.     castle_random_w[i]=Random64();
  1511.     castle_random_b[i]=Random64();
  1512.   }
  1513.   enpassant_random[0]=0;
  1514.   for (i=1;i<65;i++) {
  1515.     enpassant_random[i]=Random64();
  1516.   }
  1517.   for (i=0;i<2;i++) {
  1518.     wtm_random[i]=Random64();
  1519.   }
  1520.   endgame_random_w=Random64();
  1521.   endgame_random_b=Random64();
  1522.   w_rooks_random=Random64();
  1523.   b_rooks_random=Random64();
  1524.   for (i=0;i<64;i++) {
  1525.     w_pawn_random32[i]=Random32();
  1526.     b_pawn_random32[i]=Random32();
  1527.   }
  1528. }
  1529.  
  1530. #if defined(SMP)
  1531. /*
  1532. ********************************************************************************
  1533. *                                                                              *
  1534. *   InitlializeSMP() is used to initialize the pthread lock variables.         *
  1535. *                                                                              *
  1536. ********************************************************************************
  1537. */
  1538. void InitializeSMP(void) {
  1539.   int i;
  1540. #if defined(POSIX)
  1541.   pthread_attr_init(&pthread_attr);
  1542.   pthread_attr_setdetachstate(&pthread_attr, PTHREAD_CREATE_DETACHED);
  1543.   pthread_attr_setscope(&pthread_attr, PTHREAD_SCOPE_SYSTEM);
  1544. #endif
  1545.   LockInit(lock_hasha);
  1546.   LockInit(lock_hashb);
  1547.   LockInit(lock_pawn_hash);
  1548.   LockInit(lock_smp);
  1549.   LockInit(lock_io);
  1550.   for (i=0;i<64+1;i++)
  1551.     LockInit(local[i]->lock);
  1552. }
  1553. #endif
  1554.  
  1555. void InitializeZeroMasks(void)
  1556. {
  1557.   int i,j,maskl,maskr;
  1558. #if !defined(CRAY1)
  1559.   first_ones[0]=16;
  1560.   last_ones[0]=16;
  1561.   for (i=1;i<65536;i++){
  1562.     maskl=32768;
  1563.     for(j=0;j<16;j++){
  1564.       if ((maskl & i)){
  1565.         first_ones[i]=j;
  1566.         break;
  1567.       }
  1568.       maskl=maskl>>1;
  1569.     }
  1570.     maskr=1;
  1571.     for(j=0;j<16;j++){
  1572.       if ((maskr & i)){
  1573.         last_ones[i]=15-j;
  1574.         break;
  1575.       }
  1576.       maskr=maskr<<1;
  1577.     }
  1578.   }
  1579. #endif
  1580.   first_ones_8bit[0]=8;
  1581.   last_ones_8bit[0]=8;
  1582.   connected_passed[0]=0;
  1583.   for (i=0;i<256;i++){
  1584.     connected_passed[i]=0;
  1585.     for (j=0;j<8;j++){
  1586.       if (i & (1<<(7-j))){
  1587.         first_ones_8bit[i]=j;
  1588.         break;
  1589.       }
  1590.     }
  1591.     for (j=7;j>=0;j--){
  1592.       if (i & (1<<(7-j))){
  1593.         last_ones_8bit[i]=j;
  1594.         break;
  1595.       }
  1596.     }
  1597.     for (j=7;j>0;j--){
  1598.       if ((i & (3<<(7-j))) == (3<<(7-j))){
  1599.         connected_passed[i]=j;
  1600.         break;
  1601.       }
  1602.     }
  1603.   }
  1604. }
  1605.