| | | 1 | | using Rudim.Common; |
| | | 2 | | using System.Collections.Generic; |
| | | 3 | | using System.Linq; |
| | | 4 | | |
| | | 5 | | namespace Rudim.Board |
| | | 6 | | { |
| | | 7 | | public static class MoveOrdering |
| | | 8 | | { |
| | | 9 | | private static readonly int[,] MostValuableVictimLeastValuableAttacker; |
| | | 10 | | private static Move[,] _killerMoves; |
| | | 11 | | private static int[,] _historyMoves; |
| | | 12 | | |
| | | 13 | | static MoveOrdering() |
| | | 14 | | { |
| | 1 | 15 | | MostValuableVictimLeastValuableAttacker = new[,] |
| | 1 | 16 | | { |
| | 1 | 17 | | // P , N , B , R , Q , K , None |
| | 1 | 18 | | { 15_000, 14_000, 13_000, 12_000, 11_000, 10_000, 0 }, // P |
| | 1 | 19 | | { 25_000, 24_000, 23_000, 22_000, 21_000, 20_000, 0 }, // N |
| | 1 | 20 | | { 35_000, 34_000, 33_000, 32_000, 31_000, 30_000, 0 }, // B |
| | 1 | 21 | | { 45_000, 44_000, 43_000, 42_000, 41_000, 40_000, 0 }, // R |
| | 1 | 22 | | { 55_000, 54_000, 53_000, 52_000, 51_000, 50_000, 0 }, // Q |
| | 1 | 23 | | { 65_000, 64_000, 63_000, 62_000, 61_000, 60_000, 0 }, // K |
| | 1 | 24 | | { 0, 0, 0, 0, 0, 0, 0 } // None |
| | 1 | 25 | | }; |
| | 1 | 26 | | ResetMoveHeuristic(); |
| | 1 | 27 | | } |
| | | 28 | | |
| | | 29 | | public static void PopulateMoveScore(Move move, BoardState boardState, int ply = Constants.MaxPly - 1) |
| | | 30 | | { |
| | 62380717 | 31 | | if (!move.IsCapture()) |
| | | 32 | | { |
| | 55430956 | 33 | | if (move == _killerMoves[0, ply]) |
| | 367089 | 34 | | move.Score = 9000; // TODO : Revisit, assign better values and extract to constants |
| | 55063867 | 35 | | else if (move == _killerMoves[1, ply]) |
| | 277038 | 36 | | move.Score = 8000; |
| | | 37 | | else |
| | 54786829 | 38 | | move.Score = _historyMoves[boardState.GetPieceOn(move.Source), (int)move.Target]; |
| | 54786829 | 39 | | return; |
| | | 40 | | } |
| | | 41 | | int targetPiece; |
| | 6949761 | 42 | | int sourcePiece = boardState.GetPieceOn(move.Source, boardState.SideToMove); |
| | 6949761 | 43 | | if (move.Type == MoveTypes.EnPassant) |
| | 17363 | 44 | | targetPiece = (int)Piece.Pawn; |
| | | 45 | | else |
| | 6932398 | 46 | | targetPiece = boardState.GetPieceOn(move.Target, boardState.SideToMove.Other()); |
| | 6949761 | 47 | | move.Score = MostValuableVictimLeastValuableAttacker[targetPiece, sourcePiece]; |
| | 6949761 | 48 | | } |
| | | 49 | | |
| | | 50 | | public static void AddKillerMove(Move move, int ply) |
| | | 51 | | { |
| | 70751 | 52 | | if (_killerMoves[0, ply] == move) |
| | | 53 | | { |
| | 63624 | 54 | | return; |
| | | 55 | | } |
| | | 56 | | |
| | 7127 | 57 | | _killerMoves[1, ply] = _killerMoves[0, ply]; |
| | 7127 | 58 | | _killerMoves[0, ply] = move; |
| | 7127 | 59 | | } |
| | | 60 | | |
| | | 61 | | public static void AddHistoryMove(int piece, Move move, int depth) |
| | | 62 | | { |
| | 1120 | 63 | | _historyMoves[piece, (int)move.Target] += depth * depth; |
| | 1120 | 64 | | } |
| | | 65 | | |
| | | 66 | | public static void ResetMoveHeuristic() |
| | | 67 | | { |
| | 10 | 68 | | _killerMoves = new Move[Constants.Sides, Constants.MaxPly]; |
| | 10 | 69 | | _historyMoves = new int[Constants.Pieces * 2, Constants.Squares]; |
| | 10 | 70 | | } |
| | | 71 | | |
| | | 72 | | public static bool IsMoveHeuristicEmpty() |
| | | 73 | | { |
| | 899 | 74 | | return _killerMoves.Cast<Move>().All(move => move == null) && _historyMoves.Cast<int>().All(move => move == |
| | | 75 | | } |
| | | 76 | | |
| | | 77 | | public static void PopulateHashMove(Move move) |
| | | 78 | | { |
| | 0 | 79 | | move.Score = 10_500; |
| | 0 | 80 | | } |
| | | 81 | | |
| | | 82 | | public static void SortNextBestMove(List<Move> moves, int startingIndex) |
| | | 83 | | { |
| | 6407023 | 84 | | int bestIndex = startingIndex; |
| | 388623838 | 85 | | for (int i = startingIndex + 1; i < moves.Count; ++i) |
| | | 86 | | { |
| | 187904896 | 87 | | if (moves[i].Score >= moves[bestIndex].Score) |
| | 46173330 | 88 | | bestIndex = i; |
| | | 89 | | } |
| | | 90 | | |
| | 6407023 | 91 | | if(bestIndex != startingIndex) |
| | 6201103 | 92 | | (moves[bestIndex], moves[startingIndex]) = (moves[startingIndex], moves[bestIndex]); |
| | 6407023 | 93 | | } |
| | | 94 | | } |
| | | 95 | | } |