예제 #1
0
        public static void UciLoop()
        {
            Console.Write($"id name Infrared\n");
            Console.Write($"id author sfbea\n");
            Console.Write($"uciok\n");

            var info  = new PersistentSearchInfo();
            var board = new BitBoard(BoardVariant.Default);

            while (true)
            {
                string stdin = Console.ReadLine() ?? "";                 // todo: fix eval display, fix eval + pawn eval, fix black side play, fix your life

                if (string.IsNullOrWhiteSpace(stdin))
                {
                    continue;
                }



                if (stdin == "isready")
                {
                    Console.Write("readyok\n");
                    continue;
                }
                else if (stdin.Length >= 8 && stdin.Substring(0, 8) == "position")
                {
                    board = ParsePositionUci(info, stdin);
                }
                else if (stdin.Length >= 10 && stdin.Substring(0, 10) == "ucinewgame")
                {
                    board = ParsePositionUci(info, "position startpos");
                }
                else if (stdin.Length >= 2 && stdin.Substring(0, 2) == "go")
                {
                    ParseGoUci(board, info, stdin);
                }
                else if (stdin == "stop")
                {
                    info.Timer?.Stop();
                    LogBestmove(info.PrincipalVariation, board);
                    info.Stopped = true;
                }
                else if (stdin == "quit")
                {
                    info.Stopped = true;
                    break;
                }
                else if (stdin == "uci")
                {
                    Console.Write($"id name Infrared\n");
                    Console.Write($"id author sfbea\n");
                    Console.Write($"uciok\n");
                }

                // NOT UCI; TESTING ONLY
                if (stdin == "eval")
                {
                    Console.WriteLine($"board eval: {Engine.Evaluator.Evaluate(board)}");
                }
            }
        }
예제 #2
0
        static BitBoard ParsePositionUci(PersistentSearchInfo info, string stdin)
        {
            info.Reset();

            // position startpos
            // position fen {fen}
            // ... moves e2e4 e7e5 b7b8q
            stdin = stdin.Substring(9);
            BitBoard board;

            if (stdin.Substring(0, 3) == "fen")
            {
                string fen = stdin.Substring(4).Split(" moves ")[0].Trim();
                board = ChessStringCoding.DecodeFEN(fen);
            }
            else
            {
                board = new BitBoard(BoardVariant.Default);
            }

            if (stdin.Contains(" moves "))
            {
                string[] moves = stdin.Split(" moves ")[1].Split(' ');
                for (int i = 0; i < moves.Length; i++)
                {
                    var(from, to) = ChessStringCoding.DecodeMove(moves[i], out ChessPiece promotion);
                    board         = new BitBoard(board, from, to, BitBoardUtils.GetPieceAtIndex(board, from));

                    if (promotion != ChessPiece.None && promotion != ChessPiece.Queen)
                    {
                        // this code will basically never run, but who knows
                        int   zIdOffset = ZobristHashes.GetColourOffset(!board.Flags.HasFlag(BitBoardFlags.WhitesTurn));
                        ulong lto       = 1ul << to;

                        board.Queens    &= ~lto;
                        board.ZobristId ^= ZobristHashes.Hashes[(int)ChessPiece.Queen + zIdOffset, to];                         // xor out queen
                        board.ZobristId ^= ZobristHashes.Hashes[(int)promotion + zIdOffset, to];                                // xor in promoted piece
                        switch (promotion)
                        {
                        case ChessPiece.Rook:
                            board.Rooks |= lto;
                            break;

                        case ChessPiece.Bishop:
                            board.Bishops |= lto;
                            break;

                        case ChessPiece.Knight:
                            board.Knights |= lto;
                            break;

                        default:
                            throw new Exception();
                        }

                        if (i == moves.Length - 1)
                        {
                            // if this is the last move instruction, covered tiles must be updated
                            board.SetDerivitiveValues();
                        }
                    }
                }
            }

            return(board);
        }
예제 #3
0
        static void ParseGoUci(BitBoard board, PersistentSearchInfo info, string stdin)
        {
            // go depth 8 wtime 300000 btime 3000000 winc 1000 binc 1000 movetime 1500 movestogo 35

            bool isWhitesTurn = board.Flags.HasFlag(BitBoardFlags.WhitesTurn);

            int time      = int.MinValue;
            int increment = 0;
            int depth     = int.MinValue;
            int movestogo = 30;
            int movetime  = int.MinValue;

            string[] paramaters = stdin.Split(' ');
            for (int i = 1 /* skip 'go' */; i < paramaters.Length; i++)
            {
                // 'infinite' param will just skip over everything and continue
                if (paramaters[i] == "wtime" && isWhitesTurn || paramaters[i] == "btime" && !isWhitesTurn)
                {
                    time = int.Parse(paramaters[i + 1]);
                    i++;
                }
                else if (paramaters[i] == "winc" && isWhitesTurn || paramaters[i] == "binc" && !isWhitesTurn)
                {
                    increment = int.Parse(paramaters[i + 1]);
                    i++;
                }
                else if (paramaters[i] == "movetime")
                {
                    movetime = int.Parse(paramaters[i + 1]);
                    i++;
                }
                else if (paramaters[i] == "movestogo")
                {
                    movestogo = int.Parse(paramaters[i + 1]);
                    i++;
                }
                else if (paramaters[i] == "depth")
                {
                    depth = int.Parse(paramaters[i + 1]);
                    i++;
                }
            }

            // create search thread
            var thread = new Thread(() => Engine.Search.Search_PVS_IDF(board, info));

            // configure depth limit
            info.MaxIdfDepth = depth == int.MinValue ? 50 : depth;
            // configure engine timer
            if (time != int.MinValue || movetime != int.MinValue)
            {
                var timer = new System.Timers.Timer {
                    AutoReset = false,
                    // time controls
                    Interval = movetime == int.MinValue ? time / movestogo + increment - 50 : movetime - 50,
                };

                timer.Elapsed += (object sender, System.Timers.ElapsedEventArgs args) => {
                    LogBestmove(info.PrincipalVariation, board);
                    info.Stopped = true;
                    timer.Close();
                };

                timer.Start();
                info.Timer = timer;
            }
            thread.Start();
        }