< Summary

Information
Class: Rudim.Common.TranspositionTable
Assembly: Rudim
File(s): /home/runner/work/rudim/rudim/Rudim/Common/TranspositionTable.cs
Line coverage
90%
Covered lines: 39
Uncovered lines: 4
Coverable lines: 43
Total lines: 134
Line coverage: 90.6%
Branch coverage
84%
Covered branches: 37
Total branches: 44
Branch coverage: 84%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
ClearTable()100%11100%
GetHashMove(...)0%4260%
GetEntry(...)100%1414100%
SubmitEntry(...)100%44100%
CollectPrincipalVariation(...)91.66%131284.61%
AdjustScore(...)100%44100%
RetrieveScore(...)100%44100%
IsCloseToCheckmate(...)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        {
 115            Entries = new TranspositionTableEntry[Capacity];
 116        }
 17
 18        public static void ClearTable()
 19        {
 920            Array.Clear(Entries);
 921        }
 22
 23        public static Move GetHashMove(ulong hash)
 24        {
 025            TranspositionTableEntry entry = Entries[hash & (Capacity - 1)];
 026            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        {
 184042331            TranspositionTableEntry entry = Entries[hash & (Capacity - 1)];
 32
 184042333            if (entry == null)
 98465734                return (false, 0, null);
 85576635            if (entry.Hash != hash)
 64511536                return (false, 0, null);
 21065137            if (entry.Depth < depth)
 9455738                return (false, 0, null);
 39
 11609440            switch (entry.Type)
 41            {
 42                case TranspositionEntryType.Exact:
 22743                    return (true, entry.Score, entry.BestMove);
 44                case TranspositionEntryType.Alpha:
 2382345                    if(entry.Score <= alpha) return (true, alpha, entry.BestMove);
 46                    break;
 47                case TranspositionEntryType.Beta:
 16941448                    if(entry.Score >= beta) return (true, beta, entry.BestMove);
 49                    break;
 50            }
 51
 3849752            return (false, 0, null);
 53        }
 54
 55        public static void SubmitEntry(ulong hash, int score, int depth, Move bestMove, TranspositionEntryType entryType
 56        {
 43709957            var index = hash & (Capacity - 1);
 43709958            if (Entries[index]?.Depth >= depth)
 20668459                return;
 23041560            Entries[index] = new TranspositionTableEntry { Hash = hash, Score = score, Depth = depth, BestMove = bestMov
 23041561        }
 62
 63        public static List<Move> CollectPrincipalVariation(BoardState boardState)
 64        {
 4265            List<Move> pv = new();
 10466            while (true)
 67            {
 14668                TranspositionTableEntry entry = Entries[boardState.BoardHash & (Capacity - 1)];
 14669                if (entry == null || entry.Hash != boardState.BoardHash || entry.Type != TranspositionEntryType.Exact)
 70                {
 71                    break;
 72                }
 73
 10474                if (pv.Contains(entry.BestMove))
 75                    break;
 76
 10477                boardState.MakeMove(entry.BestMove);
 10478                if (boardState.IsInCheck(boardState.SideToMove.Other()))
 79                {
 080                    boardState.UnmakeMove(entry.BestMove);
 081                    break;
 82                }
 10483                pv.Add(entry.BestMove);
 84            }
 85
 29286            for (int i = pv.Count - 1; i >= 0; i--)
 87            {
 10488                boardState.UnmakeMove(pv[i]);
 89            }
 4290            return pv;
 91        }
 92
 93        public static int AdjustScore(int score, int ply)
 94        {
 43709995            if (!IsCloseToCheckmate(score))
 96            {
 42998897                return score;
 98            }
 99
 7111100            return score + (score > 0 ? +ply :  -ply);
 101        }
 102
 103        public static int RetrieveScore(int score, int ply)
 104        {
 77597105            if (!IsCloseToCheckmate(score))
 106            {
 75555107                return score;
 108            }
 109
 2042110            return score + (score > 0 ? -ply : +ply);
 111        }
 112
 113        private static bool IsCloseToCheckmate(int score)
 114        {
 514696115            return Constants.MaxCentipawnEval - Math.Abs(score) <= Constants.MaxPly;
 116        }
 117    }
 118
 119    public class TranspositionTableEntry
 120    {
 121        public int Score { get; init; }
 122        public ulong Hash { get; init; }
 123        public int Depth { get; init; }
 124        public Move BestMove { get; init; }
 125        public TranspositionEntryType Type { get; init; }
 126    }
 127
 128    public enum TranspositionEntryType
 129    {
 130        Exact,
 131        Alpha,
 132        Beta
 133    }
 134}