Example #1
0
        public void RunPerft(string fen, int depth, long moveCount)
        {
            var gameState = new GameState(fen, _zobristHash);
            var perftData = new PerftData();
            var count     = gameState.RunPerftRecursively(_moveData, _zobristHash, perftData, 1, depth);

            Assert.That(count, Is.EqualTo(moveCount));
        }
Example #2
0
        internal void Perft(int depth)
        {
            var perftData = new PerftData();
            var stopwatch = new Stopwatch();

            stopwatch.Start();
            var count = _gameState.RunPerftRecursively(_moveData, _zobristHash, perftData, 1, depth);

            stopwatch.Stop();

            _logger.InfoFormat("Total Nodes: {0} {1} mS Elapsed: {2}", count, Environment.NewLine, stopwatch.ElapsedMilliseconds);
            _logger.DebugFormat("Total Nodes: {0} Total Captures {1} Total Checks {2} Total EnPassants {3} Total OO Castles {4} Total OOO Castles {5} Total Promotions {6}", count, perftData.TotalCaptures, perftData.TotalChecks, perftData.TotalEnpassants, perftData.TotalOOCastles, perftData.TotalOOOCastles, perftData.TotalPromotions);
        }
Example #3
0
        /// <summary>
        /// Runs similar to perft against a gamestate. Returns the total number of nodes that each move from the starting position makes. This is used when troublshooting move generation
        /// </summary>
        /// <param name="gameState">The gamestate being tested</param>
        /// <param name="moveData">The moveData to use</param>
        /// <param name="zobristHash">The zobrist hash data to use</param>
        /// <param name="perftData">The perft data. This is used if collection additional information about perft</param>
        /// <param name="ply">The ply to start the search on</param>
        /// <param name="depth">The depth of perft to run</param>
        internal static void CalculateDivide(this GameState gameState, MoveData moveData, ZobristHash zobristHash, PerftData perftData, int ply,
                                             int depth)
        {
            var   sb    = new StringBuilder(_divideOutput);
            ulong count = 0;

            gameState.GenerateMoves(MoveGenerationMode.All, ply, moveData);

            foreach (var move in gameState.Moves[ply])
            {
                gameState.MakeMove(move, zobristHash);

                if (!gameState.IsOppositeSideKingAttacked(moveData))
                {
                    ulong moveCount = RunPerftRecursively(gameState, moveData, zobristHash, perftData, ply + 1, depth - 1);
                    sb.AppendFormat("{0}{1} {2}{3}", MoveUtility.RankAndFile[move.GetFromMove()],
                                    MoveUtility.RankAndFile[move.GetToMove()], moveCount, Environment.NewLine);
                    count += moveCount;
                }
                gameState.UnMakeMove(move);
            }
            sb.AppendFormat("Total Nodes: {0}", count);
            _logger.InfoFormat(sb.ToString());
        }
Example #4
0
        /// <summary>
        /// Runs perft (Performance Test) against a gamestate. This is used to verify that all moves are being generated correctly.
        /// </summary>
        /// <param name="gameState">The gamestate being tested</param>
        /// <param name="moveData">The moveData to use</param>
        /// <param name="zobristHash">The zobristHash data to use</param>
        /// <param name="perftData">The perft data. This is used if collection additional information about perft</param>
        /// <param name="ply">The ply to start the search on</param>
        /// <param name="depth">The depth of perft to run</param>
        /// <returns>A count of the total number of nodes at depth 0</returns>
        internal static ulong RunPerftRecursively(this GameState gameState, MoveData moveData, ZobristHash zobristHash, PerftData perftData,
                                                  int ply, int depth)
        {
            if (depth == 0)
            {
                return(1);
            }

            ulong count = 0;

            gameState.GenerateMoves(MoveGenerationMode.All, ply, moveData);

            foreach (var move in gameState.Moves[ply])
            {
#if DEBUG
                var boardArray   = new uint[64];
                var previousHash = gameState.HashKey;
                for (var i = 0; i < boardArray.Length - 1; i++)
                {
                    boardArray[i] = gameState.BoardArray[i];
                }

                if (_logger.IsTraceEnabled)
                {
                    _logger.TraceFormat(
                        "MoveHash {0} GameState Move From {1} To {2} MovingPiece {3} CapturedPiece {4} PromotedPeice {5}",
                        move.GetHashCode(), move.GetFromMove().ToRankAndFile(), move.GetToMove().ToRankAndFile(),
                        move.GetMovingPiece(), move.GetCapturedPiece(), move.GetPromotedPiece());

                    _logger.TraceFormat("GameState All Bitboards Before Move {0} {1}", Environment.NewLine,
                                        gameState.ConvertBitBoardsToConsoleOutput());
                    _logger.TraceFormat("GameState BoardArray Before Move {0} {1}", Environment.NewLine,
                                        gameState.ConvertBoardArrayToConsoleOutput());
                }
#endif
                gameState.MakeMove(move, zobristHash);

#if DEBUG
                if (_logger.IsTraceEnabled)
                {
                    _logger.TraceFormat("MoveHash {0} GameState All Bitboards After Move {1} {2}", move.GetHashCode(),
                                        Environment.NewLine,
                                        gameState.ConvertBitBoardsToConsoleOutput());
                    _logger.TraceFormat("MoveHash {0} GameState BoardArray After Move {1} {2}", move.GetHashCode(),
                                        Environment.NewLine,
                                        gameState.ConvertBoardArrayToConsoleOutput());
                }
#endif

                if (!gameState.IsOppositeSideKingAttacked(moveData))
                {
                    count += RunPerftRecursively(gameState, moveData, zobristHash, perftData, ply + 1, depth - 1);
#if DEBUG
                    if (depth == 1)
                    {
                        if (move.IsPieceCaptured())
                        {
                            perftData.TotalCaptures++;
                        }
                        if (move.IsEnPassant())
                        {
                            perftData.TotalEnpassants++;
                        }
                        if (move.IsPromotion())
                        {
                            perftData.TotalPromotions++;
                        }
                        if (move.IsCastleOO())
                        {
                            perftData.TotalOOCastles++;
                        }
                        if (move.IsCastleOOO())
                        {
                            perftData.TotalOOOCastles++;
                        }
                        if (gameState.IsCurrentSideKingAttacked(moveData))
                        {
                            perftData.TotalChecks++;
                        }
                    }
#endif
                }

                gameState.UnMakeMove(move);

#if DEBUG
                if (_logger.IsTraceEnabled)
                {
                    _logger.TraceFormat("MoveHash {0} GameState All Bitboards After UnMakeMove {1} {2}",
                                        move.GetHashCode(), Environment.NewLine,
                                        gameState.ConvertBitBoardsToConsoleOutput());
                    _logger.TraceFormat("MoveHash {0} GameState BoardArray After UnMakeMove {1} {2}", move.GetHashCode(),
                                        Environment.NewLine,
                                        gameState.ConvertBoardArrayToConsoleOutput());
                }

                for (var i = 0; i < boardArray.Length - 1; i++)
                {
                    Debug.Assert(boardArray[i] == gameState.BoardArray[i]);
                }

                Debug.Assert(previousHash == gameState.HashKey);
#endif
            }
            return(count);
        }