Skip to content

Commit 2367510

Browse files
author
Paul T
authored
feat: add support for doubled pawn detection and scoring (#157)
Elo | 2.57 +- 2.06 (95%) SPRT | 8.0+0.08s Threads=1 Hash=16MB LLR | 2.98 (-2.94, 2.94) [0.00, 5.00] Games | N: 32866 W: 5392 L: 5149 D: 22325 Penta | [323, 3493, 8592, 3668, 357] https://pyronomy.pythonanywhere.com/test/3396/ bench: 1147137
1 parent 6d3b2de commit 2367510

12 files changed

Lines changed: 225 additions & 111 deletions

File tree

chess/src/definitions.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ impl NumberOf {
5757
pub const CASTLING_OPTIONS: usize = 16;
5858
// Passed pawns cannot be on ranks 1 or 8
5959
pub const PASSED_PAWN_RANKS: usize = 6;
60+
pub const DOUBLED_PAWN_FILES: usize = 8;
6061
}
6162

6263
pub const EMPTY: u64 = 0;

engine/src/evaluation.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@ impl<Values: EvalValues<ReturnScore = PhasedScore>> Eval<Board> for Evaluation<V
9393
mg[side as usize] += passed_pawn_bonus.mg() as i32;
9494
eg[side as usize] += passed_pawn_bonus.eg() as i32;
9595
}
96+
97+
let doubled_pawn_value = self.values.doubled_pawn_value(sq as u8, side);
98+
if pawn_structure.doubled_pawns[side as usize].is_square_occupied(sq as u8) {
99+
mg[side as usize] += doubled_pawn_value.mg() as i32;
100+
eg[side as usize] += doubled_pawn_value.eg() as i32;
101+
}
96102
}
97103
let phased_score: PhasedScore = self.values.psqt(sq as u8, piece, side);
98104
mg[side as usize] += phased_score.mg() as i32;
@@ -101,6 +107,7 @@ impl<Values: EvalValues<ReturnScore = PhasedScore>> Eval<Board> for Evaluation<V
101107
game_phase += GAME_PHASE_INC[piece as usize] as i32;
102108
}
103109
}
110+
104111
let stm_idx = side_to_move as usize;
105112
let opposite = Side::opposite(side_to_move) as usize;
106113
let mg_score = mg[stm_idx] - mg[opposite];
@@ -288,13 +295,13 @@ mod tests {
288295
];
289296

290297
let scores: [ScoreType; 128] = [
291-
0, 27, 666, 674, -666, -674, 1287, -1287, 584, 611, -584, -611, 0, 7, 16, 13, -7, -16,
292-
-13, -666, -674, 666, 674, -1287, 1287, -584, -611, 584, 611, 0, -7, -16, -13, 7, 16,
293-
13, 2, -1, 0, -447, 536, -2, 1, 5, 447, -536, -21, -45, 812, -843, 28, 45, -812, 843,
294-
0, -5, 0, 5, -1236, -1346, -47, 1209, -1346, 47, 214, 239, -214, -239, -18, -214, -239,
295-
214, 239, 18, 13, 13, 0, 0, 0, 19, -19, -11, 0, 0, 0, -19, 19, 11, -11, 9, 11, 11, -11,
296-
-11, -282, 0, 11, -9, -11, -11, 11, 11, 282, 0, 2, 5, -2, -5, 10, -10, 0, -2, -5, 2, 5,
297-
-10, 10, 0, -10, 11, 40, 62, 10, -11, -40, -62, 48, 27,
298+
0, 22, 659, 668, -659, -668, 1276, -1276, 578, 606, -578, -606, 0, 7, 17, 15, -7, -17,
299+
-15, -659, -668, 659, 668, -1276, 1276, -578, -606, 578, 606, 0, -7, -17, -15, 7, 17,
300+
15, 1, -1, 0, -440, 531, -1, 1, 5, 440, -531, -21, -43, 808, -839, 29, 43, -808, 839,
301+
0, -5, 0, 5, -1226, -1337, -48, 1199, -1337, 48, 214, 239, -214, -239, -16, -214, -239,
302+
214, 239, 16, 17, 17, 0, 0, 0, 19, -19, -10, 0, 0, 0, -19, 19, 10, -13, 9, 11, 12, -11,
303+
-12, -281, 2, 13, -9, -11, -12, 11, 12, 281, -2, 3, 7, -3, -7, 10, -10, 0, -3, -7, 3,
304+
7, -10, 10, 0, -9, 11, 37, 59, 9, -11, -37, -59, 39, 27,
298305
];
299306

300307
let eval = ByteKnightEvaluation::default();

engine/src/hce_values.rs

Lines changed: 68 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -24,79 +24,90 @@ pub const GAME_PHASE_MAX: i32 = 24;
2424
pub const PSQTS : [[PhasedScore; NumberOf::SQUARES]; NumberOf::PIECE_TYPES] = [
2525
// King
2626
[
27-
S( 15, -99), S( -2, -44), S( 19, -27), S(-123, 25), S( -76, 5), S( -11, 5), S( 59, -6), S( 181, -126),
28-
S(-115, 5), S( -74, 38), S(-110, 51), S( -6, 34), S( -57, 53), S( -54, 66), S( 6, 51), S( -18, 18),
29-
S(-136, 20), S( -18, 41), S( -90, 62), S(-117, 75), S( -72, 73), S( 16, 64), S( -4, 62), S( -47, 30),
30-
S( -99, 10), S(-110, 48), S(-127, 69), S(-179, 83), S(-166, 82), S(-122, 75), S(-117, 64), S(-143, 35),
31-
S(-101, -0), S(-104, 33), S(-142, 61), S(-174, 78), S(-166, 76), S(-124, 61), S(-128, 47), S(-157, 30),
32-
S( -43, -12), S( -30, 15), S( -92, 40), S(-106, 53), S( -98, 53), S( -95, 43), S( -45, 21), S( -63, 7),
33-
S( 54, -32), S( 7, -2), S( -9, 11), S( -46, 22), S( -48, 26), S( -28, 16), S( 26, -5), S( 36, -25),
34-
S( 48, -74), S( 73, -51), S( 44, -29), S( -65, -10), S( 5, -38), S( -38, -12), S( 52, -41), S( 54, -73),
27+
S( 16, -99), S( -0, -44), S( 18, -26), S(-122, 25), S( -77, 7), S( -10, 6), S( 60, -7), S( 181, -125),
28+
S(-113, 4), S( -73, 38), S(-109, 50), S( -8, 34), S( -56, 53), S( -50, 65), S( 5, 51), S( -14, 17),
29+
S(-134, 20), S( -16, 41), S( -90, 62), S(-115, 74), S( -70, 72), S( 17, 64), S( -4, 61), S( -46, 30),
30+
S( -95, 10), S(-108, 47), S(-124, 68), S(-176, 81), S(-163, 81), S(-122, 75), S(-116, 63), S(-142, 35),
31+
S( -99, 0), S(-102, 33), S(-140, 60), S(-171, 78), S(-165, 75), S(-124, 61), S(-129, 47), S(-157, 30),
32+
S( -45, -12), S( -29, 15), S( -91, 40), S(-105, 53), S( -99, 53), S( -96, 43), S( -47, 21), S( -65, 7),
33+
S( 51, -32), S( 5, -2), S( -10, 11), S( -47, 22), S( -49, 26), S( -29, 16), S( 22, -4), S( 33, -24),
34+
S( 46, -73), S( 70, -50), S( 41, -29), S( -66, -10), S( 3, -37), S( -40, -11), S( 50, -41), S( 52, -71),
3535
],
3636
// Queen
3737
[
38-
S( 797, 1360), S( 808, 1370), S( 840, 1389), S( 874, 1377), S( 873, 1376), S( 885, 1362), S( 904, 1315), S( 843, 1352),
39-
S( 840, 1321), S( 813, 1367), S( 822, 1402), S( 813, 1423), S( 820, 1441), S( 861, 1396), S( 836, 1383), S( 885, 1355),
40-
S( 840, 1330), S( 838, 1349), S( 835, 1394), S( 852, 1396), S( 857, 1412), S( 903, 1391), S( 905, 1351), S( 901, 1339),
41-
S( 821, 1345), S( 826, 1368), S( 831, 1383), S( 829, 1409), S( 832, 1423), S( 846, 1408), S( 844, 1394), S( 851, 1370),
42-
S( 823, 1340), S( 821, 1371), S( 820, 1380), S( 829, 1402), S( 827, 1401), S( 826, 1391), S( 839, 1369), S( 842, 1356),
43-
S( 820, 1325), S( 829, 1344), S( 823, 1370), S( 822, 1369), S( 825, 1373), S( 833, 1362), S( 847, 1337), S( 839, 1324),
44-
S( 818, 1322), S( 825, 1324), S( 836, 1321), S( 835, 1331), S( 833, 1335), S( 843, 1306), S( 850, 1272), S( 862, 1242),
45-
S( 816, 1313), S( 805, 1321), S( 813, 1324), S( 830, 1314), S( 820, 1319), S( 806, 1317), S( 830, 1285), S( 822, 1288),
38+
S( 790, 1351), S( 802, 1361), S( 832, 1381), S( 866, 1369), S( 865, 1367), S( 877, 1353), S( 896, 1307), S( 835, 1344),
39+
S( 832, 1313), S( 807, 1357), S( 814, 1393), S( 806, 1415), S( 812, 1432), S( 853, 1386), S( 828, 1374), S( 879, 1346),
40+
S( 834, 1321), S( 831, 1340), S( 828, 1383), S( 844, 1386), S( 850, 1402), S( 896, 1381), S( 898, 1342), S( 894, 1330),
41+
S( 814, 1335), S( 819, 1358), S( 825, 1371), S( 822, 1399), S( 825, 1413), S( 838, 1398), S( 838, 1384), S( 844, 1361),
42+
S( 817, 1329), S( 814, 1361), S( 815, 1369), S( 822, 1391), S( 821, 1391), S( 820, 1381), S( 832, 1358), S( 836, 1347),
43+
S( 814, 1315), S( 823, 1333), S( 817, 1360), S( 816, 1359), S( 819, 1363), S( 827, 1352), S( 840, 1327), S( 833, 1314),
44+
S( 812, 1312), S( 818, 1315), S( 830, 1312), S( 829, 1322), S( 827, 1326), S( 837, 1297), S( 843, 1263), S( 854, 1234),
45+
S( 810, 1305), S( 799, 1312), S( 807, 1315), S( 823, 1304), S( 814, 1309), S( 800, 1308), S( 824, 1275), S( 816, 1279),
4646
],
4747
// Rook
4848
[
49-
S( 449, 723), S( 439, 731), S( 447, 741), S( 452, 737), S( 473, 726), S( 490, 717), S( 468, 720), S( 494, 712),
50-
S( 430, 724), S( 428, 736), S( 449, 740), S( 470, 731), S( 455, 731), S( 487, 715), S( 473, 711), S( 506, 698),
51-
S( 406, 723), S( 430, 725), S( 432, 727), S( 436, 724), S( 467, 709), S( 469, 702), S( 510, 693), S( 484, 690),
52-
S( 389, 726), S( 404, 724), S( 408, 732), S( 416, 729), S( 423, 712), S( 424, 705), S( 433, 704), S( 435, 696),
53-
S( 369, 719), S( 373, 724), S( 383, 725), S( 396, 723), S( 396, 719), S( 380, 717), S( 405, 703), S( 396, 699),
54-
S( 362, 714), S( 372, 713), S( 381, 712), S( 381, 718), S( 387, 712), S( 384, 704), S( 421, 682), S( 398, 684),
55-
S( 359, 708), S( 372, 712), S( 388, 711), S( 385, 713), S( 389, 704), S( 392, 700), S( 410, 690), S( 378, 697),
56-
S( 380, 701), S( 381, 711), S( 392, 720), S( 397, 718), S( 402, 710), S( 391, 705), S( 407, 700), S( 382, 692),
49+
S( 447, 718), S( 437, 726), S( 445, 735), S( 449, 731), S( 469, 721), S( 486, 710), S( 465, 715), S( 491, 707),
50+
S( 428, 718), S( 425, 731), S( 446, 734), S( 468, 725), S( 452, 725), S( 484, 709), S( 471, 704), S( 504, 692),
51+
S( 405, 718), S( 428, 719), S( 430, 720), S( 433, 718), S( 463, 703), S( 470, 696), S( 509, 687), S( 483, 684),
52+
S( 388, 720), S( 402, 718), S( 406, 726), S( 414, 722), S( 421, 706), S( 425, 699), S( 434, 698), S( 434, 690),
53+
S( 367, 714), S( 371, 718), S( 382, 719), S( 394, 717), S( 394, 712), S( 381, 711), S( 406, 697), S( 394, 694),
54+
S( 360, 708), S( 371, 707), S( 381, 706), S( 379, 711), S( 386, 705), S( 383, 698), S( 420, 676), S( 396, 678),
55+
S( 357, 701), S( 370, 706), S( 387, 705), S( 383, 706), S( 388, 697), S( 390, 694), S( 409, 683), S( 375, 691),
56+
S( 377, 695), S( 380, 705), S( 390, 714), S( 395, 711), S( 400, 704), S( 389, 698), S( 406, 695), S( 380, 685),
5757
],
5858
// Bishop
5959
[
60-
S( 302, 396), S( 281, 412), S( 293, 407), S( 249, 421), S( 263, 413), S( 280, 404), S( 313, 400), S( 272, 395),
61-
S( 319, 386), S( 345, 405), S( 339, 409), S( 321, 412), S( 352, 402), S( 351, 402), S( 342, 408), S( 329, 383),
62-
S( 331, 414), S( 357, 409), S( 357, 419), S( 382, 408), S( 367, 413), S( 401, 416), S( 376, 408), S( 363, 408),
63-
S( 322, 411), S( 338, 427), S( 361, 421), S( 372, 436), S( 369, 429), S( 365, 425), S( 338, 425), S( 322, 410),
64-
S( 315, 408), S( 329, 424), S( 336, 433), S( 357, 431), S( 354, 429), S( 338, 427), S( 329, 422), S( 324, 395),
65-
S( 326, 405), S( 334, 417), S( 334, 425), S( 337, 425), S( 339, 430), S( 333, 424), S( 336, 406), S( 340, 394),
66-
S( 329, 399), S( 330, 399), S( 342, 397), S( 319, 413), S( 327, 415), S( 341, 403), S( 348, 404), S( 334, 378),
67-
S( 305, 379), S( 327, 399), S( 310, 378), S( 301, 402), S( 306, 397), S( 305, 397), S( 330, 384), S( 317, 363),
60+
S( 301, 393), S( 280, 410), S( 291, 404), S( 249, 418), S( 262, 410), S( 278, 402), S( 313, 398), S( 269, 392),
61+
S( 317, 384), S( 343, 402), S( 337, 407), S( 320, 409), S( 350, 399), S( 349, 399), S( 339, 405), S( 330, 379),
62+
S( 331, 411), S( 355, 406), S( 356, 416), S( 379, 406), S( 365, 411), S( 399, 413), S( 374, 405), S( 362, 406),
63+
S( 321, 407), S( 337, 424), S( 359, 418), S( 370, 432), S( 366, 425), S( 363, 422), S( 337, 422), S( 322, 407),
64+
S( 315, 405), S( 328, 422), S( 336, 430), S( 356, 428), S( 353, 426), S( 337, 425), S( 329, 419), S( 323, 392),
65+
S( 325, 403), S( 334, 414), S( 333, 424), S( 338, 424), S( 337, 428), S( 333, 421), S( 335, 404), S( 338, 392),
66+
S( 329, 397), S( 329, 397), S( 343, 395), S( 318, 411), S( 327, 412), S( 339, 400), S( 346, 401), S( 332, 376),
67+
S( 305, 376), S( 328, 397), S( 309, 377), S( 301, 400), S( 305, 395), S( 304, 395), S( 329, 382), S( 317, 361),
6868
],
6969
// Knight
7070
[
71-
S( 136, 298), S( 176, 361), S( 241, 382), S( 277, 372), S( 310, 376), S( 249, 352), S( 194, 367), S( 196, 274),
72-
S( 279, 361), S( 299, 381), S( 327, 390), S( 347, 388), S( 329, 381), S( 396, 365), S( 298, 378), S( 322, 344),
73-
S( 298, 374), S( 335, 391), S( 352, 410), S( 366, 411), S( 405, 394), S( 410, 386), S( 359, 382), S( 326, 364),
74-
S( 293, 389), S( 308, 411), S( 334, 423), S( 357, 425), S( 338, 426), S( 365, 420), S( 319, 410), S( 330, 379),
75-
S( 279, 390), S( 295, 401), S( 311, 425), S( 313, 426), S( 322, 430), S( 317, 416), S( 316, 401), S( 290, 380),
76-
S( 258, 371), S( 283, 393), S( 297, 404), S( 301, 419), S( 313, 416), S( 302, 399), S( 306, 386), S( 276, 373),
77-
S( 244, 364), S( 257, 380), S( 275, 389), S( 288, 392), S( 289, 391), S( 291, 387), S( 277, 369), S( 274, 373),
78-
S( 197, 356), S( 255, 340), S( 241, 373), S( 257, 375), S( 262, 375), S( 276, 364), S( 258, 346), S( 229, 345),
71+
S( 134, 295), S( 175, 359), S( 238, 380), S( 272, 369), S( 308, 373), S( 246, 350), S( 194, 362), S( 191, 272),
72+
S( 277, 358), S( 296, 379), S( 324, 386), S( 345, 384), S( 326, 378), S( 392, 361), S( 295, 374), S( 322, 340),
73+
S( 296, 371), S( 333, 388), S( 350, 406), S( 362, 408), S( 402, 390), S( 406, 383), S( 357, 379), S( 325, 361),
74+
S( 291, 386), S( 306, 407), S( 333, 419), S( 354, 421), S( 336, 421), S( 363, 416), S( 317, 406), S( 328, 376),
75+
S( 277, 386), S( 293, 397), S( 309, 421), S( 310, 422), S( 320, 426), S( 315, 413), S( 314, 398), S( 289, 376),
76+
S( 257, 368), S( 281, 389), S( 296, 400), S( 300, 415), S( 312, 413), S( 301, 395), S( 304, 382), S( 274, 370),
77+
S( 243, 361), S( 255, 377), S( 273, 387), S( 286, 389), S( 287, 387), S( 290, 384), S( 275, 366), S( 272, 371),
78+
S( 197, 352), S( 254, 335), S( 240, 370), S( 256, 372), S( 261, 372), S( 274, 361), S( 256, 342), S( 228, 345),
7979
],
8080
// Pawn
8181
[
8282
S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0),
83-
S( 169, 319), S( 193, 308), S( 172, 305), S( 205, 249), S( 183, 247), S( 165, 261), S( 94, 309), S( 67, 326),
84-
S( 79, 162), S( 94, 164), S( 123, 116), S( 125, 78), S( 133, 75), S( 166, 96), S( 141, 139), S( 97, 144),
85-
S( 57, 147), S( 81, 139), S( 83, 115), S( 85, 97), S( 108, 97), S( 100, 104), S( 106, 127), S( 81, 122),
86-
S( 46, 130), S( 73, 132), S( 71, 111), S( 89, 105), S( 88, 105), S( 80, 110), S( 91, 122), S( 67, 111),
87-
S( 44, 124), S( 68, 129), S( 67, 110), S( 68, 117), S( 83, 116), S( 72, 113), S( 106, 119), S( 75, 108),
88-
S( 44, 129), S( 68, 132), S( 63, 116), S( 52, 115), S( 73, 126), S( 90, 118), S( 116, 118), S( 67, 108),
83+
S( 169, 318), S( 191, 308), S( 171, 306), S( 201, 247), S( 179, 247), S( 168, 264), S( 104, 310), S( 70, 325),
84+
S( 81, 165), S( 95, 170), S( 127, 122), S( 126, 82), S( 136, 78), S( 172, 104), S( 148, 146), S( 100, 148),
85+
S( 59, 148), S( 81, 143), S( 87, 121), S( 88, 100), S( 112, 100), S( 106, 112), S( 109, 131), S( 82, 125),
86+
S( 47, 131), S( 72, 134), S( 74, 116), S( 90, 106), S( 89, 107), S( 84, 116), S( 92, 124), S( 67, 113),
87+
S( 45, 125), S( 68, 132), S( 71, 116), S( 70, 118), S( 86, 118), S( 78, 120), S( 109, 121), S( 73, 109),
88+
S( 45, 129), S( 68, 134), S( 65, 123), S( 53, 117), S( 75, 128), S( 92, 123), S( 117, 119), S( 65, 109),
8989
S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0),
9090
],
9191
];
9292

9393
pub const PASSED_PAWN_BONUS: [PhasedScore; NumberOf::PASSED_PAWN_RANKS] = [
94-
S(-24, 6),
95-
S(2, 122),
96-
S(8, 54),
97-
S(-16, 27),
98-
S(-18, 4),
99-
S(-13, -2),
94+
S(-19, 7),
95+
S(4, 119),
96+
S(8, 52),
97+
S(-16, 25),
98+
S(-21, 1),
99+
S(-14, -2),
100+
];
101+
102+
pub const DOUBLED_PAWN_VALUES: [PhasedScore; NumberOf::DOUBLED_PAWN_FILES] = [
103+
S(-21, -46),
104+
S(-3, -38),
105+
S(-16, -35),
106+
S(-11, -23),
107+
S(-19, -22),
108+
S(-17, -35),
109+
S(-20, -34),
110+
S(-24, -51),
100111
];
101112

102113
const RANK_1: u8 = 1;
@@ -115,4 +126,9 @@ impl EvalValues for ByteKnightValues {
115126
let (_file, rank) = square::from_square(square::flip_if(side == Side::White, square));
116127
PASSED_PAWN_BONUS[(rank - RANK_1) as usize]
117128
}
129+
130+
fn doubled_pawn_value(&self, square: u8, side: Side) -> Self::ReturnScore {
131+
let (file, _rank) = square::from_square(square::flip_if(side == Side::White, square));
132+
DOUBLED_PAWN_VALUES[file as usize]
133+
}
118134
}

0 commit comments

Comments
 (0)