Upgrade to Bonanza 6.0
[bonanza.git] / mate3.c
diff --git a/mate3.c b/mate3.c
index 61d1036..29b4a0f 100644 (file)
--- a/mate3.c
+++ b/mate3.c
@@ -15,29 +15,90 @@ enum { mate_king_cap_checker = 0,
        mate_intercept_weak_move,
        mate_intercept_drop_sup };
 
-static int mate3_and( tree_t * restrict ptree, int turn, int ply, int flag );
-static void checker( const tree_t * restrict ptree, char *psq, int turn );
-static unsigned int gen_king_cap_checker( const tree_t * restrict ptree,
-                                         int to, int turn );
-static int mate_weak_or( tree_t * restrict ptree, int turn, int ply,
-                        int from, int to );
-static unsigned int *gen_move_to( const tree_t * restrict ptree, int sq,
-                                 int turn, unsigned int * restrict pmove );
-static unsigned int *gen_king_move( const tree_t * restrict ptree,
-                                   const char *psq, int turn, int is_capture,
-                                   unsigned int * restrict pmove );
-static unsigned int *gen_intercept( tree_t * restrict __ptree__,
-                                   int sq_checker, int ply, int turn,
-                                   int * restrict premaining,
-                                   unsigned int * restrict pmove, int flag );
-static int gen_next_evasion_mate( tree_t * restrict ptree, const char *psq,
-                                 int ply, int turn, int flag );
-
-unsigned int
+static int CONV mate3_and( tree_t * restrict ptree, int turn, int ply,
+                          int flag );
+static void CONV checker( const tree_t * restrict ptree, char *psq, int turn );
+static unsigned int CONV gen_king_cap_checker( const tree_t * restrict ptree,
+                                              int to, int turn );
+static int CONV mate_weak_or( tree_t * restrict ptree, int turn, int ply,
+                             int from, int to );
+static unsigned int * CONV gen_move_to( const tree_t * restrict ptree, int sq,
+                                       int turn,
+                                       unsigned int * restrict pmove );
+static unsigned int * CONV gen_king_move( const tree_t * restrict ptree,
+                                         const char *psq, int turn,
+                                         int is_capture,
+                                         unsigned int * restrict pmove );
+static unsigned int * CONV gen_intercept( tree_t * restrict __ptree__,
+                                         int sq_checker, int ply, int turn,
+                                         int * restrict premaining,
+                                         unsigned int * restrict pmove,
+                                         int flag );
+static int CONV gen_next_evasion_mate( tree_t * restrict ptree,
+                                      const char *psq, int ply, int turn,
+                                      int flag );
+
+static uint64_t mate3_hash_tbl[ MATE3_MASK + 1 ] = {0};
+
+static int CONV
+mhash_probe( tree_t * restrict ptree, int turn, int ply )
+{
+  uint64_t key_current, key, word;
+  unsigned int move;
+
+  word  = mate3_hash_tbl[ (unsigned int)HASH_KEY & MATE3_MASK ];
+#if ! defined(__x86_64__)
+  word ^= word << 32;
+#endif
+
+  key          = word     & ~(uint64_t)0x7ffffU;
+  key_current  = HASH_KEY & ~(uint64_t)0x7ffffU;
+  key_current ^= (uint64_t)HAND_B << 42;
+  key_current ^= (uint64_t)turn << 63;
+
+  if ( key != key_current ) { return 0; }
+
+  move = (unsigned int)word & 0x7ffffU;
+  if ( move != MOVE_NA )
+    {
+      move |= turn ? Cap2Move( BOARD[I2To(move)])
+                   : Cap2Move(-BOARD[I2To(move)]);
+    }
+
+  MOVE_CURR = move;
+
+  return 1;
+}
+
+
+static void CONV
+mhash_store( const tree_t * restrict ptree, int turn, unsigned int move )
+{
+  uint64_t word;
+
+  word  = HASH_KEY & ~(uint64_t)0x7ffffU;
+  word |= (uint64_t)( move & 0x7ffffU );
+  word ^= (uint64_t)HAND_B << 42;
+  word ^= (uint64_t)turn << 63;
+  
+#if ! defined(__x86_64__)
+  word ^= word << 32;
+#endif
+  mate3_hash_tbl[ (unsigned int)HASH_KEY & MATE3_MASK ] = word;
+}
+
+
+unsigned int CONV
 is_mate_in3ply( tree_t * restrict ptree, int turn, int ply )
 {
   int value, flag_skip;
 
+  if ( mhash_probe( ptree, turn, ply ) )
+    {
+      if ( MOVE_CURR == MOVE_NA ) { return 0; }
+      else                        { return 1; }
+    }
+
   if ( ply >= PLY_MAX-2 ) { return 0; }
 
   flag_skip = 0;
@@ -64,7 +125,11 @@ is_mate_in3ply( tree_t * restrict ptree, int turn, int ply )
       
       UnMakeMove( turn, MOVE_CURR, ply );
 
-      if ( value ) { return 1; }
+      if ( value )
+       {
+         mhash_store( ptree, turn, MOVE_CURR );
+         return 1;
+       }
 
       if ( ( MOVE_CURR & MOVE_CHK_SET )
           && I2To(MOVE_CURR) != I2To(ptree->current_move[ply+1]) )
@@ -73,11 +138,12 @@ is_mate_in3ply( tree_t * restrict ptree, int turn, int ply )
        }
     }
 
+  mhash_store( ptree, turn, MOVE_NA );
   return 0;
 }
 
 
-static int
+static int CONV
 mate3_and( tree_t * restrict ptree, int turn, int ply, int flag )
 {
   unsigned int move;
@@ -118,7 +184,7 @@ mate3_and( tree_t * restrict ptree, int turn, int ply, int flag )
 }
 
 
-static int
+static int CONV
 mate_weak_or( tree_t * restrict ptree, int turn, int ply, int from,
              int to )
 {
@@ -172,7 +238,7 @@ mate_weak_or( tree_t * restrict ptree, int turn, int ply, int from,
 }
 
 
-static int
+static int CONV
 gen_next_evasion_mate( tree_t * restrict ptree, const char *psq, int ply,
                       int turn, int flag )
 {
@@ -272,30 +338,29 @@ gen_next_evasion_mate( tree_t * restrict ptree, const char *psq, int ply,
 }
 
 
-static void
+static void CONV
 checker( const tree_t * restrict ptree, char *psq, int turn )
 {
-  bitboard_t bb, bb_checkers;
+  bitboard_t bb;
   int n, sq0, sq1, sq_king;
 
   if ( turn )
     {
-      sq_king     = SQ_WKING;
-      bb_checkers = BB_BOCCUPY;
+      sq_king = SQ_WKING;
+      bb = b_attacks_to_piece( ptree, sq_king );
     }
   else {
-    sq_king     = SQ_BKING;
-    bb_checkers = BB_WOCCUPY;
+    sq_king = SQ_BKING;
+    bb = w_attacks_to_piece( ptree, sq_king );
   }
-  bb = attacks_to_piece( ptree, sq_king );
-  BBAnd( bb, bb, bb_checkers );
 
-  assert( BBToU(bb) );
+
+  assert( BBTest(bb) );
   sq0 = LastOne( bb );
   sq1 = nsquare;
 
   Xor( sq0, bb );
-  if ( BBToU( bb ) )
+  if ( BBTest( bb ) )
     {
       sq1 = LastOne( bb );
       if ( BBContract( abb_king_attacks[sq_king], abb_mask[sq1] ) )
@@ -311,7 +376,7 @@ checker( const tree_t * restrict ptree, char *psq, int turn )
 }
 
 
-static unsigned int
+static unsigned int CONV
 gen_king_cap_checker( const tree_t * restrict ptree, int to, int turn )
 {
   unsigned int move;
@@ -338,19 +403,18 @@ gen_king_cap_checker( const tree_t * restrict ptree, int to, int turn )
 }
 
 
-static unsigned int *
+static unsigned int * CONV
 gen_move_to( const tree_t * restrict ptree, int to, int turn,
             unsigned int * restrict pmove )
 {
   bitboard_t bb;
   int direc, from, pc, flag_promo, flag_unpromo;
 
-  bb = attacks_to_piece( ptree, to );
   if ( turn )
     {
-      BBAnd( bb, bb, BB_WOCCUPY );
-      BBNotAnd( bb, abb_mask[SQ_WKING] );
-      while ( BBToU(bb) )
+      bb = w_attacks_to_piece( ptree, to );
+      BBNotAnd( bb, bb, abb_mask[SQ_WKING] );
+      while ( BBTest(bb) )
        {
          from = LastOne( bb );
          Xor( from, bb );
@@ -401,9 +465,9 @@ gen_move_to( const tree_t * restrict ptree, int to, int turn,
        }
     }
   else {
-    BBAnd( bb, bb, BB_BOCCUPY );
-    BBNotAnd( bb, abb_mask[SQ_BKING] );
-    while ( BBToU(bb) )
+    bb = b_attacks_to_piece( ptree, to );
+    BBNotAnd( bb, bb, abb_mask[SQ_BKING] );
+    while ( BBTest(bb) )
       {
        from = FirstOne( bb );
        Xor( from, bb );
@@ -458,7 +522,7 @@ gen_move_to( const tree_t * restrict ptree, int to, int turn,
 }
 
 
-static unsigned int *
+static unsigned int * CONV
 gen_king_move( const tree_t * restrict ptree, const char *psq, int turn,
               int is_capture, unsigned int * restrict pmove )
 {
@@ -468,28 +532,28 @@ gen_king_move( const tree_t * restrict ptree, const char *psq, int turn,
   if ( turn )
     {
       from = SQ_WKING;
-      bb      = abb_king_attacks[from];
+      bb   = abb_king_attacks[from];
       if ( is_capture )
        {
          BBAnd( bb, bb, BB_BOCCUPY );
-         BBNotAnd( bb, abb_mask[(int)psq[0]] );
+         BBNotAnd( bb, bb, abb_mask[(int)psq[0]] );
        }
-      else { BBNotAnd( bb, BB_BOCCUPY ); }
-      BBNotAnd( bb, BB_WOCCUPY );
+      else { BBNotAnd( bb, bb, BB_BOCCUPY ); }
+      BBNotAnd( bb, bb, BB_WOCCUPY );
     }
   else {
     from = SQ_BKING;
-    bb      = abb_king_attacks[from];
+    bb   = abb_king_attacks[from];
     if ( is_capture )
       {
        BBAnd( bb, bb, BB_WOCCUPY );
-       BBNotAnd( bb, abb_mask[(int)psq[0]] );
+       BBNotAnd( bb, bb, abb_mask[(int)psq[0]] );
       }
-    else { BBNotAnd( bb, BB_WOCCUPY ); }
-    BBNotAnd( bb, BB_BOCCUPY );
+    else { BBNotAnd( bb, bb, BB_WOCCUPY ); }
+    BBNotAnd( bb, bb, BB_BOCCUPY );
   }
   
-  while ( BBToU(bb) )
+  while ( BBTest(bb) )
     {
       to = LastOne( bb );
       Xor( to, bb );
@@ -530,7 +594,7 @@ gen_king_move( const tree_t * restrict ptree, const char *psq, int turn,
 }
 
 
-static unsigned int *
+static unsigned int * CONV
 gen_intercept( tree_t * restrict __ptree__, int sq_checker, int ply, int turn,
               int * restrict premaining, unsigned int * restrict pmove,
               int flag )
@@ -549,12 +613,12 @@ gen_intercept( tree_t * restrict __ptree__, int sq_checker, int ply, int turn,
     {
       sq_k        = SQ_WKING;
       bb_defender = BB_WOCCUPY;
-      BBNotAnd( bb_defender, abb_mask[sq_k] );
+      BBNotAnd( bb_defender, bb_defender, abb_mask[sq_k] );
     }
   else {
     sq_k        = SQ_BKING;
     bb_defender = BB_BOCCUPY;
-    BBNotAnd( bb_defender, abb_mask[sq_k] );
+    BBNotAnd( bb_defender, bb_defender, abb_mask[sq_k] );
   }
 
   switch ( adirec[sq_k][sq_checker] )
@@ -591,7 +655,7 @@ gen_intercept( tree_t * restrict __ptree__, int sq_checker, int ply, int turn,
     nmove  = 0;
     bb_atk = attacks_to_piece( ptree, to );
     BBAnd( bb, bb_defender, bb_atk );
-    while ( BBToU(bb) )
+    while ( BBTest(bb) )
       {
        from = LastOne( bb );
        Xor( from, bb );
@@ -689,7 +753,8 @@ gen_intercept( tree_t * restrict __ptree__, int sq_checker, int ply, int turn,
        
        /* -tentative assumption- */
        /* no intercept-drop at non-supported square. */
-       if ( I2To(MOVE_LAST) == sq_checker && dist > min_chuai ) { continue; }
+       if ( (int)I2To(MOVE_LAST) == sq_checker
+            && dist > min_chuai ) { continue; }
       }
     
     nmove = 0;