예제 #1
0
        private static bool ThreefoldRepetitionEnforceable(Chessboard position)
        {
            if (position.Board[position.LastMove.ToSquare].OccupiedBy.Type == PieceType.Pawn)
            {
                return(false);
            }

            long zobristKey     = ZobristHasher.GetZobristHash(position);
            bool drawEnforcable = position.GameHistory.ContainsKey(zobristKey) ?
                                  position.GameHistory[zobristKey] >= 3 : false;

            return(drawEnforcable);
        }
예제 #2
0
        private static void PlayEngineGame()
        {
            Stopwatch sw = new Stopwatch();

            //Chessboard position = new Chessboard(false);
            //Chessboard position = Utils.LoadPositionFromFenString("1rbq1bnr/pp1kpppp/2p5/P1PP4/Q7/4P3/5PPP/RNB1KBNR w KQ - 0 15");
            //Chessboard position = Utils.LoadPositionFromFenString("r1k2bnr/p3pppp/8/2P5/4b3/8/3N1PPP/R1B1KBNR b KQ - 1 20"); // Castling problems
            //Chessboard position = Utils.LoadPositionFromFenString("R1rqkb1r/1Ppbpppp/7n/8/3P4/2P1P3/3N1PPP/2BQKBNR b KQkq - 2 25");
            //Chessboard position = Utils.LoadPositionFromFenString("r1bqkbnr/pppppppp/2P5/8/P2P4/2P1P3/5PPP/RNBQKBNR b KQkq - 0 12");
            //Chessboard position = Utils.LoadPositionFromFenString("1r2kbnr/pqpbpppp/8/8/3P4/2P1P3/3N1PPP/1RBQKBNR b Kk - 2 30");
            //Chessboard position = Utils.LoadPositionFromFenString("4kbnr/p1p1pppp/4b3/N7/3P4/2P1P3/5PPP/2B1KBNR b Kk 16 2 32");
            //Chessboard position = Utils.LoadPositionFromFenString("8/3nbkpp/p2rp3/8/K7/2P5/4BPPP/2B3NR w - - 10 42");
            //Chessboard position = Utils.LoadPositionFromFenString("8/8/5k2/K3R1p1/6p1/2r5/7P/6N1 w - - 10 48");
            //Chessboard position = Utils.LoadPositionFromFenString("2k2bnr/pr2pppp/2P5/8/4b3/8/3N1PPP/R1B1KBNR w KQ - 5 21");
            //Chessboard position = Utils.LoadPositionFromFenString("6r1/pk1b1pp1/2p5/2P2n1p/8/8/5PPP/2B1KBNR w K - 3 54");
            //Chessboard position = Utils.LoadPositionFromFenString("4r3/pk1b1pp1/2p5/2P2n1B/8/8/5PPP/2B1K1NR w K - 0 56"); //Problematic
            //Chessboard position = Utils.LoadPositionFromFenString("2k1b3/3r1pp1/2p4n/2P3K1/5P2/3B4/3B2PP/6NR w - - 7 70");
            //Chessboard position = Utils.LoadPositionFromFenString("4k3/7K/2p5/2P5/8/8/8/8 w - - 10 83");
            //Chessboard position = Utils.LoadPositionFromFenString("8/2kbrpp1/p1p5/2P2n2/5P2/6PB/4N2P/2B1K2R b K - 0 67");
            //Chessboard position = Utils.LoadPositionFromFenString("8/4k3/2p2pp1/p4n2/1rb2PB1/8/6PP/2B1K1NR w K - 8 81");
            //Chessboard position = Utils.LoadPositionFromFenString("4k3/1R2N1K1/8/8/8/8/8/8 b - - 4 151");
            //Chessboard position = Utils.LoadPositionFromFenString("3k4/R5K1/3N4/8/8/8/8/8 b - - 14 156");
            //Chessboard position = Utils.LoadPositionFromFenString("8/4k3/5pp1/p1p2n2/1rb2PB1/8/6PP/2B1K1NR w K - 8 81");
            //Chessboard position = Utils.LoadPositionFromFenString("8/4k3/5pp1/p1p2B2/1rb2P2/8/6PP/2B1K1NR b K - 1 82");
            //Chessboard position = Utils.LoadPositionFromFenString("8/5k2/5pp1/p1p2n2/1rb2PB1/8/6PP/2B1K1NR w K - 8 81");
            //Chessboard position = Utils.LoadPositionFromFenString("8/1k6/5pp1/p1p5/1rb2P1P/3B4/3B2P1/4K1NR b K - 12 41");
            Chessboard position = Utils.LoadPositionFromFenString("r4r1k/1bpq1p1n/p1np4/1p1Bb1BQ/P7/6R1/1P3PPP/1N2R1K1 w - - 4 28"); // Mate in 4

            //Chessboard position = Utils.LoadPositionFromFenString("4rr1k/1Ppq1p1n/2np4/3B2BQ/8/6b1/1P3PPP/1N2R1K1 b - - 8 32");
            //Chessboard position = Utils.LoadPositionFromFenString("5k2/2p4n/8/p3Q3/5r2/8/5q1P/7K b - - 17 59");
            //Chessboard position = Utils.LoadPositionFromFenString("r1b1k2r/ppppnppp/2n2q2/2b5/3NP3/2P1B3/PP3PPP/RN1QKB1R w KQkq - 5 13");
            //Chessboard position = Utils.LoadPositionFromFenString("rnb1kb1r/ppppnppp/5q2/6B1/3pP3/2N2N2/PPP2PPP/R2QKB1R b KQkq - 4 1");
            //Chessboard position = Utils.LoadPositionFromFenString("rnb1kb1r/ppppnppp/3q4/6B1/4P3/2p2N2/PPPK1PPP/R2Q1B1R w kq - 3 32");
            //Chessboard position = Utils.LoadPositionFromFenString("rnb1kb1r/3p1ppp/p2q4/1ppNn1B1/B3P3/P7/R1PQ1PPP/4NRK1 w kq 17 0 16");
            //Chessboard position = Utils.LoadPositionFromFenString("rnb1kb1r/3p1ppp/p2q4/QppNn1B1/B3P3/P7/R1P2PPP/4NRK1 b kq 17 0 16");
            //Chessboard position = Utils.LoadPositionFromFenString("r1b1k1nr/pppp1ppp/8/4P3/1P6/6P1/PP2Q2P/RNB1KBNq b KQkq - 0 6");
            //Chessboard position = Utils.LoadPositionFromFenString("1n1qkb1r/4pppp/2p3b1/3nP3/r5P1/3B3P/PPPP1P2/R1BQK2R w KQkq - 0 11");

            position.PrintBoard();

            while (true)
            {
                //try
                //{
                sw.Start();

                Search.Initialize(position, 5);

                sw.Stop();
                //}
                //catch
                //{
                //    position.PrintBoard();
                //    System.Console.WriteLine("\n\nERROR");
                //    System.Console.ReadLine();
                //}

                if (position.MaximizingSideBestMove.Direction != Direction.Castle)
                {
                    Move bestMove = new Move(
                        position.MaximizingSideBestMove.FromSquare,
                        position.MaximizingSideBestMove.ToSquare,
                        position.MaximizingSideBestMove.Direction);

                    position.MakeMove(bestMove);
                }
                else
                {
                    Move bestMove = new Move(
                        position.MaximizingSideBestMove.KingFromSquare,
                        position.MaximizingSideBestMove.KingToSquare,
                        position.MaximizingSideBestMove.RookFromSquare,
                        position.MaximizingSideBestMove.RookToSquare);

                    position.MakeMove(bestMove);
                }

                position.PrintBoard();

                System.Console.WriteLine("\n\nMove: " + position.MoveCounter);
                System.Console.WriteLine("Fifty-move rule: " + position.FiftyMoveCounter);
                System.Console.WriteLine("Hash: " + ZobristHasher.GetZobristHash(position));
                System.Console.WriteLine("Side to move: " + position.SideToMove);
                System.Console.WriteLine("EnPassant square: " + position.EnPassantSquare);
                System.Console.WriteLine("Visited nodes: " + Search.VisitedNodes);
                System.Console.WriteLine("Elapsed: " + sw.Elapsed);
                System.Console.ReadLine();

                sw.Reset();
            }
        }
예제 #3
0
        private static int DoAlphaBetaPruning(int depth, int alpha, int beta)
        {
            VisitedNodes++;

            List <Move> availableMoves = MoveGenerator.GetAvailableMoves(position);

            position.PieceActivity = availableMoves.Count;
            int gameStateScore = GetGameStateScore(position, availableMoves.Count, depth);

            if (gameStateScore != 9999)
            {
                return(gameStateScore);
            }

            MoveSorter.SortMoves(position, availableMoves, killerMoves, depth);

            for (int moveIndex = 0; moveIndex < availableMoves.Count; moveIndex++)
            {
                Move currentMove = availableMoves[moveIndex];

                position.MakeMove(currentMove);

                long zobristKey = ZobristHasher.GetZobristHash(position);

                if (!position.GameHistory.ContainsKey(zobristKey))
                {
                    position.GameHistory.Add(zobristKey, 1);
                }
                else
                {
                    position.GameHistory[zobristKey]++;
                }

                int score =
                    (position.TranspositionTable.ContainsKey(zobristKey) &&
                     position.TranspositionTable[zobristKey].Depth >= depth) ?
                    position.TranspositionTable[zobristKey].Score :
                    DoAlphaBetaPruning(depth + 1, alpha, beta);

                position.UndoMove(currentMove);
                position.GameHistory.Remove(zobristKey);

                if (position.SideToMove == maximizingSide)
                {
                    if (score >= beta)
                    {
                        TryAddKillerMove(currentMove, depth);

                        return(beta);
                    }

                    if (score > alpha)
                    {
                        alpha = score;

                        if (depth == 0)
                        {
                            position.MaximizingSideBestMove = currentMove;
                        }

                        UpdatePrincipalVariation(depth, currentMove);
                        TryAddTableEntry(zobristKey, score, depth, currentMove);
                    }
                }
                else
                {
                    if (score <= alpha)
                    {
                        return(alpha);
                    }

                    if (score <= beta)
                    {
                        beta = score;

                        UpdatePrincipalVariation(depth, currentMove);
                    }
                }
            }

            return((position.SideToMove == maximizingSide) ? alpha : beta);
        }