Upgrade to Bonanza 6.0
[bonanza.git] / evaluate.c
index 85b8a63..e573385 100644 (file)
@@ -1,15 +1,31 @@
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
+#include <limits.h>
 #include "shogi.h"
 
-static int ehash_probe( uint64_t current_key, unsigned int hand_b,
-                       int *pscore );
-static void ehash_store( uint64_t key, unsigned int hand_b, int score );
-static int make_list( const tree_t * restrict ptree, int * restrict pscore,
-                     int list0[52], int list1[52] );
+#define PcPcOnSqAny(k,i,j) ( i >= j ? PcPcOnSq(k,i,j) : PcPcOnSq(k,j,i) )
+
+static int CONV doacapt( const tree_t * restrict ptree, int pc, int turn,
+                        int hand_index, const int list0[52],
+                        const int list1[52], int nlist );
+static int CONV doapc( const tree_t * restrict ptree, int pc, int sq,
+                      const int list0[52], const int list1[52], int nlist );
+static int CONV ehash_probe( uint64_t current_key, unsigned int hand_b,
+                            int * restrict pscore );
+static void CONV ehash_store( uint64_t key, unsigned int hand_b, int score );
+static int CONV calc_difference( const tree_t * restrict ptree, int ply,
+                                int turn, int list0[52], int list1[52],
+                                int * restrict pscore );
+static int CONV make_list( const tree_t * restrict ptree,
+                          int * restrict pscore,
+                          int list0[52], int list1[52] );
+
+#if defined(INANIWA_SHIFT)
+static int inaniwa_score( const tree_t * restrict ptree );
+#endif
 
-int
+int CONV
 eval_material( const tree_t * restrict ptree )
 {
   int material, itemp;
@@ -70,29 +86,67 @@ eval_material( const tree_t * restrict ptree )
 }
 
 
-int
+int CONV
 evaluate( tree_t * restrict ptree, int ply, int turn )
 {
   int list0[52], list1[52];
   int nlist, score, sq_bk, sq_wk, k0, k1, l0, l1, i, j, sum;
 
+  assert( 0 < ply );
   ptree->neval_called++;
 
-  if ( ptree->stand_pat[ply] != score_bound )
+  if ( ptree->save_eval[ply] != INT_MAX )
     {
-      return (int)ptree->stand_pat[ply];
+      return (int)ptree->save_eval[ply] / FV_SCALE;
     }
 
   if ( ehash_probe( HASH_KEY, HAND_B, &score ) )
     {
       score                 = turn ? -score : score;
-      ptree->stand_pat[ply] = (short)score;
+      ptree->save_eval[ply] = score;
 
-      return score;
+      return score / FV_SCALE;
     }
 
+  list0[ 0] = f_hand_pawn   + I2HandPawn(HAND_B);
+  list0[ 1] = e_hand_pawn   + I2HandPawn(HAND_W);
+  list0[ 2] = f_hand_lance  + I2HandLance(HAND_B);
+  list0[ 3] = e_hand_lance  + I2HandLance(HAND_W);
+  list0[ 4] = f_hand_knight + I2HandKnight(HAND_B);
+  list0[ 5] = e_hand_knight + I2HandKnight(HAND_W);
+  list0[ 6] = f_hand_silver + I2HandSilver(HAND_B);
+  list0[ 7] = e_hand_silver + I2HandSilver(HAND_W);
+  list0[ 8] = f_hand_gold   + I2HandGold(HAND_B);
+  list0[ 9] = e_hand_gold   + I2HandGold(HAND_W);
+  list0[10] = f_hand_bishop + I2HandBishop(HAND_B);
+  list0[11] = e_hand_bishop + I2HandBishop(HAND_W);
+  list0[12] = f_hand_rook   + I2HandRook(HAND_B);
+  list0[13] = e_hand_rook   + I2HandRook(HAND_W);
+
+  list1[ 0] = f_hand_pawn   + I2HandPawn(HAND_W);
+  list1[ 1] = e_hand_pawn   + I2HandPawn(HAND_B);
+  list1[ 2] = f_hand_lance  + I2HandLance(HAND_W);
+  list1[ 3] = e_hand_lance  + I2HandLance(HAND_B);
+  list1[ 4] = f_hand_knight + I2HandKnight(HAND_W);
+  list1[ 5] = e_hand_knight + I2HandKnight(HAND_B);
+  list1[ 6] = f_hand_silver + I2HandSilver(HAND_W);
+  list1[ 7] = e_hand_silver + I2HandSilver(HAND_B);
+  list1[ 8] = f_hand_gold   + I2HandGold(HAND_W);
+  list1[ 9] = e_hand_gold   + I2HandGold(HAND_B);
+  list1[10] = f_hand_bishop + I2HandBishop(HAND_W);
+  list1[11] = e_hand_bishop + I2HandBishop(HAND_B);
+  list1[12] = f_hand_rook   + I2HandRook(HAND_W);
+  list1[13] = e_hand_rook   + I2HandRook(HAND_B);
+
+  if ( calc_difference( ptree, ply, turn, list0, list1, &score ) )
+    {
+      ehash_store( HASH_KEY, HAND_B, score );
+      score                 = turn ? -score : score;
+      ptree->save_eval[ply] = score;
+
+      return score / FV_SCALE;
+    }
 
-  score = 0;
   nlist = make_list( ptree, &score, list0, list1 );
   sq_bk = SQ_BKING;
   sq_wk = Inv( SQ_WKING );
@@ -113,13 +167,18 @@ evaluate( tree_t * restrict ptree, int ply, int turn )
     }
   
   score += sum;
-  score /= FV_SCALE;
+  score += MATERIAL * FV_SCALE;
+#if defined(INANIWA_SHIFT)
+  score += inaniwa_score( ptree );
+#endif
 
-  score += MATERIAL;
+  ehash_store( HASH_KEY, HAND_B, score );
 
-#if defined(MNJ_LAN)
-  if ( sckt_mnj != SCKT_NULL ) { score += mnj_tbl[ HASH_KEY & MNJ_MASK ]; }
-#endif
+  score = turn ? -score : score;
+
+  ptree->save_eval[ply] = score;
+
+  score /= FV_SCALE;
 
 #if ! defined(MINIMUM)
   if ( abs(score) > score_max_eval )
@@ -128,24 +187,16 @@ evaluate( tree_t * restrict ptree, int ply, int turn )
     }
 #endif
 
-  ehash_store( HASH_KEY, HAND_B, score );
-
-  score = turn ? -score : score;
-  ptree->stand_pat[ply] = (short)score;
-
   return score;
 
 }
 
 
-void ehash_clear( void )
-{
-  memset( ehash_tbl, 0, sizeof(ehash_tbl) );
-}
+void CONV ehash_clear( void ) { memset( ehash_tbl, 0, sizeof(ehash_tbl) ); }
 
 
-static int ehash_probe( uint64_t current_key, unsigned int hand_b,
-                       int *pscore )
+static int CONV ehash_probe( uint64_t current_key, unsigned int hand_b,
+                            int * restrict pscore )
 {
   uint64_t hash_word, hash_key;
 
@@ -155,28 +206,28 @@ static int ehash_probe( uint64_t current_key, unsigned int hand_b,
   hash_word ^= hash_word << 32;
 #endif
 
-  current_key ^= (uint64_t)hand_b << 16;
-  current_key &= ~(uint64_t)0xffffU;
+  current_key ^= (uint64_t)hand_b << 21;
+  current_key &= ~(uint64_t)0x1fffffU;
 
   hash_key  = hash_word;
-  hash_key &= ~(uint64_t)0xffffU;
+  hash_key &= ~(uint64_t)0x1fffffU;
 
   if ( hash_key != current_key ) { return 0; }
 
-  *pscore = (int)( (unsigned int)hash_word & 0xffffU ) - 32768;
+  *pscore = (int)( (unsigned int)hash_word & 0x1fffffU ) - 0x100000;
 
   return 1;
 }
 
 
-static void ehash_store( uint64_t key, unsigned int hand_b, int score )
+static void CONV ehash_store( uint64_t key, unsigned int hand_b, int score )
 {
   uint64_t hash_word;
 
   hash_word  = key;
-  hash_word ^= (uint64_t)hand_b << 16;
-  hash_word &= ~(uint64_t)0xffffU;
-  hash_word |= (uint64_t)( score + 32768 );
+  hash_word ^= (uint64_t)hand_b << 21;
+  hash_word &= ~(uint64_t)0x1fffffU;
+  hash_word |= (uint64_t)( score + 0x100000 );
 
 #if ! defined(__x86_64__)
   hash_word ^= hash_word << 32;
@@ -186,7 +237,138 @@ static void ehash_store( uint64_t key, unsigned int hand_b, int score )
 }
 
 
-static int
+static int CONV
+calc_difference( const tree_t * restrict ptree, int ply, int turn,
+                int list0[52], int list1[52], int * restrict pscore )
+{
+  bitboard_t bb;
+  int nlist, diff, from, to, sq, pc;
+
+#if defined(INANIWA_SHIFT)
+  if ( inaniwa_flag ) { return 0; }
+#endif
+
+  if ( ptree->save_eval[ply-1] == INT_MAX ) { return 0; }
+  if ( I2PieceMove(MOVE_LAST)  == king )    { return 0; }
+
+  assert( MOVE_LAST != MOVE_PASS );
+
+  nlist = 14;
+  diff  = 0;
+  from  = I2From(MOVE_LAST);
+  to    = I2To(MOVE_LAST);
+
+  BBOr( bb, BB_BOCCUPY, BB_WOCCUPY );
+  Xor( SQ_BKING, bb );
+  Xor( SQ_WKING, bb );
+  Xor( to,       bb );
+    
+  while ( BBTest(bb) )
+    {
+      sq = FirstOne(bb);
+      Xor( sq, bb );
+      
+      pc = BOARD[sq];
+      list0[nlist  ] = aikpp[15+pc] + sq;
+      list1[nlist++] = aikpp[15-pc] + Inv(sq);
+    }
+
+  pc = BOARD[to];
+  list0[nlist  ] = aikpp[15+pc] + to;
+  list1[nlist++] = aikpp[15-pc] + Inv(to);
+
+  diff = doapc( ptree, pc, to, list0, list1, nlist );
+  nlist -= 1;
+
+  if ( from >= nsquare )
+    {
+      unsigned int hand;
+      int hand_index;
+
+      pc   = From2Drop(from);
+      hand = turn ? HAND_B : HAND_W;
+
+      switch ( pc )
+       {
+       case pawn:   hand_index = I2HandPawn(hand);   break;
+       case lance:  hand_index = I2HandLance(hand);  break;
+       case knight: hand_index = I2HandKnight(hand); break;
+       case silver: hand_index = I2HandSilver(hand); break;
+       case gold:   hand_index = I2HandGold(hand);   break;
+       case bishop: hand_index = I2HandBishop(hand); break;
+       default:     hand_index = I2HandRook(hand);   break;
+       }
+
+      diff += doacapt( ptree, pc, turn, hand_index, list0, list1, nlist );
+
+      list0[ 2*(pc-1) + 1 - turn ] += 1;
+      list1[ 2*(pc-1) + turn     ] += 1;
+      hand_index                   += 1;
+
+      diff -= doacapt( ptree, pc, turn, hand_index, list0, list1, nlist );
+    }
+  else {
+    int pc_cap = UToCap(MOVE_LAST);
+    if ( pc_cap )
+      {
+       unsigned int hand;
+       int hand_index;
+
+       pc     = pc_cap & ~promote;
+       hand   = turn ? HAND_B : HAND_W;
+       pc_cap = turn ? -pc_cap : pc_cap;
+       diff  += turn ?  p_value_ex[15+pc_cap] * FV_SCALE
+                      : -p_value_ex[15+pc_cap] * FV_SCALE;
+
+       switch ( pc )
+         {
+         case pawn:   hand_index = I2HandPawn(hand);   break;
+         case lance:  hand_index = I2HandLance(hand);  break;
+         case knight: hand_index = I2HandKnight(hand); break;
+         case silver: hand_index = I2HandSilver(hand); break;
+         case gold:   hand_index = I2HandGold(hand);   break;
+         case bishop: hand_index = I2HandBishop(hand); break;
+         default:     hand_index = I2HandRook(hand);   break;
+         }
+
+       diff += doacapt( ptree, pc, turn, hand_index, list0, list1, nlist );
+       
+       list0[ 2*(pc-1) + 1 - turn ] -= 1;
+       list1[ 2*(pc-1) + turn     ] -= 1;
+       hand_index                   -= 1;
+       
+       diff -= doacapt( ptree, pc, turn, hand_index, list0, list1, nlist );
+
+       list0[nlist  ] = aikpp[15+pc_cap] + to;
+       list1[nlist++] = aikpp[15-pc_cap] + Inv(to);
+
+       diff -= doapc( ptree, pc_cap, to, list0, list1, nlist );
+    }
+
+    pc = I2PieceMove(MOVE_LAST);
+    if ( I2IsPromote(MOVE_LAST) )
+      {
+       diff += ( turn ? p_value_pm[7+pc] : -p_value_pm[7+pc] ) * FV_SCALE;
+      }
+    
+    pc = turn ? pc : -pc;
+
+    list0[nlist  ] = aikpp[15+pc] + from;
+    list1[nlist++] = aikpp[15-pc] + Inv(from);
+
+    diff -= doapc( ptree, pc, from, list0, list1, nlist );
+  
+  }
+  
+  diff += turn ? ptree->save_eval[ply-1] : - ptree->save_eval[ply-1];
+
+  *pscore = diff;
+
+  return 1;
+}
+
+
+static int CONV
 make_list( const tree_t * restrict ptree, int * restrict pscore,
           int list0[52], int list1[52] )
 {
@@ -201,36 +383,6 @@ make_list( const tree_t * restrict ptree, int * restrict pscore,
   sq_bk1 = Inv(SQ_WKING);
   sq_wk1 = Inv(SQ_BKING);
 
-  list0[ 0] = f_hand_pawn   + I2HandPawn(HAND_B);
-  list0[ 1] = e_hand_pawn   + I2HandPawn(HAND_W);
-  list0[ 2] = f_hand_lance  + I2HandLance(HAND_B);
-  list0[ 3] = e_hand_lance  + I2HandLance(HAND_W);
-  list0[ 4] = f_hand_knight + I2HandKnight(HAND_B);
-  list0[ 5] = e_hand_knight + I2HandKnight(HAND_W);
-  list0[ 6] = f_hand_silver + I2HandSilver(HAND_B);
-  list0[ 7] = e_hand_silver + I2HandSilver(HAND_W);
-  list0[ 8] = f_hand_gold   + I2HandGold(HAND_B);
-  list0[ 9] = e_hand_gold   + I2HandGold(HAND_W);
-  list0[10] = f_hand_bishop + I2HandBishop(HAND_B);
-  list0[11] = e_hand_bishop + I2HandBishop(HAND_W);
-  list0[12] = f_hand_rook   + I2HandRook(HAND_B);
-  list0[13] = e_hand_rook   + I2HandRook(HAND_W);
-
-  list1[ 0] = f_hand_pawn   + I2HandPawn(HAND_W);
-  list1[ 1] = e_hand_pawn   + I2HandPawn(HAND_B);
-  list1[ 2] = f_hand_lance  + I2HandLance(HAND_W);
-  list1[ 3] = e_hand_lance  + I2HandLance(HAND_B);
-  list1[ 4] = f_hand_knight + I2HandKnight(HAND_W);
-  list1[ 5] = e_hand_knight + I2HandKnight(HAND_B);
-  list1[ 6] = f_hand_silver + I2HandSilver(HAND_W);
-  list1[ 7] = e_hand_silver + I2HandSilver(HAND_B);
-  list1[ 8] = f_hand_gold   + I2HandGold(HAND_W);
-  list1[ 9] = e_hand_gold   + I2HandGold(HAND_B);
-  list1[10] = f_hand_bishop + I2HandBishop(HAND_W);
-  list1[11] = e_hand_bishop + I2HandBishop(HAND_B);
-  list1[12] = f_hand_rook   + I2HandRook(HAND_W);
-  list1[13] = e_hand_rook   + I2HandRook(HAND_B);
-
   score += kkp[sq_bk0][sq_wk0][ kkp_hand_pawn   + I2HandPawn(HAND_B) ];
   score += kkp[sq_bk0][sq_wk0][ kkp_hand_lance  + I2HandLance(HAND_B) ];
   score += kkp[sq_bk0][sq_wk0][ kkp_hand_knight + I2HandKnight(HAND_B) ];
@@ -249,7 +401,7 @@ make_list( const tree_t * restrict ptree, int * restrict pscore,
 
   n2 = 0;
   bb = BB_BPAWN;
-  while ( BBToU(bb) ) {
+  while ( BBTest(bb) ) {
     sq = FirstOne( bb );
     Xor( sq, bb );
 
@@ -261,7 +413,7 @@ make_list( const tree_t * restrict ptree, int * restrict pscore,
   }
 
   bb = BB_WPAWN;
-  while ( BBToU(bb) ) {
+  while ( BBTest(bb) ) {
     sq = FirstOne( bb );
     Xor( sq, bb );
 
@@ -275,7 +427,7 @@ make_list( const tree_t * restrict ptree, int * restrict pscore,
 
   n2 = 0;
   bb = BB_BLANCE;
-  while ( BBToU(bb) ) {
+  while ( BBTest(bb) ) {
     sq = FirstOne( bb );
     Xor( sq, bb );
 
@@ -287,7 +439,7 @@ make_list( const tree_t * restrict ptree, int * restrict pscore,
   }
 
   bb = BB_WLANCE;
-  while ( BBToU(bb) ) {
+  while ( BBTest(bb) ) {
     sq = FirstOne( bb );
     Xor( sq, bb );
 
@@ -302,7 +454,7 @@ make_list( const tree_t * restrict ptree, int * restrict pscore,
 
   n2 = 0;
   bb = BB_BKNIGHT;
-  while ( BBToU(bb) ) {
+  while ( BBTest(bb) ) {
     sq = FirstOne( bb );
     Xor( sq, bb );
 
@@ -314,7 +466,7 @@ make_list( const tree_t * restrict ptree, int * restrict pscore,
   }
 
   bb = BB_WKNIGHT;
-  while ( BBToU(bb) ) {
+  while ( BBTest(bb) ) {
     sq = FirstOne( bb );
     Xor( sq, bb );
 
@@ -329,7 +481,7 @@ make_list( const tree_t * restrict ptree, int * restrict pscore,
 
   n2 = 0;
   bb = BB_BSILVER;
-  while ( BBToU(bb) ) {
+  while ( BBTest(bb) ) {
     sq = FirstOne( bb );
     Xor( sq, bb );
 
@@ -341,7 +493,7 @@ make_list( const tree_t * restrict ptree, int * restrict pscore,
   }
 
   bb = BB_WSILVER;
-  while ( BBToU(bb) ) {
+  while ( BBTest(bb) ) {
     sq = FirstOne( bb );
     Xor( sq, bb );
 
@@ -356,7 +508,7 @@ make_list( const tree_t * restrict ptree, int * restrict pscore,
 
   n2 = 0;
   bb = BB_BTGOLD;
-  while ( BBToU(bb) ) {
+  while ( BBTest(bb) ) {
     sq = FirstOne( bb );
     Xor( sq, bb );
 
@@ -368,7 +520,7 @@ make_list( const tree_t * restrict ptree, int * restrict pscore,
   }
 
   bb = BB_WTGOLD;
-  while ( BBToU(bb) ) {
+  while ( BBTest(bb) ) {
     sq = FirstOne( bb );
     Xor( sq, bb );
 
@@ -383,7 +535,7 @@ make_list( const tree_t * restrict ptree, int * restrict pscore,
 
   n2 = 0;
   bb = BB_BBISHOP;
-  while ( BBToU(bb) ) {
+  while ( BBTest(bb) ) {
     sq = FirstOne( bb );
     Xor( sq, bb );
 
@@ -395,7 +547,7 @@ make_list( const tree_t * restrict ptree, int * restrict pscore,
   }
 
   bb = BB_WBISHOP;
-  while ( BBToU(bb) ) {
+  while ( BBTest(bb) ) {
     sq = FirstOne( bb );
     Xor( sq, bb );
 
@@ -410,7 +562,7 @@ make_list( const tree_t * restrict ptree, int * restrict pscore,
 
   n2 = 0;
   bb = BB_BHORSE;
-  while ( BBToU(bb) ) {
+  while ( BBTest(bb) ) {
     sq = FirstOne( bb );
     Xor( sq, bb );
 
@@ -422,7 +574,7 @@ make_list( const tree_t * restrict ptree, int * restrict pscore,
   }
 
   bb = BB_WHORSE;
-  while ( BBToU(bb) ) {
+  while ( BBTest(bb) ) {
     sq = FirstOne( bb );
     Xor( sq, bb );
 
@@ -437,7 +589,7 @@ make_list( const tree_t * restrict ptree, int * restrict pscore,
 
   n2 = 0;
   bb = BB_BROOK;
-  while ( BBToU(bb) ) {
+  while ( BBTest(bb) ) {
     sq = FirstOne( bb );
     Xor( sq, bb );
 
@@ -449,7 +601,7 @@ make_list( const tree_t * restrict ptree, int * restrict pscore,
   }
 
   bb = BB_WROOK;
-  while ( BBToU(bb) ) {
+  while ( BBTest(bb) ) {
     sq = FirstOne( bb );
     Xor( sq, bb );
 
@@ -464,7 +616,7 @@ make_list( const tree_t * restrict ptree, int * restrict pscore,
 
   n2 = 0;
   bb = BB_BDRAGON;
-  while ( BBToU(bb) ) {
+  while ( BBTest(bb) ) {
     sq = FirstOne( bb );
     Xor( sq, bb );
 
@@ -476,7 +628,7 @@ make_list( const tree_t * restrict ptree, int * restrict pscore,
   }
 
   bb = BB_WDRAGON;
-  while ( BBToU(bb) ) {
+  while ( BBTest(bb) ) {
     sq = FirstOne( bb );
     Xor( sq, bb );
 
@@ -489,6 +641,148 @@ make_list( const tree_t * restrict ptree, int * restrict pscore,
   for ( i = 0; i < n2; i++ ) { list1[nlist-i-1] = list2[i]; }
 
   assert( nlist <= 52 );
-  *pscore += score;
+
+  *pscore = score;
   return nlist;
 }
+
+
+static int CONV doapc( const tree_t * restrict ptree, int pc, int sq,
+                      const int list0[52], const int list1[52], int nlist )
+{
+  int i, sum;
+  int index_b = aikpp[15+pc] + sq;
+  int index_w = aikpp[15-pc] + Inv(sq);
+  int sq_bk   = SQ_BKING;
+  int sq_wk   = Inv(SQ_WKING);
+  
+  sum = 0;
+  for( i = 0; i < 14; i++ )
+    {
+      sum += PcPcOnSq( sq_bk, index_b, list0[i] );
+      sum -= PcPcOnSq( sq_wk, index_w, list1[i] );
+    }
+  
+  for( i = 14; i < nlist; i++ )
+    {
+      sum += PcPcOnSqAny( sq_bk, index_b, list0[i] );
+      sum -= PcPcOnSqAny( sq_wk, index_w, list1[i] );
+    }
+  
+  if ( pc > 0 )
+    {
+      sq_bk  = SQ_BKING;
+      sq_wk  = SQ_WKING;
+      sum   += kkp[sq_bk][sq_wk][ aikkp[pc] + sq ];
+    }
+  else {
+    sq_bk  = Inv(SQ_WKING);
+    sq_wk  = Inv(SQ_BKING);
+    sum   -= kkp[sq_bk][sq_wk][ aikkp[-pc] + Inv(sq) ];
+  }
+  
+  return sum;
+}
+
+
+static int CONV
+doacapt( const tree_t * restrict ptree, int pc, int turn, int hand_index,
+        const int list0[52], const int list1[52], int nlist )
+{
+  int i, sum, sq_bk, sq_wk, index_b, index_w;
+  
+  index_b = 2*(pc-1) + 1 - turn;
+  index_w = 2*(pc-1) + turn;
+  sq_bk   = SQ_BKING;
+  sq_wk   = Inv(SQ_WKING);
+  
+  sum = 0;
+  for( i = 14; i < nlist; i++ )
+    {
+      sum += PcPcOnSq( sq_bk, list0[i], list0[index_b] );
+      sum -= PcPcOnSq( sq_wk, list1[i], list1[index_w] );
+    }
+
+  for( i = 0; i <= 2*(pc-1); i++ )
+    {
+      sum += PcPcOnSq( sq_bk, list0[index_b], list0[i] );
+      sum -= PcPcOnSq( sq_wk, list1[index_w], list1[i] );
+    }
+
+  for( i += 1; i < 14; i++ )
+    {
+      sum += PcPcOnSq( sq_bk, list0[i], list0[index_b] );
+      sum -= PcPcOnSq( sq_wk, list1[i], list1[index_w] );
+    }
+
+  if ( turn )
+    {
+      sum += PcPcOnSq( sq_bk, list0[index_w], list0[index_b] );
+      sum -= PcPcOnSq( sq_wk, list1[index_w], list1[index_w] );
+      sq_bk = SQ_BKING;
+      sq_wk = SQ_WKING;
+      sum  += kkp[sq_bk][sq_wk][ aikkp_hand[pc] + hand_index ];
+    }
+  else {
+    sum += PcPcOnSq( sq_bk, list0[index_b], list0[index_b] );
+    sum -= PcPcOnSq( sq_wk, list1[index_b], list1[index_w] );
+    sq_bk = Inv(SQ_WKING);
+    sq_wk = Inv(SQ_BKING);
+    sum  -= kkp[sq_bk][sq_wk][ aikkp_hand[pc] + hand_index ];
+  }
+  
+  return sum;
+}
+
+
+#if defined(INANIWA_SHIFT)
+static int
+inaniwa_score( const tree_t * restrict ptree )
+{
+  int score;
+
+  if ( ! inaniwa_flag ) { return 0; }
+
+  score = 0;
+  if ( inaniwa_flag == 2 ) {
+
+    if ( BOARD[B9] == -knight ) { score += 700 * FV_SCALE; }
+    if ( BOARD[H9] == -knight ) { score += 700 * FV_SCALE; }
+    
+    if ( BOARD[A7] == -knight ) { score += 700 * FV_SCALE; }
+    if ( BOARD[C7] == -knight ) { score += 400 * FV_SCALE; }
+    if ( BOARD[G7] == -knight ) { score += 400 * FV_SCALE; }
+    if ( BOARD[I7] == -knight ) { score += 700 * FV_SCALE; }
+    
+    if ( BOARD[B5] == -knight ) { score += 700 * FV_SCALE; }
+    if ( BOARD[D5] == -knight ) { score += 100 * FV_SCALE; }
+    if ( BOARD[F5] == -knight ) { score += 100 * FV_SCALE; }
+    if ( BOARD[H5] == -knight ) { score += 700 * FV_SCALE; }
+
+    if ( BOARD[E3] ==  pawn )   { score += 200 * FV_SCALE; }
+    if ( BOARD[E4] ==  pawn )   { score += 200 * FV_SCALE; }
+    if ( BOARD[E5] ==  pawn )   { score += 200 * FV_SCALE; }
+
+  } else {
+
+    if ( BOARD[B1] ==  knight ) { score -= 700 * FV_SCALE; }
+    if ( BOARD[H1] ==  knight ) { score -= 700 * FV_SCALE; }
+    
+    if ( BOARD[A3] ==  knight ) { score -= 700 * FV_SCALE; }
+    if ( BOARD[C3] ==  knight ) { score -= 400 * FV_SCALE; }
+    if ( BOARD[G3] ==  knight ) { score -= 400 * FV_SCALE; }
+    if ( BOARD[I3] ==  knight ) { score -= 700 * FV_SCALE; }
+    
+    if ( BOARD[B5] ==  knight ) { score -= 700 * FV_SCALE; }
+    if ( BOARD[D5] ==  knight ) { score -= 100 * FV_SCALE; }
+    if ( BOARD[F5] ==  knight ) { score -= 100 * FV_SCALE; }
+    if ( BOARD[H5] ==  knight ) { score -= 700 * FV_SCALE; }
+
+    if ( BOARD[E7] == -pawn )   { score -= 200 * FV_SCALE; }
+    if ( BOARD[E6] == -pawn )   { score -= 200 * FV_SCALE; }
+    if ( BOARD[E5] == -pawn )   { score -= 200 * FV_SCALE; }
+  }
+
+  return score;
+}
+#endif