Exemplo n.º 1
0
        /// <summary>
        /// Runs CPU benchmark and outputs summary results,
        /// with an overall statistic provided (index to 100 on a Intel Skylake 6142).
        /// </summary>
        /// <returns>Relative CPU index (baseline 100)</returns>
        static int DumpCPUBenchmark()
        {
            Console.WriteLine("-----------------------------------------------------------------------------------");
            Console.WriteLine("CPU BENCHMARK");

            Position             ps = Position.StartPosition;
            EncodedPositionBoard zb = default;
            MGMove nmove            = ConverterMGMoveEncodedMove.EncodedMoveToMGChessMove(new EncodedMove("e2e4"), MGChessPositionConverter.MGChessPositionFromFEN(ps.FEN));

            float ops1 = Benchmarking.DumpOperationTimeAndMemoryStats(() => MGPosition.FromPosition(ps), "MGPosition.FromPosition");
            float ops2 = Benchmarking.DumpOperationTimeAndMemoryStats(() => MGChessPositionConverter.MGChessPositionFromFEN(ps.FEN), "MGChessPositionFromFEN");
            float ops3 = Benchmarking.DumpOperationTimeAndMemoryStats(() => ConverterMGMoveEncodedMove.MGChessMoveToEncodedMove(nmove), "MGChessMoveToLZPositionMove");
            float ops4 = Benchmarking.DumpOperationTimeAndMemoryStats(() => EncodedBoardZobrist.ZobristHash(zb), "ZobristHash");

            // Performance metric is against a baseline system (Intel Skylake 6142)
            const float REFERENCE_BM1_OPS = 2160484;
            const float REFERENCE_BM2_OPS = 448074;
            const float REFERENCE_BM3_OPS = 157575582;
            const float REFERENCE_BM4_OPS = 112731351;

            float relative1 = ops1 / REFERENCE_BM1_OPS;
            float relative2 = ops2 / REFERENCE_BM2_OPS;
            float relative3 = ops3 / REFERENCE_BM3_OPS;
            float relative4 = ops4 / REFERENCE_BM4_OPS;

            float avg = StatUtils.Average(relative1, relative2, relative3, relative4);

            Console.WriteLine();
            Console.WriteLine($"CERES CPU BENCHMARK SCORE: {avg*100,4:F0}");

            return((int)MathF.Round(avg * 100, 0));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Dumps detailed information about possible moves from this node
        /// and optionally from descendent nodes up to a specified depth.
        /// </summary>
        /// <param name="lastLevel"></param>
        /// <param name="firstLevelStartPVOnly"></param>
        /// <param name="minNodes"></param>
        /// <param name="prefixString"></param>
        /// <param name="shouldAbort"></param>
        public void Dump(int lastLevel             = int.MaxValue,
                         int firstLevelStartPVOnly = int.MaxValue,
                         int minNodes        = int.MinValue,
                         string prefixString = null,
                         Predicate <MCTSNode> shouldAbort = null,
                         int maxMoves = int.MaxValue)
        {
            if (N < minNodes)
            {
                return;
            }

            if (shouldAbort != null && shouldAbort(this))
            {
                return;
            }

            Position cPos = MGChessPositionConverter.PositionFromMGChessPosition(Annotation.PosMG);

            float multiplerOurPerspective = Annotation.PosMG.BlackToMove ? -1.0f : 1.0f;

            bool  minimize       = true;
            float bestChildValue = minimize ? int.MaxValue : int.MinValue;

            if (Parent != null)
            {
                MCTSNode[] sortedChildren = Parent.ChildrenSorted(n => n.V);
                bestChildValue = minimize ? sortedChildren[0].V : sortedChildren[^ 1].V;
Exemplo n.º 3
0
        /// <summary>
        /// Constructs a test batch of specified size.
        /// </summary>
        /// <param name="evaluator"></param>
        /// <param name="count"></param>
        /// <param name="fen"></param>
        /// <returns></returns>
        public static EncodedPositionBatchFlat MakeTestBatch(NNEvaluator evaluator, int count, string fen = null)
        {
            EncodedPositionBatchFlat batch;

            if (fen == null)
            {
                fen = Position.StartPosition.FEN;
            }
            Position   rawPos = Position.FromFEN(fen);
            MGPosition mgPos  = MGPosition.FromPosition(rawPos);

            EncodedPositionWithHistory position = EncodedPositionWithHistory.FromFEN(fen);

            EncodedPositionWithHistory[] positions = new EncodedPositionWithHistory[count];
            Array.Fill(positions, position);

            batch = new EncodedPositionBatchFlat(positions, count);

            bool hasPositions = evaluator.InputsRequired.HasFlag(NNEvaluator.InputTypes.Positions);
            bool hasMoves     = evaluator.InputsRequired.HasFlag(NNEvaluator.InputTypes.Moves);
            bool hasHashes    = evaluator.InputsRequired.HasFlag(NNEvaluator.InputTypes.Hashes);
            bool hasBoards    = evaluator.InputsRequired.HasFlag(NNEvaluator.InputTypes.Boards);

            if (fen != null)
            {
                if (hasPositions)
                {
                    batch.Positions = new MGPosition[count];
                }
                if (hasHashes)
                {
                    batch.PositionHashes = new ulong[count];
                }
                if (hasMoves)
                {
                    batch.Moves = new MGMoveList[count];
                }

                for (int i = 0; i < count; i++)
                {
                    if (hasPositions)
                    {
                        batch.Positions[i] = MGChessPositionConverter.MGChessPositionFromFEN(fen);
                    }
                    if (hasHashes)
                    {
                        batch.PositionHashes[i] = (ulong)i + (ulong)batch.Positions[i].GetHashCode();
                    }
                    if (hasMoves)
                    {
                        MGMoveList moves = new MGMoveList();
                        MGMoveGen.GenerateMoves(in mgPos, moves);
                        batch.Moves[i] = moves;
                    }
                }
            }
            return(batch);
        }
Exemplo n.º 4
0
        static void TestZZ(string fen)
        {
            MGPosition curPosition = MGChessPositionConverter.MGChessPositionFromFEN(fen);

            // Generate moves
            MGMoveList moves = new MGMoveList();

            MGMoveGen.GenerateMoves(in curPosition, moves);
            foreach (var move in moves)
            {
                Console.WriteLine(move + " " + MoveStr(curPosition.AsPosition, move));
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Generates the set of moves and positions possible as the next move in a position.
        /// </summary>
        /// <param name="startPos"></param>
        /// <param name="moveToIncludeFilter"></param>
        /// <returns></returns>
        public static IEnumerable <(MGMove, Position)> GenPositions(Position startPos, Predicate <MGMove> moveToIncludeFilter = null)
        {
            MGPosition posMG = MGChessPositionConverter.MGChessPositionFromFEN(startPos.FEN); // TODO: more efficient?
            MGMoveList moves = new MGMoveList();

            MGMoveGen.GenerateMoves(in posMG, moves);

            for (int i = 0; i < moves.NumMovesUsed; i++)
            {
                // Only consider captures (would reduce number of pieces into range of tablebase)
                if (moveToIncludeFilter == null || moveToIncludeFilter(moves.MovesArray[i]))
                {
                    // Make this move and get new Position
                    MGPosition newPosMG = new MGPosition(posMG);
                    newPosMG.MakeMove(moves.MovesArray[i]);
                    Position newPos = MGChessPositionConverter.PositionFromMGChessPosition(in newPosMG);

                    yield return(moves.MovesArray[i], newPos);
                }
            }
        }
Exemplo n.º 6
0
        public static string AlgebraicMoveString(MGMove mgMove, Position pos)
        {
            string ret = null;

            bool white = pos.MiscInfo.SideToMove == SideType.White;

            MGPosition curPosition = MGChessPositionConverter.MGChessPositionFromFEN(pos.FEN);

            // Generate moves
            MGMoveList moves = new MGMoveList();

            MGMoveGen.GenerateMoves(in curPosition, moves);

            //if (white) mgMove = new MGMove(mgMove, true);
            MGPosition newPosition = MGChessPositionConverter.MGChessPositionFromFEN(pos.FEN);

            newPosition.MakeMove(mgMove);

            bool isCheck = MGMoveGen.IsInCheck(newPosition, white);

            if (mgMove.CastleShort)
            {
                ret = "O-O";
            }
            else if (mgMove.CastleLong)
            {
                ret = "O-O-O";
            }

            else
            {
                Square fromSquare = mgMove.FromSquare;
                Square toSquare   = mgMove.ToSquare;

                Piece fromType = pos.PieceOnSquare(fromSquare);
                Piece toPiece  = pos.PieceOnSquare(toSquare);

                if (fromType.Type == PieceType.Pawn)
                {
                    string promoteChar = "";
                    if (mgMove.PromoteQueen)
                    {
                        promoteChar = "Q";
                    }
                    if (mgMove.PromoteBishop)
                    {
                        promoteChar = "B";
                    }
                    if (mgMove.PromoteRook)
                    {
                        promoteChar = "R";
                    }
                    if (mgMove.PromoteKnight)
                    {
                        promoteChar = "N";
                    }

                    if (mgMove.EnPassantCapture)
                    {
                        int  newRank = white ? 6 : 3;
                        char newFile = char.ToLower(toSquare.FileChar);
                        ret = fromSquare.ToString().Substring(0, 1).ToLower() + "x" +
                              newFile + newRank;
                    }
                    else if (toPiece.Type == PieceType.None)
                    {
                        ret = toSquare.ToString().ToLower() + promoteChar;
                    }
                    else
                    {
                        ret = fromSquare.ToString().Substring(0, 1).ToLower() + "x" +
                              toSquare.ToString().ToLower() + promoteChar;
                    }
                }
                else
                {
                    string captureChar = toPiece.Type == PieceType.None ? "" : "x";

                    List <MGMove> matchingCaptures = MovesByPieceTypeThatTakeOnSquare(mgMove.Piece, mgMove.ToSquareIndex, moves);
                    if (matchingCaptures.Count == 1)
                    {
                        ret = char.ToUpper(fromType.Char) + captureChar + toSquare.ToString().ToLower();
                    }
                    else
                    {
                        // Disambiguate
                        DifferBy differBy = MoveDifferFromAllOthersBy(matchingCaptures, mgMove);
                        string   fileChar = fromSquare.FileChar.ToString().ToLower();
                        string   rankChar = fromSquare.RankChar.ToString().ToLower();

                        if (differBy == DifferBy.File)
                        {
                            ret = char.ToUpper(fromType.Char) + fileChar + captureChar + toSquare.ToString().ToLower();
                        }
                        else if (differBy == DifferBy.Rank)
                        {
                            ret = char.ToUpper(fromType.Char) + rankChar + captureChar + toSquare.ToString().ToLower();
                        }
                        else
                        {
                            ret = char.ToUpper(fromType.Char) + fileChar + rankChar + captureChar + toSquare.ToString().ToLower();
                        }
                    }
                }
            }

            if (isCheck)
            {
                return(ret + "+");
            }
            else
            {
                return(ret);
            }
        }