From f5a226046125bf0db06e4352fc8b75ead39e66e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20C=C3=A1ceres?= Date: Tue, 30 Jul 2024 02:47:41 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9A=96=20Allow=20bucketed=20PSQTs=20+=20impl?= =?UTF-8?q?ement=20friendly=20king=20related=20PSQTs=20(king/queenside)=20?= =?UTF-8?q?(#873)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Allow bucketed PSQTs, with a constant (`PSQTBucketCount`) that determines the number of buckets/PSQT instances per conceptual PSQT. They're `short[PSQTBucketCount][64]` now, with `PackedPSQT` being `short[2][12][64]` (candidate for flattenning?) - Make `PSQTBucketCount = 2` and split PSQTs according to friendly king in kingside or queenside of the board. --- src/Lynx.Benchmark/EnumCasting_Benchmark.cs | 24 +- src/Lynx.Cli/appsettings.json | 240 +++++------ src/Lynx.Dev/Program.cs | 4 +- src/Lynx/Configuration.cs | 140 +++---- src/Lynx/EvaluationConstants.cs | 422 ++++++++++++++------ src/Lynx/Model/Position.cs | 17 +- tests/Lynx.Test/EvaluationConstantsTest.cs | 55 +-- tests/Lynx.Test/Model/PositionTest.cs | 4 +- 8 files changed, 537 insertions(+), 369 deletions(-) diff --git a/src/Lynx.Benchmark/EnumCasting_Benchmark.cs b/src/Lynx.Benchmark/EnumCasting_Benchmark.cs index d754ae797..0cc6bf21c 100644 --- a/src/Lynx.Benchmark/EnumCasting_Benchmark.cs +++ b/src/Lynx.Benchmark/EnumCasting_Benchmark.cs @@ -35,12 +35,12 @@ public int Constant(int iterations) var sum = 0; for (int i = 0; i < iterations; ++i) { - sum += EvaluationConstants.MiddleGamePieceValues[Pawn]; - sum += EvaluationConstants.MiddleGamePieceValues[Pawn]; - sum += EvaluationConstants.MiddleGamePieceValues[Pawn]; - sum += EvaluationConstants.MiddleGamePieceValues[Pawn]; - sum += EvaluationConstants.MiddleGamePieceValues[Pawn]; - sum += EvaluationConstants.MiddleGamePieceValues[Pawn]; + sum += EvaluationConstants.MiddleGamePieceValues[0][Pawn]; + sum += EvaluationConstants.MiddleGamePieceValues[0][Pawn]; + sum += EvaluationConstants.MiddleGamePieceValues[0][Pawn]; + sum += EvaluationConstants.MiddleGamePieceValues[0][Pawn]; + sum += EvaluationConstants.MiddleGamePieceValues[0][Pawn]; + sum += EvaluationConstants.MiddleGamePieceValues[0][Pawn]; } return sum; @@ -53,12 +53,12 @@ public int Cast(int iterations) var sum = 0; for (int i = 0; i < iterations; ++i) { - sum += EvaluationConstants.MiddleGamePieceValues[(int)Piece.P]; - sum += EvaluationConstants.MiddleGamePieceValues[(int)Piece.P]; - sum += EvaluationConstants.MiddleGamePieceValues[(int)Piece.P]; - sum += EvaluationConstants.MiddleGamePieceValues[(int)Piece.P]; - sum += EvaluationConstants.MiddleGamePieceValues[(int)Piece.P]; - sum += EvaluationConstants.MiddleGamePieceValues[(int)Piece.P]; + sum += EvaluationConstants.MiddleGamePieceValues[0][(int)Piece.P]; + sum += EvaluationConstants.MiddleGamePieceValues[0][(int)Piece.P]; + sum += EvaluationConstants.MiddleGamePieceValues[0][(int)Piece.P]; + sum += EvaluationConstants.MiddleGamePieceValues[0][(int)Piece.P]; + sum += EvaluationConstants.MiddleGamePieceValues[0][(int)Piece.P]; + sum += EvaluationConstants.MiddleGamePieceValues[0][(int)Piece.P]; } return sum; diff --git a/src/Lynx.Cli/appsettings.json b/src/Lynx.Cli/appsettings.json index a8c53d742..6771546a6 100644 --- a/src/Lynx.Cli/appsettings.json +++ b/src/Lynx.Cli/appsettings.json @@ -60,7 +60,7 @@ // Evaluation "IsolatedPawnPenalty": { - "MG": -19, + "MG": -20, "EG": -14 }, "OpenFileRookBonus": { @@ -76,23 +76,23 @@ "EG": 8 }, "SemiOpenFileKingPenalty": { - "MG": -30, - "EG": 18 + "MG": -21, + "EG": 17 }, "OpenFileKingPenalty": { - "MG": -96, + "MG": -86, "EG": 15 }, "KingShieldBonus": { - "MG": 23, - "EG": -11 + "MG": 11, + "EG": -9 }, "BishopPairBonus": { - "MG": 30, + "MG": 31, "EG": 81 }, "PieceProtectedByPawnBonus": { - "MG": 7, + "MG": 6, "EG": 11 }, "PieceAttackedByPawnPenalty": { @@ -105,28 +105,28 @@ "EG": 0 }, "Rank1": { - "MG": 2, + "MG": 7, "EG": 11 }, "Rank2": { - "MG": -11, - "EG": 20 + "MG": -6, + "EG": 19 }, "Rank3": { - "MG": -12, - "EG": 47 + "MG": -8, + "EG": 46 }, "Rank4": { - "MG": 18, + "MG": 21, "EG": 81 }, "Rank5": { - "MG": 63, + "MG": 64, "EG": 161 }, "Rank6": { - "MG": 102, - "EG": 225 + "MG": 100, + "EG": 227 }, "Rank7": { "MG": 0, @@ -148,27 +148,27 @@ "EG": 0 }, "Count3": { - "MG": 37, - "EG": -5 + "MG": 36, + "EG": 0 }, "Count4": { - "MG": 51, - "EG": -8 + "MG": 47, + "EG": -6 }, "Count5": { - "MG": 24, - "EG": 24 + "MG": 20, + "EG": 23 }, "Count6": { - "MG": 22, - "EG": 13 + "MG": 18, + "EG": 14 }, "Count7": { - "MG": 19, + "MG": 18, "EG": 3 }, "Count8": { - "MG": 15, + "MG": 14, "EG": 6 }, "Count9": { @@ -180,71 +180,71 @@ "EG": 9 }, "Count11": { - "MG": 2, + "MG": 4, "EG": 13 }, "Count12": { - "MG": 0, + "MG": 3, "EG": 9 }, "Count13": { - "MG": -5, - "EG": 12 + "MG": -3, + "EG": 13 }, "Count14": { - "MG": -15, + "MG": -12, "EG": 15 }, "Count15": { - "MG": -26, - "EG": 18 + "MG": -22, + "EG": 17 }, "Count16": { - "MG": -35, - "EG": 15 + "MG": -30, + "EG": 14 }, "Count17": { - "MG": -46, + "MG": -42, "EG": 12 }, "Count18": { - "MG": -52, - "EG": 10 + "MG": -47, + "EG": 9 }, "Count19": { - "MG": -60, - "EG": 3 + "MG": -53, + "EG": 2 }, "Count20": { - "MG": -51, - "EG": -5 + "MG": -42, + "EG": -6 }, "Count21": { - "MG": -46, - "EG": -13 + "MG": -35, + "EG": -15 }, "Count22": { - "MG": -44, + "MG": -35, "EG": -24 }, "Count23": { - "MG": -39, - "EG": -34 + "MG": -26, + "EG": -35 }, "Count24": { - "MG": -45, + "MG": -34, "EG": -44 }, "Count25": { - "MG": -22, - "EG": -65 + "MG": -9, + "EG": -64 }, "Count26": { - "MG": -62, - "EG": -72 + "MG": -58, + "EG": -71 }, "Count27": { - "MG": -36, + "MG": -22, "EG": -90 } }, @@ -254,94 +254,94 @@ "EG": 0 }, "Count1": { - "MG": 25, - "EG": -4 + "MG": 24, + "EG": -3 }, "Count2": { - "MG": 34, - "EG": 5 + "MG": 31, + "EG": 6 }, "Count3": { - "MG": 40, - "EG": 5 + "MG": 36, + "EG": 6 }, "Count4": { - "MG": 44, - "EG": 11 + "MG": 41, + "EG": 12 }, "Count5": { - "MG": 42, + "MG": 39, "EG": 20 }, "Count6": { - "MG": 41, - "EG": 22 + "MG": 39, + "EG": 24 }, "Count7": { - "MG": 43, - "EG": 24 + "MG": 42, + "EG": 25 }, "Count8": { - "MG": 55, - "EG": 17 + "MG": 53, + "EG": 18 } }, "BishopMobilityBonus": { "Count0": { - "MG": -198, - "EG": -154 + "MG": -214, + "EG": -182 }, "Count1": { "MG": 0, "EG": 0 }, "Count2": { - "MG": 12, - "EG": 2 + "MG": 14, + "EG": -2 }, "Count3": { "MG": 21, - "EG": 41 + "EG": 37 }, "Count4": { - "MG": 36, - "EG": 57 + "MG": 35, + "EG": 54 }, "Count5": { "MG": 42, - "EG": 72 + "EG": 68 }, "Count6": { - "MG": 58, - "EG": 92 + "MG": 57, + "EG": 89 }, "Count7": { - "MG": 67, - "EG": 102 + "MG": 66, + "EG": 98 }, "Count8": { - "MG": 76, - "EG": 114 + "MG": 75, + "EG": 111 }, "Count9": { - "MG": 76, - "EG": 121 + "MG": 75, + "EG": 118 }, "Count10": { - "MG": 82, - "EG": 126 + "MG": 81, + "EG": 123 }, "Count11": { "MG": 85, - "EG": 125 + "EG": 122 }, "Count12": { - "MG": 87, - "EG": 126 + "MG": 86, + "EG": 122 }, "Count13": { - "MG": 119, - "EG": 118 + "MG": 117, + "EG": 116 }, "Count14": { "MG": 0, @@ -355,60 +355,60 @@ "EG": 0 }, "Count1": { - "MG": 7, - "EG": 31 + "MG": 9, + "EG": 28 }, "Count2": { - "MG": 12, - "EG": 34 + "MG": 14, + "EG": 29 }, "Count3": { - "MG": 16, - "EG": 42 + "MG": 19, + "EG": 36 }, "Count4": { - "MG": 14, - "EG": 52 + "MG": 17, + "EG": 46 }, "Count5": { - "MG": 21, - "EG": 55 + "MG": 24, + "EG": 50 }, "Count6": { - "MG": 24, - "EG": 62 + "MG": 27, + "EG": 57 }, "Count7": { - "MG": 29, - "EG": 66 + "MG": 32, + "EG": 61 }, "Count8": { - "MG": 30, - "EG": 78 + "MG": 33, + "EG": 73 }, "Count9": { - "MG": 34, - "EG": 85 + "MG": 36, + "EG": 80 }, "Count10": { - "MG": 38, - "EG": 87 + "MG": 41, + "EG": 82 }, "Count11": { - "MG": 41, - "EG": 89 + "MG": 44, + "EG": 83 }, "Count12": { - "MG": 41, - "EG": 93 + "MG": 44, + "EG": 88 }, "Count13": { - "MG": 55, - "EG": 92 + "MG": 59, + "EG": 87 }, "Count14": { - "MG": 50, - "EG": 90 + "MG": 54, + "EG": 85 } } // End of evaluation diff --git a/src/Lynx.Dev/Program.cs b/src/Lynx.Dev/Program.cs index 5df414ad9..03937976f 100644 --- a/src/Lynx.Dev/Program.cs +++ b/src/Lynx.Dev/Program.cs @@ -1151,8 +1151,8 @@ static void TestMoveGen(string fen) static void PieceSquareTables() { - short[] middleGamePawnTableBlack = EvaluationConstants.MiddleGamePawnTable.Select((_, index) => (short)-EvaluationConstants.MiddleGamePawnTable[index ^ 56]).ToArray(); - short[] endGamePawnTableBlack = EvaluationConstants.EndGamePawnTable.Select((_, index) => (short)-EvaluationConstants.EndGamePawnTable[index ^ 56]).ToArray(); + short[] middleGamePawnTableBlack = EvaluationConstants.MiddleGamePawnTable.Select((_, index) => (short)-EvaluationConstants.MiddleGamePawnTable[0][index ^ 56]).ToArray(); + short[] endGamePawnTableBlack = EvaluationConstants.EndGamePawnTable.Select((_, index) => (short)-EvaluationConstants.EndGamePawnTable[0][index ^ 56]).ToArray(); PrintBitBoard(EvaluationConstants.MiddleGamePawnTable); PrintBitBoard(middleGamePawnTableBlack); diff --git a/src/Lynx/Configuration.cs b/src/Lynx/Configuration.cs index 538da9080..e07177821 100644 --- a/src/Lynx/Configuration.cs +++ b/src/Lynx/Configuration.cs @@ -189,7 +189,7 @@ public sealed class EngineSettings #region Evaluation - public TaperedEvaluationTerm IsolatedPawnPenalty { get; set; } = new(-19, -14); + public TaperedEvaluationTerm IsolatedPawnPenalty { get; set; } = new(-20, -14); public TaperedEvaluationTerm OpenFileRookBonus { get; set; } = new(45, 6); @@ -197,102 +197,102 @@ public sealed class EngineSettings public TaperedEvaluationTerm QueenMobilityBonus { get; set; } = new(3, 8); - public TaperedEvaluationTerm SemiOpenFileKingPenalty { get; set; } = new(-30, 18); + public TaperedEvaluationTerm SemiOpenFileKingPenalty { get; set; } = new(-21, 17); - public TaperedEvaluationTerm OpenFileKingPenalty { get; set; } = new(-96, 15); + public TaperedEvaluationTerm OpenFileKingPenalty { get; set; } = new(-86, 15); - public TaperedEvaluationTerm KingShieldBonus { get; set; } = new(23, -11); + public TaperedEvaluationTerm KingShieldBonus { get; set; } = new(11, -9); - public TaperedEvaluationTerm BishopPairBonus { get; set; } = new(30, 81); + public TaperedEvaluationTerm BishopPairBonus { get; set; } = new(31, 81); - public TaperedEvaluationTerm PieceProtectedByPawnBonus { get; set; } = new(7, 11); + public TaperedEvaluationTerm PieceProtectedByPawnBonus { get; set; } = new(6, 11); public TaperedEvaluationTerm PieceAttackedByPawnPenalty { get; set; } = new(-45, -18); public TaperedEvaluationTermByRank PassedPawnBonus { get; set; } = new( new(0, 0), - new(2, 11), - new(-11, 20), - new(-12, 47), - new(18, 81), - new(63, 161), - new(102, 225), + new(7, 11), + new(-6, 19), + new(-8, 46), + new(21, 81), + new(64, 161), + new(100, 227), new(0, 0)); public TaperedEvaluationTermByCount27 VirtualKingMobilityBonus { get; set; } = new( new(0, 0), new(0, 0), new(0, 0), - new(37, -5), - new(51, -8), - new(24, 24), - new(22, 13), - new(19, 3), - new(15, 6), + new(36, 0), + new(47, -6), + new(20, 23), + new(18, 14), + new(18, 3), + new(14, 6), new(11, 5), new(9, 9), - new(2, 13), - new(0, 9), - new(-5, 12), - new(-15, 15), - new(-26, 18), - new(-35, 15), - new(-46, 12), - new(-52, 10), - new(-60, 3), - new(-51, -5), - new(-46, -13), - new(-44, -24), - new(-39, -34), - new(-45, -44), - new(-22, -65), - new(-62, -72), - new(-36, -90)); + new(4, 13), + new(3, 9), + new(-3, 13), + new(-12, 15), + new(-22, 17), + new(-30, 14), + new(-42, 12), + new(-47, 9), + new(-53, 2), + new(-42, -6), + new(-35, -15), + new(-35, -24), + new(-26, -35), + new(-34, -44), + new(-9, -64), + new(-58, -71), + new(-22, -90)); public TaperedEvaluationTermByCount8 KnightMobilityBonus { get; set; } = new( new(0, 0), - new(25, -4), - new(34, 5), - new(40, 5), - new(44, 11), - new(42, 20), - new(41, 22), - new(43, 24), - new(55, 17)); + new(24, -3), + new(31, 6), + new(36, 6), + new(41, 12), + new(39, 20), + new(39, 24), + new(42, 25), + new(53, 18)); public TaperedEvaluationTermByCount14 BishopMobilityBonus { get; set; } = new( - new(-198, -154), + new(-214, -182), new(0, 0), - new(12, 2), - new(21, 41), - new(36, 57), - new(42, 72), - new(58, 92), - new(67, 102), - new(76, 114), - new(76, 121), - new(82, 126), - new(85, 125), - new(87, 126), - new(119, 118), + new(14, -2), + new(21, 37), + new(35, 54), + new(42, 68), + new(57, 89), + new(66, 98), + new(75, 111), + new(75, 118), + new(81, 123), + new(85, 122), + new(86, 122), + new(117, 116), new(0, 0)); public TaperedEvaluationTermByCount14 RookMobilityBonus { get; set; } = new( new(0, 0), - new(7, 31), - new(12, 34), - new(16, 42), - new(14, 52), - new(21, 55), - new(24, 62), - new(29, 66), - new(30, 78), - new(34, 85), - new(38, 87), - new(41, 89), - new(41, 93), - new(55, 92), - new(50, 90)); + new(9, 28), + new(14, 29), + new(19, 36), + new(17, 46), + new(24, 50), + new(27, 57), + new(32, 61), + new(33, 73), + new(36, 80), + new(41, 82), + new(44, 83), + new(44, 88), + new(59, 87), + new(54, 85)); #endregion } diff --git a/src/Lynx/EvaluationConstants.cs b/src/Lynx/EvaluationConstants.cs index f84c4a08a..595109f59 100644 --- a/src/Lynx/EvaluationConstants.cs +++ b/src/Lynx/EvaluationConstants.cs @@ -18,174 +18,332 @@ public static class EvaluationConstants #pragma warning disable IDE0055 // Discard formatting in this region + public const int PSQTBucketCount = 2; + public static readonly int[] GamePhaseByPiece = [ 0, 1, 1, 2, 4, 0, 0, 1, 1, 2, 4, 0 ]; -internal static readonly short[] MiddleGamePieceValues = +internal static readonly short[][] MiddleGamePieceValues = [ - +97, +356, +373, +507, +1123, 0, - -97, -356, -373, -507, -1123, 0 + [ + +97, +332, +350, +451, +999, 0, + -97, -332, -350, -451, -999, 0 + ], + [ + +103, +367, +382, +517, +1150, 0, + -103, -367, -382, -517, -1150, 0 + ], ]; -internal static readonly short[] EndGamePieceValues = +internal static readonly short[][] EndGamePieceValues = [ - +123, +427, +363, +747, +1425, 0, - -123, -427, -363, -747, -1425, 0 + [ + +128, +405, +348, +708, +1326, 0, + -128, -405, -348, -708, -1326, 0 + ], + [ + +121, +436, +375, +773, +1463, 0, + -121, -436, -375, -773, -1463, 0 + ], ]; -internal static readonly short[] MiddleGamePawnTable = +internal static readonly short[][] MiddleGamePawnTable = [ - 0, 0, 0, 0, 0, 0, 0, 0, - -21, -22, -14, -12, -6, 20, 23, -12, - -24, -26, -6, 9, 15, 23, 20, 8, - -20, -14, 5, 18, 27, 30, 4, -1, - -20, -10, 3, 20, 29, 29, 3, -2, - -22, -21, -5, 2, 10, 20, 13, 2, - -21, -19, -19, -15, -9, 14, 12, -19, - 0, 0, 0, 0, 0, 0, 0, 0, + [ + 0, 0, 0, 0, 0, 0, 0, 0, + 17, 50, 39, 14, -21, -19, -47, -66, + 18, 21, 29, 12, 9, -1, -38, -54, + 8, 16, 26, 28, 22, 7, -27, -49, + 21, 26, 28, 34, 20, 2, -26, -52, + 37, 37, 29, 6, -1, -10, -45, -74, + 27, 66, 28, 10, -12, -19, -55, -71, + 0, 0, 0, 0, 0, 0, 0, 0, + ], + [ + 0, 0, 0, 0, 0, 0, 0, 0, + -31, -32, -23, -14, -5, 32, 46, 7, + -34, -35, -14, 3, 12, 25, 33, 19, + -30, -21, -2, 12, 23, 30, 12, 7, + -30, -18, -4, 13, 25, 29, 12, 8, + -34, -30, -13, -4, 7, 23, 27, 15, + -31, -31, -27, -17, -8, 26, 38, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + ], ]; -internal static readonly short[] EndGamePawnTable = +internal static readonly short[][] EndGamePawnTable = [ - 0, 0, 0, 0, 0, 0, 0, 0, - 16, 11, 5, -7, 8, 3, -5, -3, - 10, 6, -3, -15, -10, -10, -10, -9, - 27, 17, -1, -20, -16, -15, 4, 1, - 24, 16, -3, -16, -15, -12, 2, -1, - 12, 3, -6, -13, -7, -8, -9, -10, - 18, 11, 9, -5, 17, 7, -1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, + [ + 0, 0, 0, 0, 0, 0, 0, 0, + 3, -11, -11, -15, 1, 1, 10, 28, + 3, 1, -9, -21, -15, -13, -1, 11, + 25, 16, -4, -22, -12, -10, 10, 16, + 23, 12, -6, -18, -12, -7, 7, 15, + 5, -10, -12, -15, -10, -10, 1, 10, + 4, -14, -3, 3, 5, 3, 16, 30, + 0, 0, 0, 0, 0, 0, 0, 0, + ], + [ + 0, 0, 0, 0, 0, 0, 0, 0, + 19, 14, 5, -8, 12, 4, -9, -12, + 12, 7, -1, -10, -5, -6, -12, -13, + 27, 16, -1, -18, -15, -14, 3, -2, + 24, 16, -2, -15, -14, -12, 2, -5, + 12, 6, -4, -10, -3, -5, -11, -14, + 22, 15, 9, -10, 19, 7, -7, -10, + 0, 0, 0, 0, 0, 0, 0, 0, + ], ]; -internal static readonly short[] MiddleGameKnightTable = +internal static readonly short[][] MiddleGameKnightTable = [ - -142, -19, -51, -28, -10, -13, -7, -79, - -42, -27, -5, 16, 18, 28, -8, 0, - -35, -4, 12, 50, 52, 33, 26, -7, - -13, 21, 37, 51, 51, 52, 43, 14, - -10, 21, 39, 39, 50, 51, 43, 13, - -33, -3, 12, 43, 49, 26, 20, -8, - -45, -20, -2, 15, 17, 23, -6, 0, - -157, -22, -49, -20, -8, -4, -15, -67, + [ + -106, -47, -40, -12, -43, -35, -28, -93, + -46, -56, 10, 20, 14, 44, -5, -28, + -37, 15, 44, 67, 59, 22, 13, -10, + 12, 37, 54, 81, 75, 56, 55, 9, + 1, 33, 59, 52, 66, 49, 46, 26, + -20, 1, 38, 62, 58, 15, 9, -26, + -24, -14, 19, 11, 12, 12, -19, -32, + -156, -60, -51, -32, -28, -44, -32, -127, + ], + [ + -148, -18, -52, -30, -9, -10, -2, -76, + -42, -26, -7, 14, 18, 28, -5, 1, + -34, -5, 9, 47, 51, 33, 27, -6, + -15, 19, 35, 47, 48, 51, 41, 14, + -11, 19, 36, 36, 47, 50, 41, 12, + -34, -4, 8, 40, 47, 26, 20, -6, + -47, -20, -4, 14, 17, 25, -1, 2, + -143, -21, -46, -19, -6, -1, -10, -64, + ], ]; -internal static readonly short[] EndGameKnightTable = +internal static readonly short[][] EndGameKnightTable = [ - -56, -38, -5, -3, -3, -25, -31, -80, - -9, 6, 10, 4, 4, -3, -7, -16, - -8, 7, 26, 27, 22, 7, -1, -9, - 10, 11, 37, 38, 43, 35, 15, -3, - 7, 16, 36, 42, 43, 32, 19, 4, - -10, 11, 16, 31, 22, 8, -3, -5, - -15, 8, 1, 7, -0, -8, -8, -20, - -60, -35, 0, -6, -5, -25, -30, -79, + [ + -66, 5, 2, -16, 5, -30, -10, -64, + -12, 20, 5, 1, -1, -6, -3, -23, + 7, -0, 7, 19, 21, 12, -3, -12, + 1, 7, 30, 24, 31, 36, 3, -10, + 8, 15, 29, 32, 37, 25, 3, -15, + -2, 18, 0, 19, 19, 11, -6, 3, + -15, 7, -4, 12, -2, -9, 2, -10, + -54, -13, 9, -1, -4, -8, -11, -76, + ], + [ + -51, -43, -8, -0, -3, -23, -39, -82, + -8, 4, 10, 5, 5, -3, -8, -13, + -13, 8, 26, 27, 21, 6, 1, -8, + 11, 12, 38, 40, 44, 33, 18, -1, + 6, 15, 37, 43, 43, 34, 24, 8, + -14, 8, 16, 33, 22, 7, -2, -7, + -15, 8, 2, 7, 1, -6, -10, -20, + -66, -34, -3, -6, -5, -26, -36, -71, + ], ]; -internal static readonly short[] MiddleGameBishopTable = +internal static readonly short[][] MiddleGameBishopTable = [ - -13, 13, -9, -20, -15, -10, -21, 14, - 4, 1, 4, -17, 1, 3, 36, -6, - -9, -0, -9, 4, -12, 6, -2, 26, - -9, -8, -2, 23, 21, -13, 2, -3, - -17, -3, -11, 20, 9, -10, -5, 3, - 2, -2, 2, -4, -0, -1, 0, 21, - 7, 12, 7, -6, -4, 5, 28, 6, - 11, 16, 3, -35, -17, -16, 2, -3, + [ + -20, -23, -9, -15, -19, -7, -17, -12, + -14, 45, 20, -1, 1, 7, -2, -11, + -3, 7, 22, 27, 4, -3, -1, 6, + -0, 4, 18, 39, 37, -15, -2, -7, + -18, 17, 6, 34, 16, -6, 2, -2, + -9, 18, 25, 12, 3, -5, -15, 3, + -20, 59, 36, 15, -10, -5, -19, -24, + -7, -9, 1, -37, -18, -8, -14, -74, + ], + [ + -13, 14, -9, -19, -12, -8, -16, 14, + 5, -1, 3, -19, 1, 4, 38, -6, + -10, -0, -12, 2, -14, 7, -2, 27, + -11, -10, -5, 22, 19, -13, 2, -1, + -18, -5, -14, 18, 9, -10, -7, 5, + 1, -5, -0, -7, -0, 0, 2, 21, + 8, 9, 5, -8, -4, 9, 31, 9, + 10, 17, 3, -34, -16, -17, 8, 4, + ], ]; -internal static readonly short[] EndGameBishopTable = +internal static readonly short[][] EndGameBishopTable = [ - 1, 17, -3, 5, 2, 3, 1, -19, - 3, -7, -6, -0, -2, -14, -7, -10, - 13, 8, 4, -2, 6, 1, 0, 10, - 13, 0, 3, 0, -1, 2, -1, 6, - 7, 3, 1, 4, -3, 3, -1, 7, - 10, -2, -2, -4, 1, -4, -2, 7, - -6, -9, -16, -2, -4, -8, -7, -5, - 3, -8, -2, 9, 9, 4, -1, -6, + [ + 14, 12, 4, -0, 7, 5, 3, 7, + 19, -16, -9, -9, -6, -13, -1, -9, + 19, 6, -12, -14, -10, 2, -5, 8, + 17, -6, -9, -8, -14, 4, 1, 14, + 13, -2, -11, -9, -7, -6, -4, 10, + 31, -16, -7, -17, -5, -1, -3, -8, + 4, -19, -21, -16, -5, -8, 4, 14, + 13, 13, 11, 16, 5, -2, 6, 28, + ], + [ + -2, 19, -4, 6, -1, 3, -1, -26, + -2, -7, -6, 1, -1, -14, -5, -10, + 12, 8, 7, -1, 10, 1, 3, 13, + 12, 1, 5, 2, 2, 2, -1, 2, + 6, 2, 4, 7, -2, 6, 1, 6, + 7, 1, -1, -2, 2, -5, 0, 14, + -8, -9, -16, 1, -3, -7, -6, -8, + 2, -14, -3, 5, 11, 6, -6, -16, + ], ]; -internal static readonly short[] MiddleGameRookTable = +internal static readonly short[][] MiddleGameRookTable = [ - -4, -10, -6, 0, 9, 8, 11, 2, - -29, -18, -11, -8, 4, 12, 29, -2, - -33, -22, -23, -12, 3, 9, 48, 24, - -29, -26, -23, -11, -6, 6, 37, 16, - -24, -21, -17, -7, -8, 7, 28, 12, - -26, -18, -19, -2, 0, 19, 48, 22, - -26, -27, -7, -2, 5, 10, 35, 5, - -2, -4, -1, 10, 17, 12, 19, 14, + [ + -57, -31, -20, 9, 4, 9, 22, 1, + -7, 6, 15, -6, 0, 10, 3, -18, + -3, -8, -33, 6, -12, -21, 18, -7, + -16, 17, -1, -0, -2, 6, 15, 3, + -0, 12, 9, 6, -10, -8, -9, -0, + 5, 8, 40, 3, -9, 18, 18, -5, + 11, 16, 2, 5, -2, -1, 8, -15, + -36, -28, -3, 20, 11, 7, 23, 2, + ], + [ + -5, -12, -7, -0, 10, 8, 2, 2, + -33, -21, -14, -8, 4, 15, 38, 4, + -37, -25, -24, -14, 4, 12, 51, 31, + -33, -31, -25, -12, -7, 7, 37, 15, + -27, -25, -20, -9, -8, 9, 35, 15, + -31, -22, -25, -3, 1, 21, 52, 30, + -30, -30, -8, -3, 6, 13, 44, 19, + -4, -5, -3, 9, 18, 14, 11, 21, + ], ]; -internal static readonly short[] EndGameRookTable = +internal static readonly short[][] EndGameRookTable = [ - 7, 5, 9, 1, -7, -1, -3, -6, - 17, 19, 19, 9, -1, -5, -9, 0, - 14, 10, 12, 4, -8, -12, -23, -18, - 15, 11, 12, 4, -3, -5, -17, -16, - 14, 10, 11, 2, -2, -10, -15, -12, - 14, 13, 4, -3, -10, -15, -24, -11, - 20, 22, 15, 4, -3, -5, -10, -0, - 2, -1, 4, -5, -14, -9, -9, -14, + [ + 26, 22, 26, -1, -6, -17, -21, 3, + 5, 18, 15, 9, -5, -9, -3, 0, + 6, 12, 18, -8, -2, -4, -18, -10, + 9, 2, 7, 4, -8, -11, -17, -13, + 13, 7, 2, -2, 4, -9, -10, -6, + 4, 8, -17, -6, -9, -7, -19, -7, + 9, 13, 13, 0, 1, -5, -8, 6, + 14, 23, 12, -5, -4, -15, -23, -4, + ], + [ + 8, 3, 7, -0, -7, 2, 8, -15, + 20, 19, 19, 8, -1, -4, -10, 1, + 15, 9, 12, 6, -9, -12, -23, -19, + 17, 12, 13, 2, -2, -3, -15, -14, + 14, 10, 13, 2, -4, -9, -14, -14, + 15, 13, 6, -4, -11, -18, -24, -11, + 21, 22, 15, 5, -4, -6, -10, -5, + 4, -2, 4, -7, -17, -7, 0, -24, + ], ]; -internal static readonly short[] MiddleGameQueenTable = +internal static readonly short[][] MiddleGameQueenTable = [ - -13, -12, -13, 5, -2, -30, 6, 2, - -4, -10, 7, -0, 3, 11, 28, 50, - -12, -8, -10, -10, -14, 5, 30, 53, - -12, -20, -17, -8, -8, -3, 13, 26, - -12, -16, -16, -16, -6, -3, 12, 23, - -9, -6, -16, -11, -9, 1, 17, 33, - -16, -19, 3, 12, 8, 7, 12, 38, - -11, -12, -2, 7, 1, -35, -15, 25, + [ + -34, -60, -48, -14, -4, -1, 5, 23, + -11, -20, 19, 15, 6, 11, 29, 46, + -42, -0, -8, 5, -5, 1, 31, 70, + -4, -32, -7, 13, 7, 4, 20, 39, + -6, -7, -9, 13, 9, 10, 16, 25, + -26, -10, -10, -2, 10, -2, 29, 46, + -49, -48, 18, 25, 19, -3, 22, 49, + -54, -53, -30, -21, 1, -12, -14, 12, + ], + [ + -14, -11, -11, 7, 1, -31, 0, -8, + -5, -9, 8, -1, 5, 14, 28, 45, + -9, -7, -8, -10, -13, 8, 31, 47, + -12, -17, -16, -8, -7, -2, 12, 23, + -13, -15, -15, -17, -6, -2, 12, 21, + -8, -5, -14, -10, -9, 4, 17, 29, + -18, -17, 3, 11, 9, 13, 12, 28, + -15, -11, -1, 8, 4, -35, -18, 25, + ], ]; -internal static readonly short[] EndGameQueenTable = +internal static readonly short[][] EndGameQueenTable = [ - -22, -16, -3, -11, -15, -15, -32, 8, - -14, -9, -25, -2, -4, -21, -49, -5, - -13, -4, 7, 2, 22, 19, -8, 5, - -10, 7, 6, 11, 23, 33, 40, 28, - -2, 3, 12, 22, 19, 29, 20, 38, - -13, -10, 14, 11, 13, 18, 16, 18, - -9, -3, -21, -21, -13, -17, -34, 3, - -13, -13, -10, -6, -9, 11, 15, -2, + [ + -40, -3, 34, -2, -13, -48, -72, -56, + -10, -7, -27, 2, -4, -23, -36, -16, + 36, 6, 33, 3, 27, 10, -41, -33, + -2, 35, 17, 15, 20, 14, 4, -8, + 1, 20, 32, 21, 17, -5, -9, 14, + 15, 18, 32, 16, 16, 35, -8, 15, + 14, 18, -18, -3, 4, 25, -37, -40, + -37, -16, 18, 24, 6, -1, 15, -15, + ], + [ + -15, -16, -7, -14, -18, -8, -10, 37, + -15, -10, -27, -5, -6, -20, -46, 7, + -22, -9, -0, -1, 18, 17, -2, 16, + -16, -2, 0, 5, 20, 33, 46, 35, + -7, -6, 4, 16, 16, 31, 23, 43, + -20, -16, 7, 6, 10, 13, 19, 21, + -9, -5, -23, -25, -20, -26, -30, 26, + -2, -12, -13, -9, -16, 11, 19, 7, + ], ]; -internal static readonly short[] MiddleGameKingTable = +internal static readonly short[][] MiddleGameKingTable = [ - 6, 39, 36, -64, 19, -55, 35, 24, - -21, -15, -20, -54, -67, -44, -5, 5, - -83, -65, -99, -97, -106, -115, -79, -99, - -99, -80, -104, -151, -145, -122, -121, -155, - -66, -54, -92, -129, -143, -108, -125, -151, - -81, -44, -91, -91, -82, -92, -70, -90, - 59, -9, -21, -42, -46, -29, 11, 14, - 16, 60, 46, -46, 34, -42, 51, 38, + [ + 330, 351, 334, 276, 0, 0, 0, 0, + 309, 321, 313, 292, 0, 0, 0, 0, + 252, 273, 238, 236, 0, 0, 0, 0, + 233, 251, 231, 180, 0, 0, 0, 0, + 255, 277, 239, 199, 0, 0, 0, 0, + 240, 274, 230, 227, 0, 0, 0, 0, + 347, 313, 286, 280, 0, 0, 0, 0, + 317, 345, 322, 266, 0, 0, 0, 0, + ], + [ + 0, 0, 0, 0, -108, -171, -78, -90, + 0, 0, 0, 0, -176, -153, -107, -101, + 0, 0, 0, 0, -215, -215, -174, -199, + 0, 0, 0, 0, -260, -227, -220, -256, + 0, 0, 0, 0, -256, -215, -221, -251, + 0, 0, 0, 0, -193, -194, -167, -190, + 0, 0, 0, 0, -163, -142, -91, -93, + 0, 0, 0, 0, -101, -163, -64, -76, + ], ]; -internal static readonly short[] EndGameKingTable = +internal static readonly short[][] EndGameKingTable = [ - -77, -49, -28, -1, -41, -9, -43, -91, - -23, 15, 24, 37, 43, 30, 8, -29, - -2, 40, 69, 81, 84, 73, 40, 10, - 0, 52, 90, 122, 120, 92, 63, 23, - -10, 43, 88, 119, 123, 91, 65, 22, - -1, 37, 70, 81, 78, 68, 39, 5, - -47, 11, 26, 35, 37, 26, 3, -33, - -88, -57, -34, -9, -38, -14, -48, -96, + [ + -98, -68, -47, -30, 0, 0, 0, 0, + -46, -11, -1, 8, 0, 0, 0, 0, + -26, 15, 44, 55, 0, 0, 0, 0, + -23, 29, 65, 97, 0, 0, 0, 0, + -31, 20, 63, 94, 0, 0, 0, 0, + -22, 15, 46, 58, 0, 0, 0, 0, + -62, -13, 6, 10, 0, 0, 0, 0, + -102, -74, -49, -30, 0, 0, 0, 0, + ], + [ + 0, 0, 0, 0, -26, 1, -32, -79, + 0, 0, 0, 0, 52, 39, 15, -22, + 0, 0, 0, 0, 92, 80, 44, 15, + 0, 0, 0, 0, 128, 98, 67, 27, + 0, 0, 0, 0, 130, 97, 69, 26, + 0, 0, 0, 0, 88, 75, 43, 11, + 0, 0, 0, 0, 48, 36, 10, -25, + 0, 0, 0, 0, -21, -2, -35, -83, + ], ]; #pragma warning restore IDE0055 /// - /// 12x64 + /// 2x12x64 /// - public static readonly int[][] PackedPSQT = new int[12][]; + public static readonly int[][][] PackedPSQT = new int[2][][]; /// /// x @@ -199,7 +357,7 @@ public static class EvaluationConstants static EvaluationConstants() { - short[][] mgPositionalTables = + short[][][] mgPositionalTables = [ MiddleGamePawnTable, MiddleGameKnightTable, @@ -209,7 +367,7 @@ static EvaluationConstants() MiddleGameKingTable ]; - short[][] egPositionalTables = + short[][][] egPositionalTables = [ EndGamePawnTable, EndGameKnightTable, @@ -219,20 +377,24 @@ static EvaluationConstants() EndGameKingTable ]; - for (int piece = (int)Piece.P; piece <= (int)Piece.K; ++piece) + for (int bucket = 0; bucket < PSQTBucketCount; ++bucket) { - PackedPSQT[piece] = new int[64]; - PackedPSQT[piece + 6] = new int[64]; - - for (int sq = 0; sq < 64; ++sq) + PackedPSQT[bucket] = new int[12][]; + for (int piece = (int)Piece.P; piece <= (int)Piece.K; ++piece) { - PackedPSQT[piece][sq] = Utils.Pack( - (short)(MiddleGamePieceValues[piece] + mgPositionalTables[piece][sq]), - (short)(EndGamePieceValues[piece] + egPositionalTables[piece][sq])); - - PackedPSQT[piece + 6][sq] = Utils.Pack( - (short)(MiddleGamePieceValues[piece + 6] - mgPositionalTables[piece][sq ^ 56]), - (short)(EndGamePieceValues[piece + 6] - egPositionalTables[piece][sq ^ 56])); + PackedPSQT[bucket][piece] = new int[64]; + PackedPSQT[bucket][piece + 6] = new int[64]; + + for (int sq = 0; sq < 64; ++sq) + { + PackedPSQT[bucket][piece][sq] = Utils.Pack( + (short)(MiddleGamePieceValues[bucket][piece] + mgPositionalTables[piece][bucket][sq]), + (short)(EndGamePieceValues[bucket][piece] + egPositionalTables[piece][bucket][sq])); + + PackedPSQT[bucket][piece + 6][sq] = Utils.Pack( + (short)(MiddleGamePieceValues[bucket][piece + 6] - mgPositionalTables[piece][bucket][sq ^ 56]), + (short)(EndGamePieceValues[bucket][piece + 6] - egPositionalTables[piece][bucket][sq ^ 56])); + } } } diff --git a/src/Lynx/Model/Position.cs b/src/Lynx/Model/Position.cs index 63a3b132b..98f44741b 100644 --- a/src/Lynx/Model/Position.cs +++ b/src/Lynx/Model/Position.cs @@ -683,6 +683,12 @@ public bool WasProduceByAValidMove() BitBoard whitePawnAttacks = PieceBitBoards[(int)Piece.P].ShiftUpRight() | PieceBitBoards[(int)Piece.P].ShiftUpLeft(); BitBoard blackPawnAttacks = PieceBitBoards[(int)Piece.p].ShiftDownRight() | PieceBitBoards[(int)Piece.p].ShiftDownLeft(); + var whiteKing = PieceBitBoards[(int)Piece.K].GetLS1BIndex(); + var blackKing = PieceBitBoards[(int)Piece.k].GetLS1BIndex(); + + var whiteBucket = Constants.File[whiteKing] / 4; + var blackBucket = Constants.File[blackKing] / 4; + for (int pieceIndex = (int)Piece.P; pieceIndex < (int)Piece.K; ++pieceIndex) { // Bitboard copy that we 'empty' @@ -693,7 +699,7 @@ public bool WasProduceByAValidMove() var pieceSquareIndex = bitboard.GetLS1BIndex(); bitboard.ResetLS1B(); - packedScore += EvaluationConstants.PackedPSQT[pieceIndex][pieceSquareIndex]; + packedScore += EvaluationConstants.PackedPSQT[whiteBucket][pieceIndex][pieceSquareIndex]; gamePhase += EvaluationConstants.GamePhaseByPiece[pieceIndex]; packedScore += AdditionalPieceEvaluation(pieceSquareIndex, pieceIndex); @@ -710,7 +716,7 @@ public bool WasProduceByAValidMove() var pieceSquareIndex = bitboard.GetLS1BIndex(); bitboard.ResetLS1B(); - packedScore += EvaluationConstants.PackedPSQT[pieceIndex][pieceSquareIndex]; + packedScore += EvaluationConstants.PackedPSQT[blackBucket][pieceIndex][pieceSquareIndex]; gamePhase += EvaluationConstants.GamePhaseByPiece[pieceIndex]; packedScore -= AdditionalPieceEvaluation(pieceSquareIndex, pieceIndex); @@ -737,11 +743,8 @@ public bool WasProduceByAValidMove() * ((blackPawnAttacks & OccupancyBitBoards[(int)Side.White]).CountBits() - (whitePawnAttacks & OccupancyBitBoards[(int)Side.Black]).CountBits()); - var whiteKing = PieceBitBoards[(int)Piece.K].GetLS1BIndex(); - var blackKing = PieceBitBoards[(int)Piece.k].GetLS1BIndex(); - - packedScore += EvaluationConstants.PackedPSQT[(int)Piece.K][whiteKing] - + EvaluationConstants.PackedPSQT[(int)Piece.k][blackKing] + packedScore += EvaluationConstants.PackedPSQT[whiteBucket][(int)Piece.K][whiteKing] + + EvaluationConstants.PackedPSQT[blackBucket][(int)Piece.k][blackKing] + KingAdditionalEvaluation(whiteKing, Side.White) - KingAdditionalEvaluation(blackKing, Side.Black); diff --git a/tests/Lynx.Test/EvaluationConstantsTest.cs b/tests/Lynx.Test/EvaluationConstantsTest.cs index f2a7a25d5..ad7969e95 100644 --- a/tests/Lynx.Test/EvaluationConstantsTest.cs +++ b/tests/Lynx.Test/EvaluationConstantsTest.cs @@ -9,12 +9,12 @@ public class EvaluationConstantsTest /// Shy from 14k /// private readonly int _sensibleEvaluation = - (2 * (Math.Max(MiddleGameBishopTable.Max(), EndGameBishopTable.Max()) + Configuration.EngineSettings.BishopMobilityBonus[13].MG)) + - (2 * (Math.Max(MiddleGameKnightTable.Max(), EndGameKnightTable.Max()))) + - (2 * (Math.Max(MiddleGameRookTable.Max(), EndGameRookTable.Max()) + Configuration.EngineSettings.OpenFileRookBonus.MG + Configuration.EngineSettings.SemiOpenFileRookBonus.MG)) + - (9 * (Math.Max(MiddleGameQueenTable.Max(), EndGameQueenTable.Max()) + (Configuration.EngineSettings.QueenMobilityBonus.MG * 64))) + - (1 * (Math.Max(MiddleGameKingTable.Max(), EndGameKingTable.Max()) + (Configuration.EngineSettings.KingShieldBonus.MG * 8))) + - MiddleGameQueenTable.Max(); // just in case + (2 * (Math.Max(MiddleGameBishopTable[0].Max(), EndGameBishopTable[0].Max()) + Configuration.EngineSettings.BishopMobilityBonus[13].MG)) + + (2 * (Math.Max(MiddleGameKnightTable[0].Max(), EndGameKnightTable[0].Max()))) + + (2 * (Math.Max(MiddleGameRookTable[0].Max(), EndGameRookTable[0].Max()) + Configuration.EngineSettings.OpenFileRookBonus.MG + Configuration.EngineSettings.SemiOpenFileRookBonus.MG)) + + (9 * (Math.Max(MiddleGameQueenTable[0].Max(), EndGameQueenTable[0].Max()) + (Configuration.EngineSettings.QueenMobilityBonus.MG * 64))) + + (1 * (Math.Max(MiddleGameKingTable[0].Max(), EndGameKingTable[0].Max()) + (Configuration.EngineSettings.KingShieldBonus.MG * 8))) + + MiddleGameQueenTable[0].Max(); // just in case [TestCase(PositiveCheckmateDetectionLimit)] [TestCase(-NegativeCheckmateDetectionLimit)] @@ -208,25 +208,25 @@ public void SingleMoveEvaluation() [Test] public void PackedEvaluation() { - short[] middleGamePawnTableBlack = MiddleGamePawnTable.Select((_, index) => (short)-MiddleGamePawnTable[index ^ 56]).ToArray(); - short[] endGamePawnTableBlack = EndGamePawnTable.Select((_, index) => (short)-EndGamePawnTable[index ^ 56]).ToArray(); + short[][] middleGamePawnTableBlack = MiddleGamePawnTable.Select(bucketedArray => bucketedArray.Select((_, index) => (short)-bucketedArray[index ^ 56]).ToArray()).ToArray(); + short[][] endGamePawnTableBlack = EndGamePawnTable.Select(bucketedArray => bucketedArray.Select((_, index) => (short)-bucketedArray[index ^ 56]).ToArray()).ToArray(); - short[] middleGameKnightTableBlack = MiddleGameKnightTable.Select((_, index) => (short)-MiddleGameKnightTable[index ^ 56]).ToArray(); - short[] endGameKnightTableBlack = EndGameKnightTable.Select((_, index) => (short)-EndGameKnightTable[index ^ 56]).ToArray(); + short[][] middleGameKnightTableBlack = MiddleGameKnightTable.Select(bucketedArray => bucketedArray.Select((_, index) => (short)-bucketedArray[index ^ 56]).ToArray()).ToArray(); + short[][] endGameKnightTableBlack = EndGameKnightTable.Select(bucketedArray => bucketedArray.Select((_, index) => (short)-bucketedArray[index ^ 56]).ToArray()).ToArray(); - short[] middleGameBishopTableBlack = MiddleGameBishopTable.Select((_, index) => (short)-MiddleGameBishopTable[index ^ 56]).ToArray(); - short[] endGameBishopTableBlack = EndGameBishopTable.Select((_, index) => (short)-EndGameBishopTable[index ^ 56]).ToArray(); + short[][] middleGameBishopTableBlack = MiddleGameBishopTable.Select(bucketedArray => bucketedArray.Select((_, index) => (short)-bucketedArray[index ^ 56]).ToArray()).ToArray(); + short[][] endGameBishopTableBlack = EndGameBishopTable.Select(bucketedArray => bucketedArray.Select((_, index) => (short)-bucketedArray[index ^ 56]).ToArray()).ToArray(); - short[] middleGameRookTableBlack = MiddleGameRookTable.Select((_, index) => (short)-MiddleGameRookTable[index ^ 56]).ToArray(); - short[] endGameRookTableBlack = EndGameRookTable.Select((_, index) => (short)-EndGameRookTable[index ^ 56]).ToArray(); + short[][] middleGameRookTableBlack = MiddleGameRookTable.Select(bucketedArray => bucketedArray.Select((_, index) => (short)-bucketedArray[index ^ 56]).ToArray()).ToArray(); + short[][] endGameRookTableBlack = EndGameRookTable.Select(bucketedArray => bucketedArray.Select((_, index) => (short)-bucketedArray[index ^ 56]).ToArray()).ToArray(); - short[] middleGameQueenTableBlack = MiddleGameQueenTable.Select((_, index) => (short)-MiddleGameQueenTable[index ^ 56]).ToArray(); - short[] EndGameQueenTableBlack = EndGameQueenTable.Select((_, index) => (short)-EndGameQueenTable[index ^ 56]).ToArray(); + short[][] middleGameQueenTableBlack = MiddleGameQueenTable.Select(bucketedArray => bucketedArray.Select((_, index) => (short)-bucketedArray[index ^ 56]).ToArray()).ToArray(); + short[][] EndGameQueenTableBlack = EndGameQueenTable.Select(bucketedArray => bucketedArray.Select((_, index) => (short)-bucketedArray[index ^ 56]).ToArray()).ToArray(); - short[] middleGameKingTableBlack = MiddleGameKingTable.Select((_, index) => (short)-MiddleGameKingTable[index ^ 56]).ToArray(); - short[] endGameKingTableBlack = EndGameKingTable.Select((_, index) => (short)-EndGameKingTable[index ^ 56]).ToArray(); + short[][] middleGameKingTableBlack = MiddleGameKingTable.Select(bucketedArray => bucketedArray.Select((_, index) => (short)-bucketedArray[index ^ 56]).ToArray()).ToArray(); + short[][] endGameKingTableBlack = EndGameKingTable.Select(bucketedArray => bucketedArray.Select((_, index) => (short)-bucketedArray[index ^ 56]).ToArray()).ToArray(); - short[][] mgPositionalTables = + short[][][] mgPositionalTables = [ MiddleGamePawnTable, MiddleGameKnightTable, @@ -243,7 +243,7 @@ public void PackedEvaluation() middleGameKingTableBlack ]; - short[][] egPositionalTables = + short[][][] egPositionalTables = [ EndGamePawnTable, EndGameKnightTable, @@ -260,15 +260,18 @@ public void PackedEvaluation() endGameKingTableBlack ]; - for (int piece = (int)Piece.P; piece <= (int)Piece.k; ++piece) + for (int bucket = 0; bucket < EvaluationConstants.PSQTBucketCount; ++bucket) { - for (int sq = 0; sq < 64; ++sq) + for (int piece = (int)Piece.P; piece <= (int)Piece.k; ++piece) { - var mg = (short)(MiddleGamePieceValues[piece] + mgPositionalTables[piece][sq]); - var eg = (short)(EndGamePieceValues[piece] + egPositionalTables[piece][sq]); + for (int sq = 0; sq < 64; ++sq) + { + var mg = (short)(MiddleGamePieceValues[bucket][piece] + mgPositionalTables[piece][bucket][sq]); + var eg = (short)(EndGamePieceValues[bucket][piece] + egPositionalTables[piece][bucket][sq]); - Assert.AreEqual(Utils.UnpackMG(PackedPSQT[piece][sq]), mg); - Assert.AreEqual(Utils.UnpackEG(PackedPSQT[piece][sq]), eg); + Assert.AreEqual(Utils.UnpackMG(PackedPSQT[bucket][piece][sq]), mg); + Assert.AreEqual(Utils.UnpackEG(PackedPSQT[bucket][piece][sq]), eg); + } } } } diff --git a/tests/Lynx.Test/Model/PositionTest.cs b/tests/Lynx.Test/Model/PositionTest.cs index 0d434b6c1..0fc588a2c 100644 --- a/tests/Lynx.Test/Model/PositionTest.cs +++ b/tests/Lynx.Test/Model/PositionTest.cs @@ -933,8 +933,8 @@ public void StaticEvaluation_QueenMobility(string fen, int mobilityDifference) /// [TestCase("QQQQQQQQ/QQQQQQQQ/QQQQQQQQ/QQQQQQQQ/QQQQQQQQ/QQQQQQQQ/QPPPPPPP/K6k b - - 0 1", EvaluationConstants.MinEval, IgnoreReason = "Packed eval reduces max eval to a short, so over Short.MaxValue it overflows and produces unexpected results")] [TestCase("QQQQQQQQ/QQQQQQQQ/QQQQQQQQ/QQQQQQQQ/QQQQQQQQ/QQQQQQQQ/QPPPPPPP/K5k1 w - - 0 1", EvaluationConstants.MaxEval, IgnoreReason = "Packed eval reduces max eval to a short, so over Short.MaxValue it overflows and produces unexpected results")] - [TestCase("8/8/8/QQQQQQQQ/QQQQQQQQ/QQQQQQQQ/QPPPPPPP/K6k b - - 0 1", EvaluationConstants.MinEval)] - [TestCase("8/8/8/QQQQQQQQ/QQQQQQQQ/QQQQQQQQ/QPPPPPPP/K5k1 w - - 0 1", EvaluationConstants.MaxEval)] + [TestCase("8/8/8/QQQQQQQQ/QQQQQQQQ/QQQQQQQQ/QQPPPPPP/K6k b - - 0 1", EvaluationConstants.MinEval)] + [TestCase("8/8/8/QQQQQQQQ/QQQQQQQQ/QQQQQQQQ/QQPPPPPP/K5k1 w - - 0 1", EvaluationConstants.MaxEval)] public void StaticEvaluation_Clamp(string fen, int expectedStaticEvaluation) { var position = new Position(fen);