public void Add(TranspositionEntry entry)
        {
            ulong index = ItemHashFunction(entry.Hash);
            TranspositionEntry tpEntry = _items[index];

            if (tpEntry == null)
            {
                Count++;
                _items[index] = entry;
            }
            else //Collision
            {
                string tracemsg      = "";
                string tracemsdgtype = "";
                if (entry != null && entry.BestMove != null)
                {
                    tracemsg = entry.BestMove.Bits.ToString();
                }
                if (entry != null && entry.BestMove != null)
                {
                    tracemsdgtype = entry.BestMove.GetType().ToString();
                }

                TranspositionTableStatistics.Collisions++;
                _items[index] = ResolveCollision(tpEntry, entry);
            }
        }
Example #2
0
        public void Add(TranspositionEntry entry)
        {
            if (System.IO.File.Exists("stop.now"))
            {
                BinaryFormatter bf     = new BinaryFormatter();
                var             stream = File.Create("TranspositionTable_serialize.obj");
                bf.Serialize(stream, this);
                Environment.Exit(0);
            }

            ulong index = ItemHashFunction(entry.Hash);
            TranspositionEntry tpEntry = _items[index];

            //Trace.WriteLine( string.Format( "{0} : {1}", index, tpEntry.Hash ) );
            if (tpEntry == null)
            {
                Count++;
                _items[index] = entry;
                //Trace.WriteLine( string.Format( "[TranspositionTable]: Adding {0} : {1}", entry.Move.GetType().ToString(), entry.Move.Bits.ToString() ) );
            }
            else //Collision
            {
                Trace.WriteLine(string.Format("[TranspositionTable]: Collision {0}: {1}", entry.Move.GetType().ToString(), entry.Move.Bits.ToString()));
                _items[index] = ResolveCollision(tpEntry, entry);
            }
        }
 public TranspositionEntry this[ulong hash] {
     get {
         ulong index = ItemHashFunction(hash);
         TranspositionEntry entry = _items[index];
         if (entry == null)
         {
             TranspositionTableStatistics.Misses++;
         }
         else
         {
             TranspositionTableStatistics.Hits++;
         }
         return(entry);
     }
 }
Example #4
0
        /// <summary>
        /// Decides the best move for the player given by the color parameter, with a search
        /// of the given depth.
        /// </summary>
        public static ColoredBitBoard GetBestMove(ChessBoard board, int depth, ChessPieceColors color, GenerateMoveDelegate GenerateMoves, GetMaterialDelegate GetMaterialValue)
        {
            Debug.Assert(board != null);
            Debug.Assert(depth > 0);
            Debug.Assert(GenerateMoves != null);
            Debug.Assert(GetMaterialValue != null);

            //Alpha, have to add one to change symbol later otherwise overflow.
            double a = int.MinValue + 1;
            //Beta value.
            double                 b        = int.MaxValue;
            double                 val      = 0;
            ColoredBitBoard        bestMove = null;
            List <ColoredBitBoard> moves    = GenerateMoves(board, color);
            var ttEntry = new TranspositionEntry(board.BoardHash.Key, depth, val, false, EntryType.Exact);

            foreach (ColoredBitBoard move in moves)
            {
                board.Update(move);
                if (color == ChessPieceColors.Black)
                {
                    val = -NegaMaxAlgorithm(board, depth - 1, -b, -a, ChessPieceColors.White, GenerateMoves, GetMaterialValue);
                }
                else if (color == ChessPieceColors.White)
                {
                    val = -NegaMaxAlgorithm(board, depth - 1, -b, -a, ChessPieceColors.Black, GenerateMoves, GetMaterialValue);
                }
                if (val > a)
                {
                    a                = val;
                    bestMove         = move;
                    ttEntry.BestMove = move;
                    ttEntry.Score    = a;
                }

                board.Undo();
            }
            TranspositionTable.TranspositionCache.Add(ttEntry);
            return(bestMove);
        }
Example #5
0
        public static List <ColoredBitBoard> SortMovesByPV(List <ColoredBitBoard> legalMoves, ChessBoard inputChessBoard, BitBoard blackMoves, BitBoard whiteMoves)
        {
            TranspositionEntry entry = TranspositionTable.TranspositionCache[inputChessBoard.BoardHash.Key];

            if (entry == null || entry.BestMove == null)
            {
                return(legalMoves);
            }
            ColoredBitBoard bestmove = entry.BestMove;

            if (bestmove is PawnBitBoard && ((PawnBitBoard)bestmove).Color == ChessPieceColors.White && legalMoves[0].Color == ChessPieceColors.White)
            {
                Debug.Assert(bestmove.Bits != inputChessBoard.WhitePawn.Bits);
            }
            ColoredBitBoard bestmoveInLegalMoves = legalMoves.Find(p => p.Equals(bestmove));

            if (bestmoveInLegalMoves != null)
            {
                legalMoves.Remove(bestmoveInLegalMoves);
                legalMoves.Insert(0, bestmove);
            }
            return(legalMoves);
        }
Example #6
0
        /// <summary>
        /// Implementation of the NegaMax algorithm.
        /// <param name="board"></param>
        /// <param name="depth"></param>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <param name="color"></param>
        /// <param name="GenerateMoves"></param>
        /// <param name="GetMaterialValue"></param>
        /// <returns></returns>
        public static double NegaMaxAlgorithm(
            ChessBoard board,
            int depth, double a, double b,
            ChessPieceColors color,
            GenerateMoveDelegate GenerateMoves,
            GetMaterialDelegate GetMaterialValue
            )
        {
            ColoredBitBoard bestMove = null;
            var             hashBeforeTermCondition = board.BoardHash.Key;
            var             termCondition           = IsTerminal(board, color, GenerateMoves);

            Debug.Assert(hashBeforeTermCondition == board.BoardHash.Key);
            if (termCondition == TerminalConditions.Win ||
                termCondition == TerminalConditions.Draw ||
                depth == 0)
            {
                return((int)color * (GetMaterialValue(board)));
            }
            else
            {
                bool  usingTT         = false;
                ulong hash_beforeMove = board.BoardHash.Key;
                var   ttEntry         = TranspositionTable.TranspositionCache[board.BoardHash.Key];
                if (ttEntry != null &&
                    ttEntry.Hash == board.BoardHash.Key &&
                    ttEntry.Depth >= depth
                    )
                {
                    if (ttEntry.NodeType == EntryType.Alpha && ttEntry.Score <= a)
                    {
                        return(a);
                    }

                    if (ttEntry.NodeType == EntryType.Beta && ttEntry.Score >= b)
                    {
                        return(b);
                    }
                    if (ttEntry.NodeType == EntryType.Exact)
                    {
                        return(ttEntry.Score);
                    }
                    usingTT = true;
                }

                TranspositionEntry newEntry = new TranspositionEntry(board.BoardHash.Key, depth, 0, false, EntryType.Alpha);

                List <ColoredBitBoard> moves = new List <ColoredBitBoard>();
                moves = GenerateMoves(board, color);

                foreach (ColoredBitBoard move in moves)
                {
                    double val = 0;
                    board.Update(move);
                    var hashBeforeRec = board.BoardHash.Key;
                    if (color == ChessPieceColors.White)
                    {
                        val = -NegaMaxAlgorithm(board, depth - 1, -b, -a, ChessPieceColors.Black, GenerateMoves, GetMaterialValue);
                    }
                    else if (color == ChessPieceColors.Black)
                    {
                        val = -NegaMaxAlgorithm(board, depth - 1, -b, -a, ChessPieceColors.White, GenerateMoves, GetMaterialValue);
                    }
                    Debug.Assert(hashBeforeRec == board.BoardHash.Key);
                    board.Undo();
                    usingTT = false;
                    if (val >= b)
                    {
                        if (!usingTT)
                        {
                            newEntry.NodeType = EntryType.Beta;
                            newEntry.Score    = val;
                            TranspositionTable.TranspositionCache.Add(newEntry);
                            Debug.Assert(hash_beforeMove == board.BoardHash.Key, "Board hash changed during update/undo");
                        }
                        return(val);
                    }
                    if (val >= a)
                    {
                        a                 = val;
                        bestMove          = move;
                        newEntry.NodeType = EntryType.Exact;
                    }

                    Debug.Assert(hash_beforeMove == board.BoardHash.Key, "Board hash changed during update/undo");
                }
                if (!usingTT)
                {
                    if (newEntry.NodeType == EntryType.Exact)
                    {
                        newEntry.BestMove = bestMove;
                    }
                    newEntry.Score = a;
                    TranspositionTable.TranspositionCache.Add(newEntry);
                }
                return(a);
            }
        }
 private TranspositionEntry ResolveCollision(TranspositionEntry oldEntry, TranspositionEntry newEntry)
 {
     return(newEntry);
 }