A chess library for Gleam

Use stockfish piece-square tables

Changed files
+270 -76
src
starfish
+152
gen.js
··· 1 + const tables = { 2 + "pawn": `#( 3 + #(000, 000, 000, 000, 000, 000, 000, 000), 4 + #(-007, 007, -003, -013, 005, -016, 010, -008), 5 + #(005, -012, -007, 022, -008, -005, -015, -008), 6 + #(013, 000, -013, 001, 011, -002, -013, 005), 7 + #(-004, -023, 006, 020, 040, 017, 004, -008), 8 + #(-009, -015, 011, 015, 032, 022, 005, -022), 9 + #(003, 003, 010, 019, 016, 019, 007, -005), 10 + #(000, 000, 000, 000, 000, 000, 000, 000), 11 + )`, 12 + 13 + "knight": `#( 14 + #(-201, -083, -056, -026, -026, -056, -083, -201), 15 + #(-067, -027, 004, 037, 037, 004, -027, -067), 16 + #(-009, 022, 058, 053, 053, 058, 022, -009), 17 + #(-034, 013, 044, 051, 051, 044, 013, -034), 18 + #(-035, 008, 040, 049, 049, 040, 008, -035), 19 + #(-061, -017, 006, 012, 012, 006, -017, -061), 20 + #(-077, -041, -027, -015, -015, -027, -041, -077), 21 + #(-175, -092, -074, -073, -073, -074, -092, -175), 22 + )`, 23 + 24 + "bishop": `#( 25 + #(-048, 001, -014, -023, -023, -014, 001, -048), 26 + #(-017, -014, 005, 000, 000, 005, -014, -017), 27 + #(-016, 006, 001, 011, 011, 001, 006, -016), 28 + #(-012, 029, 022, 031, 031, 022, 029, -012), 29 + #(-005, 011, 025, 039, 039, 025, 011, -005), 30 + #(-007, 021, -005, 017, 017, -005, 021, -007), 31 + #(-015, 008, 019, 004, 004, 019, 008, -015), 32 + #(-053, -005, -008, -023, -023, -008, -005, -053), 33 + )`, 34 + 35 + "rook": `#( 36 + #(-017, -019, -001, 009, 009, -001, -019, -017), 37 + #(-002, 012, 016, 018, 018, 016, 012, -002), 38 + #(-022, -002, 006, 012, 012, 006, -002, -022), 39 + #(-027, -015, -004, 003, 003, -004, -015, -027), 40 + #(-013, -005, -004, -006, -006, -004, -005, -013), 41 + #(-025, -011, -001, 003, 003, -001, -011, -025), 42 + #(-021, -013, -008, 006, 006, -008, -013, -021), 43 + #(-031, -020, -014, -005, -005, -014, -020, -031), 44 + )`, 45 + 46 + "queen": `#( 47 + #(-002, -002, 001, -002, -002, 001, -002, -002), 48 + #(-005, 006, 010, 008, 008, 010, 006, -005), 49 + #(-004, 010, 006, 008, 008, 006, 010, -004), 50 + #(000, 014, 012, 005, 005, 012, 014, 000), 51 + #(004, 005, 009, 008, 008, 009, 005, 004), 52 + #(-003, 006, 013, 007, 007, 013, 006, -003), 53 + #(-003, 005, 008, 012, 012, 008, 005, -003), 54 + #(003, -005, -005, 004, 004, -005, -005, 003), 55 + )`, 56 + 57 + "king": `#( 58 + #(059, 089, 045, -001, -001, 045, 089, 059), 59 + #(088, 120, 065, 033, 033, 065, 120, 088), 60 + #(123, 145, 081, 031, 031, 081, 145, 123), 61 + #(154, 179, 105, 070, 070, 105, 179, 154), 62 + #(164, 190, 138, 098, 098, 138, 190, 164), 63 + #(195, 258, 169, 120, 120, 169, 258, 195), 64 + #(278, 303, 234, 179, 179, 234, 303, 278), 65 + #(271, 327, 271, 198, 198, 271, 327, 271), 66 + )`, 67 + 68 + "pawn_endgame": `#( 69 + #(000, 000, 000, 000, 000, 000, 000, 000), 70 + #(000, -011, 012, 021, 025, 019, 004, 007), 71 + #(028, 020, 021, 028, 030, 007, 006, 013), 72 + #(010, 005, 004, -005, -005, -005, 014, 009), 73 + #(006, -002, -008, -004, -013, -012, -010, -009), 74 + #(-010, -010, -010, 004, 004, 003, -006, -004), 75 + #(-010, -006, 010, 000, 014, 007, -005, -019), 76 + #(000, 000, 000, 000, 000, 000, 000, 000), 77 + )`, 78 + 79 + "knight_endgame": `#( 80 + #(-100, -088, -056, -017, -017, -056, -088, -100), 81 + #(-069, -050, -051, 012, 012, -051, -050, -069), 82 + #(-051, -044, -016, 017, 017, -016, -044, -051), 83 + #(-045, -016, 009, 039, 039, 009, -016, -045), 84 + #(-035, -002, 013, 028, 028, 013, -002, -035), 85 + #(-040, -027, -008, 029, 029, -008, -027, -040), 86 + #(-067, -054, -018, 008, 008, -018, -054, -067), 87 + #(-096, -065, -049, -021, -021, -049, -065, -096), 88 + )`, 89 + 90 + "bishop_endgame": `#( 91 + #(-046, -042, -037, -024, -024, -037, -042, -046), 92 + #(-031, -020, -001, 001, 001, -001, -020, -031), 93 + #(-030, 006, 004, 006, 006, 004, 006, -030), 94 + #(-017, -001, -014, 015, 015, -014, -001, -017), 95 + #(-020, -006, 000, 017, 017, 000, -006, -020), 96 + #(-016, -001, -002, 010, 010, -002, -001, -016), 97 + #(-037, -013, -017, 001, 001, -017, -013, -037), 98 + #(-057, -030, -037, -012, -012, -037, -030, -057), 99 + )`, 100 + 101 + "rook_endgame": `#( 102 + #(018, 000, 019, 013, 013, 019, 000, 018), 103 + #(004, 005, 020, -005, -005, 020, 005, 004), 104 + #(006, 001, -007, 010, 010, -007, 001, 006), 105 + #(-005, 008, 007, -006, -006, 007, 008, -005), 106 + #(-006, 001, -009, 007, 007, -009, 001, -006), 107 + #(006, -008, -002, -006, -006, -002, -008, 006), 108 + #(-012, -009, -001, -002, -002, -001, -009, -012), 109 + #(-009, -013, -010, -009, -009, -010, -013, -009), 110 + )`, 111 + 112 + "queen_endgame": `#( 113 + #(-075, -052, -043, -036, -036, -043, -052, -075), 114 + #(-050, -027, -024, -008, -008, -024, -027, -050), 115 + #(-038, -018, -012, 001, 001, -012, -018, -038), 116 + #(-029, -006, 009, 021, 021, 009, -006, -029), 117 + #(-023, -003, 013, 024, 024, 013, -003, -023), 118 + #(-039, -018, -009, 003, 003, -009, -018, -039), 119 + #(-055, -031, -022, -004, -004, -022, -031, -055), 120 + #(-069, -057, -047, -026, -026, -047, -057, -069), 121 + )`, 122 + 123 + "king_endgame": `#( 124 + #(011, 059, 073, 078, 078, 073, 059, 011), 125 + #(047, 121, 116, 131, 131, 116, 121, 047), 126 + #(092, 172, 184, 191, 191, 184, 172, 092), 127 + #(096, 166, 199, 199, 199, 199, 166, 096), 128 + #(103, 156, 172, 172, 172, 172, 156, 103), 129 + #(088, 130, 169, 175, 175, 169, 130, 088), 130 + #(053, 100, 133, 135, 135, 133, 100, 053), 131 + #(001, 045, 085, 076, 076, 085, 045, 001), 132 + )`, 133 + } 134 + 135 + let out = ""; 136 + 137 + for (let [name, table] of Object.entries(tables)) { 138 + if (!table.startsWith("#(\n")) throw undefined; 139 + if (!table.endsWith("\n)")) throw undefined; 140 + 141 + table = table.slice(3, table.length - 2); 142 + 143 + const rows = table.split("\n").reverse(); 144 + 145 + const reverseTable = `#( 146 + ${rows.join("\n")} 147 + )`; 148 + 149 + out += `const ${name} = ${reverseTable}\n\n`; 150 + } 151 + 152 + console.log(out);
+118 -76
src/starfish/internal/piece_table.gleam
··· 12 12 // need to worry about the cost of updating. 13 13 14 14 const pawn = #( 15 - #(0, 0, 0, 0, 0, 0, 0, 0), 16 - #(30, 30, 30, 30, 30, 30, 30, 30), 17 - #(10, 10, 20, 30, 30, 20, 10, 10), 18 - #(5, 5, 10, 25, 25, 10, 5, 5), 19 - #(0, 0, 0, 20, 20, 0, 0, 0), 20 - #(5, -5, -10, 0, 0, -10, -5, 5), 21 - #(5, 10, 10, -20, -20, 10, 10, 5), 22 - #(0, 0, 0, 0, 0, 0, 0, 0), 15 + #(000, 000, 000, 000, 000, 000, 000, 000), 16 + #(003, 003, 010, 019, 016, 019, 007, -005), 17 + #(-009, -015, 011, 015, 032, 022, 005, -022), 18 + #(-004, -023, 006, 020, 040, 017, 004, -008), 19 + #(013, 000, -013, 001, 011, -002, -013, 005), 20 + #(005, -012, -007, 022, -008, -005, -015, -008), 21 + #(-007, 007, -003, -013, 005, -016, 010, -008), 22 + #(000, 000, 000, 000, 000, 000, 000, 000), 23 23 ) 24 24 25 25 const knight = #( 26 - #(-50, -40, -30, -30, -30, -30, -40, -50), 27 - #(-40, -20, 0, 0, 0, 0, -20, -40), 28 - #(-30, 0, 10, 15, 15, 10, 0, -30), 29 - #(-30, 5, 15, 20, 20, 15, 5, -30), 30 - #(-30, 0, 15, 20, 20, 15, 0, -30), 31 - #(-30, 5, 10, 15, 15, 10, 5, -30), 32 - #(-40, -20, 0, 5, 5, 0, -20, -40), 33 - #(-50, -40, -30, -30, -30, -30, -40, -50), 26 + #(-175, -092, -074, -073, -073, -074, -092, -175), 27 + #(-077, -041, -027, -015, -015, -027, -041, -077), 28 + #(-061, -017, 006, 012, 012, 006, -017, -061), 29 + #(-035, 008, 040, 049, 049, 040, 008, -035), 30 + #(-034, 013, 044, 051, 051, 044, 013, -034), 31 + #(-009, 022, 058, 053, 053, 058, 022, -009), 32 + #(-067, -027, 004, 037, 037, 004, -027, -067), 33 + #(-201, -083, -056, -026, -026, -056, -083, -201), 34 34 ) 35 35 36 36 const bishop = #( 37 - #(-20, -10, -10, -10, -10, -10, -10, -20), 38 - #(-10, 0, 0, 0, 0, 0, 0, -10), 39 - #(-10, 0, 5, 10, 10, 5, 0, -10), 40 - #(-10, 5, 5, 10, 10, 5, 5, -10), 41 - #(-10, 0, 10, 10, 10, 10, 0, -10), 42 - #(-10, 10, 10, 10, 10, 10, 10, -10), 43 - #(-10, 5, 0, 0, 0, 0, 5, -10), 44 - #(-20, -10, -10, -10, -10, -10, -10, -20), 37 + #(-053, -005, -008, -023, -023, -008, -005, -053), 38 + #(-015, 008, 019, 004, 004, 019, 008, -015), 39 + #(-007, 021, -005, 017, 017, -005, 021, -007), 40 + #(-005, 011, 025, 039, 039, 025, 011, -005), 41 + #(-012, 029, 022, 031, 031, 022, 029, -012), 42 + #(-016, 006, 001, 011, 011, 001, 006, -016), 43 + #(-017, -014, 005, 000, 000, 005, -014, -017), 44 + #(-048, 001, -014, -023, -023, -014, 001, -048), 45 45 ) 46 46 47 47 const rook = #( 48 - #(0, 0, 0, 0, 0, 0, 0, 0), 49 - #(5, 10, 10, 10, 10, 10, 10, 5), 50 - #(-5, 0, 0, 0, 0, 0, 0, -5), 51 - #(-5, 0, 0, 0, 0, 0, 0, -5), 52 - #(-5, 0, 0, 0, 0, 0, 0, -5), 53 - #(-5, 0, 0, 0, 0, 0, 0, -5), 54 - #(-5, 0, 0, 0, 0, 0, 0, -5), 55 - #(0, 0, 0, 5, 5, 0, 0, 0), 48 + #(-031, -020, -014, -005, -005, -014, -020, -031), 49 + #(-021, -013, -008, 006, 006, -008, -013, -021), 50 + #(-025, -011, -001, 003, 003, -001, -011, -025), 51 + #(-013, -005, -004, -006, -006, -004, -005, -013), 52 + #(-027, -015, -004, 003, 003, -004, -015, -027), 53 + #(-022, -002, 006, 012, 012, 006, -002, -022), 54 + #(-002, 012, 016, 018, 018, 016, 012, -002), 55 + #(-017, -019, -001, 009, 009, -001, -019, -017), 56 56 ) 57 57 58 58 const queen = #( 59 - #(-20, -10, -10, -5, -5, -10, -10, -20), 60 - #(-10, 0, 0, 0, 0, 0, 0, -10), 61 - #(-10, 0, 5, 5, 5, 5, 0, -10), 62 - #(-5, 0, 5, 5, 5, 5, 0, -5), 63 - #(0, 0, 5, 5, 5, 5, 0, -5), 64 - #(-10, 5, 5, 5, 5, 5, 0, -10), 65 - #(-10, 0, 5, 0, 0, 0, 0, -10), 66 - #(-20, -10, -10, -5, -5, -10, -10, -20), 59 + #(003, -005, -005, 004, 004, -005, -005, 003), 60 + #(-003, 005, 008, 012, 012, 008, 005, -003), 61 + #(-003, 006, 013, 007, 007, 013, 006, -003), 62 + #(004, 005, 009, 008, 008, 009, 005, 004), 63 + #(000, 014, 012, 005, 005, 012, 014, 000), 64 + #(-004, 010, 006, 008, 008, 006, 010, -004), 65 + #(-005, 006, 010, 008, 008, 010, 006, -005), 66 + #(-002, -002, 001, -002, -002, 001, -002, -002), 67 67 ) 68 68 69 69 const king = #( 70 - #(-30, -40, -40, -50, -50, -40, -40, -30), 71 - #(-30, -40, -40, -50, -50, -40, -40, -30), 72 - #(-30, -40, -40, -50, -50, -40, -40, -30), 73 - #(-30, -40, -40, -50, -50, -40, -40, -30), 74 - #(-20, -30, -30, -40, -40, -30, -30, -20), 75 - #(-10, -20, -20, -20, -20, -20, -20, -10), 76 - #(20, 20, 0, 0, 0, 0, 20, 20), 77 - #(20, 30, 10, 0, 0, 10, 30, 20), 78 - ) 79 - 80 - /// In the beginning and middle of the game, the king must be kept safe. However 81 - /// as the game progresses towards the end, the king should become more aggressive 82 - /// so we use a different set of scores for kings in the endgame. 83 - const king_endgame = #( 84 - #(-50, -40, -30, -20, -20, -30, -40, -50), 85 - #(-30, -20, -10, 0, 0, -10, -20, -30), 86 - #(-30, -10, 20, 30, 30, 20, -10, -30), 87 - #(-30, -10, 30, 40, 40, 30, -10, -30), 88 - #(-30, -10, 30, 40, 40, 30, -10, -30), 89 - #(-30, -10, 20, 30, 30, 20, -10, -30), 90 - #(-30, -30, 0, 0, 0, 0, -30, -30), 91 - #(-50, -30, -30, -30, -30, -30, -30, -50), 70 + #(271, 327, 271, 198, 198, 271, 327, 271), 71 + #(278, 303, 234, 179, 179, 234, 303, 278), 72 + #(195, 258, 169, 120, 120, 169, 258, 195), 73 + #(164, 190, 138, 098, 098, 138, 190, 164), 74 + #(154, 179, 105, 070, 070, 105, 179, 154), 75 + #(123, 145, 081, 031, 031, 081, 145, 123), 76 + #(088, 120, 065, 033, 033, 065, 120, 088), 77 + #(059, 089, 045, -001, -001, 045, 089, 059), 92 78 ) 93 79 94 80 /// In the middlegame, pawns are encouraged to protect the king's castling 95 81 /// squares. In the endgame though, they no longer need to protect the king and 96 82 /// instead should promote. Therefore, we use a different table to encourage this. 97 83 const pawn_endgame = #( 98 - #(100, 100, 100, 100, 100, 100, 100, 100), 99 - #(80, 80, 80, 80, 80, 80, 80, 80), 100 - #(50, 50, 50, 50, 50, 50, 50, 50), 101 - #(30, 30, 30, 30, 30, 30, 30, 30), 102 - #(10, 10, 10, 10, 10, 10, 10, 10), 103 - // Since pawns can double-move, the first two ranks are equivalent from the 104 - // pawn's perspective. 105 - #(-10, -10, -10, -10, -10, -10, -10, -10), 106 - #(-10, -10, -10, -10, -10, -10, -10, -10), 107 - #(-10, -10, -10, -10, -10, -10, -10, -10), 84 + #(000, 000, 000, 000, 000, 000, 000, 000), 85 + #(-010, -006, 010, 000, 014, 007, -005, -019), 86 + #(-010, -010, -010, 004, 004, 003, -006, -004), 87 + #(006, -002, -008, -004, -013, -012, -010, -009), 88 + #(010, 005, 004, -005, -005, -005, 014, 009), 89 + #(028, 020, 021, 028, 030, 007, 006, 013), 90 + #(000, -011, 012, 021, 025, 019, 004, 007), 91 + #(000, 000, 000, 000, 000, 000, 000, 000), 92 + ) 93 + 94 + const knight_endgame = #( 95 + #(-096, -065, -049, -021, -021, -049, -065, -096), 96 + #(-067, -054, -018, 008, 008, -018, -054, -067), 97 + #(-040, -027, -008, 029, 029, -008, -027, -040), 98 + #(-035, -002, 013, 028, 028, 013, -002, -035), 99 + #(-045, -016, 009, 039, 039, 009, -016, -045), 100 + #(-051, -044, -016, 017, 017, -016, -044, -051), 101 + #(-069, -050, -051, 012, 012, -051, -050, -069), 102 + #(-100, -088, -056, -017, -017, -056, -088, -100), 103 + ) 104 + 105 + const bishop_endgame = #( 106 + #(-057, -030, -037, -012, -012, -037, -030, -057), 107 + #(-037, -013, -017, 001, 001, -017, -013, -037), 108 + #(-016, -001, -002, 010, 010, -002, -001, -016), 109 + #(-020, -006, 000, 017, 017, 000, -006, -020), 110 + #(-017, -001, -014, 015, 015, -014, -001, -017), 111 + #(-030, 006, 004, 006, 006, 004, 006, -030), 112 + #(-031, -020, -001, 001, 001, -001, -020, -031), 113 + #(-046, -042, -037, -024, -024, -037, -042, -046), 114 + ) 115 + 116 + const rook_endgame = #( 117 + #(-009, -013, -010, -009, -009, -010, -013, -009), 118 + #(-012, -009, -001, -002, -002, -001, -009, -012), 119 + #(006, -008, -002, -006, -006, -002, -008, 006), 120 + #(-006, 001, -009, 007, 007, -009, 001, -006), 121 + #(-005, 008, 007, -006, -006, 007, 008, -005), 122 + #(006, 001, -007, 010, 010, -007, 001, 006), 123 + #(004, 005, 020, -005, -005, 020, 005, 004), 124 + #(018, 000, 019, 013, 013, 019, 000, 018), 125 + ) 126 + 127 + const queen_endgame = #( 128 + #(-069, -057, -047, -026, -026, -047, -057, -069), 129 + #(-055, -031, -022, -004, -004, -022, -031, -055), 130 + #(-039, -018, -009, 003, 003, -009, -018, -039), 131 + #(-023, -003, 013, 024, 024, 013, -003, -023), 132 + #(-029, -006, 009, 021, 021, 009, -006, -029), 133 + #(-038, -018, -012, 001, 001, -012, -018, -038), 134 + #(-050, -027, -024, -008, -008, -024, -027, -050), 135 + #(-075, -052, -043, -036, -036, -043, -052, -075), 136 + ) 137 + 138 + /// In the beginning and middle of the game, the king must be kept safe. However 139 + /// as the game progresses towards the end, the king should become more aggressive 140 + /// so we use a different set of scores for kings in the endgame. 141 + const king_endgame = #( 142 + #(001, 045, 085, 076, 076, 085, 045, 001), 143 + #(053, 100, 133, 135, 135, 133, 100, 053), 144 + #(088, 130, 169, 175, 175, 169, 130, 088), 145 + #(103, 156, 172, 172, 172, 172, 156, 103), 146 + #(096, 166, 199, 199, 199, 199, 166, 096), 147 + #(092, 172, 184, 191, 191, 184, 172, 092), 148 + #(047, 121, 116, 131, 131, 116, 121, 047), 149 + #(011, 059, 073, 078, 078, 073, 059, 011), 108 150 ) 109 151 110 152 type Table = ··· 178 220 let table = case piece { 179 221 board.Pawn -> pawn_endgame 180 222 board.King -> king_endgame 181 - board.Bishop -> bishop 182 - board.Knight -> knight 183 - board.Queen -> queen 184 - board.Rook -> rook 223 + board.Bishop -> bishop_endgame 224 + board.Knight -> knight_endgame 225 + board.Queen -> queen_endgame 226 + board.Rook -> rook_endgame 185 227 } 186 228 187 229 get(table, position, colour)