< Summary

Information
Class: Rudim.Common.TranspositionTableEntry
Assembly: Rudim
File(s): /home/runner/work/rudim/rudim/Rudim/Common/TranspositionTable.cs
Line coverage
100%
Covered lines: 5
Uncovered lines: 0
Coverable lines: 5
Total lines: 134
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_Score()100%11100%
get_Hash()100%11100%
get_Depth()100%11100%
get_BestMove()100%11100%
get_Type()100%11100%

File(s)

/home/runner/work/rudim/rudim/Rudim/Common/TranspositionTable.cs

#LineLine coverage
 1using Rudim.Board;
 2using System;
 3using System.Collections.Generic;
 4
 5namespace Rudim.Common
 6{
 7    public static class TranspositionTable
 8    {
 9        // TODO : Calculate this based on a constant and in MiB, not hard numbers
 10        private const int Capacity = 4096 * 16;
 11        private static readonly TranspositionTableEntry[] Entries;
 12
 13        static TranspositionTable()
 14        {
 15            Entries = new TranspositionTableEntry[Capacity];
 16        }
 17
 18        public static void ClearTable()
 19        {
 20            Array.Clear(Entries);
 21        }
 22
 23        public static Move GetHashMove(ulong hash)
 24        {
 25            TranspositionTableEntry entry = Entries[hash & (Capacity - 1)];
 26            return entry?.Hash == hash && entry.Type == TranspositionEntryType.Exact ? entry.BestMove : null;
 27        }
 28
 29        public static (bool, int, Move) GetEntry(ulong hash, int alpha, int beta, int depth)
 30        {
 31            TranspositionTableEntry entry = Entries[hash & (Capacity - 1)];
 32
 33            if (entry == null)
 34                return (false, 0, null);
 35            if (entry.Hash != hash)
 36                return (false, 0, null);
 37            if (entry.Depth < depth)
 38                return (false, 0, null);
 39
 40            switch (entry.Type)
 41            {
 42                case TranspositionEntryType.Exact:
 43                    return (true, entry.Score, entry.BestMove);
 44                case TranspositionEntryType.Alpha:
 45                    if(entry.Score <= alpha) return (true, alpha, entry.BestMove);
 46                    break;
 47                case TranspositionEntryType.Beta:
 48                    if(entry.Score >= beta) return (true, beta, entry.BestMove);
 49                    break;
 50            }
 51
 52            return (false, 0, null);
 53        }
 54
 55        public static void SubmitEntry(ulong hash, int score, int depth, Move bestMove, TranspositionEntryType entryType
 56        {
 57            var index = hash & (Capacity - 1);
 58            if (Entries[index]?.Depth >= depth)
 59                return;
 60            Entries[index] = new TranspositionTableEntry { Hash = hash, Score = score, Depth = depth, BestMove = bestMov
 61        }
 62
 63        public static List<Move> CollectPrincipalVariation(BoardState boardState)
 64        {
 65            List<Move> pv = new();
 66            while (true)
 67            {
 68                TranspositionTableEntry entry = Entries[boardState.BoardHash & (Capacity - 1)];
 69                if (entry == null || entry.Hash != boardState.BoardHash || entry.Type != TranspositionEntryType.Exact)
 70                {
 71                    break;
 72                }
 73
 74                if (pv.Contains(entry.BestMove))
 75                    break;
 76
 77                boardState.MakeMove(entry.BestMove);
 78                if (boardState.IsInCheck(boardState.SideToMove.Other()))
 79                {
 80                    boardState.UnmakeMove(entry.BestMove);
 81                    break;
 82                }
 83                pv.Add(entry.BestMove);
 84            }
 85
 86            for (int i = pv.Count - 1; i >= 0; i--)
 87            {
 88                boardState.UnmakeMove(pv[i]);
 89            }
 90            return pv;
 91        }
 92
 93        public static int AdjustScore(int score, int ply)
 94        {
 95            if (!IsCloseToCheckmate(score))
 96            {
 97                return score;
 98            }
 99
 100            return score + (score > 0 ? +ply :  -ply);
 101        }
 102
 103        public static int RetrieveScore(int score, int ply)
 104        {
 105            if (!IsCloseToCheckmate(score))
 106            {
 107                return score;
 108            }
 109
 110            return score + (score > 0 ? -ply : +ply);
 111        }
 112
 113        private static bool IsCloseToCheckmate(int score)
 114        {
 115            return Constants.MaxCentipawnEval - Math.Abs(score) <= Constants.MaxPly;
 116        }
 117    }
 118
 119    public class TranspositionTableEntry
 120    {
 346509121        public int Score { get; init; }
 1086316122        public ulong Hash { get; init; }
 697658123        public int Depth { get; init; }
 308324124        public Move BestMove { get; init; }
 346644125        public TranspositionEntryType Type { get; init; }
 126    }
 127
 128    public enum TranspositionEntryType
 129    {
 130        Exact,
 131        Alpha,
 132        Beta
 133    }
 134}