X-Git-Url: http://winboard.nl/cgi-bin?p=bonanza.git;a=blobdiff_plain;f=evaluate.c;h=e57338540d790cd1a863a0033b5f831d27f9d73e;hp=85b8a630508cc6307c458dbd25e7e75bb228581b;hb=31daebfc1031441aa180e3af2e547a8cd2b92c32;hpb=18b507e1b20fc6c32ee50f00fb910a59110c1a1d diff --git a/evaluate.c b/evaluate.c index 85b8a63..e573385 100644 --- a/evaluate.c +++ b/evaluate.c @@ -1,15 +1,31 @@ #include #include #include +#include #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