Example #1
0
        public void TestMakingMoves()
        {
            Board board2 = new Board();
            TestingHelper.MakeSomeMoves(board2);

            Debug.WriteLine(board2.ToString());
        }
Example #2
0
        public void TestEnPassantCapture()
        {
            Board board2 = new Board();
            TestingHelper.MakeSomeMoves(board2);

            board2.MakeUserMove("c5d6");

            Debug.WriteLine(board2.ToString());
        }
Example #3
0
        public void TestFirstMoveGeneration()
        {
            Board board = new Board();

            TestingHelper.MakeSomeMoves(board);
            int movesCount;
            UInt16[] moves = board.GenerateMoves(out movesCount);
            Console.WriteLine(movesCount);
        }
Example #4
0
        public void TestCastling()
        {
            Board board2 = new Board();
            TestingHelper.MakeSomeMoves(board2);

            board2.MakeUserMove("e1c1");

            board2.MakeUserMove("e8c8");

            Debug.WriteLine(board2.ToString());
        }
Example #5
0
        static void TestAlphaBetaParallel()
        {
            Board board = new Board();
            // TestingHelper.MakeSomeMoves(board);
            Evaluation2.Initialise();

            Stopwatch sw = new Stopwatch();
            sw.Start();
            Tuple<UInt16, int, long, int> bestMoveAndScore = AlphaBeta2.IterativeDeepeningParallel(board, Side.White);
                // AlphaBeta2.IDASParallel(board, Side.White);
              //Tuple<UInt16, int> bestMoveAndScore = AlphaBeta2.RootAlphaBetaTTParallel(board, Side.White, 7, -120, -60);
            sw.Stop();

            //Console.WriteLine("Best Move For White: {0}. Depth: {1}. Score:{2}. TIME: {3} milliseconds",
            //   board.ConvertToAlgebraicNotation(bestMoveAndScore.Item1), 7, bestMoveAndScore.Item2, sw.ElapsedMilliseconds);

            Console.WriteLine("Best Move For White: {0}. Depth: {1}. Score:{2}. TIME: {3} milliseconds",
               board.ConvertToAlgebraicNotation(bestMoveAndScore.Item1), bestMoveAndScore.Item2, bestMoveAndScore.Item4, sw.ElapsedMilliseconds);
        }
Example #6
0
        public void TestPawnPromotion()
        {
            Board board2 = new Board();
            TestingHelper.MakeSomeMoves(board2);

            board2.MakeUserMove("d2e3");

            bool success = board2.MakeUserMove("d5d4");

            success = board2.MakeUserMove("e1g1");

            success = board2.MakeUserMove("d4d3");

            success = board2.MakeUserMove("a1c1");

            success = board2.MakeUserMove("d3d2");

            success = board2.MakeUserMove("f1e1");

            success = board2.MakeUserMove("d2e1q");
        }
Example #7
0
        static void Main(string[] args)
        {
            // variables
            sbyte ownSide;
            Board board = new Board();
            Stack<BoardState> undoStack = new Stack<BoardState>();

            UInt16 move;
            Tuple<UInt16, int, long, int> moveDepthTimeAndScore;

            string userMove, filthyMindMove = "INVALID_MOVE";
            File.Delete(LogFileName);
            string guiMessage = Console.ReadLine();
            File.AppendAllText(LogFileName, "\nGUI: " + guiMessage + Environment.NewLine);

            Console.WriteLine("id name Shutranj");
            Console.WriteLine("id author Okash Khawaja");
            Console.WriteLine("uciok");

            guiMessage = Console.ReadLine();
            File.AppendAllText(LogFileName, "GUI: " + guiMessage + Environment.NewLine);

            Console.WriteLine("readyok");

            guiMessage = Console.ReadLine();
            File.AppendAllText(LogFileName, "GUI: " + guiMessage + Environment.NewLine);

            guiMessage = Console.ReadLine();
            File.AppendAllText(LogFileName, "GUI: " + guiMessage + Environment.NewLine);

            guiMessage = Console.ReadLine();
            File.AppendAllText(LogFileName, "GUI: " + guiMessage + Environment.NewLine);

            /********** this is when the game begins **************/

            guiMessage = Console.ReadLine();
            File.AppendAllText(LogFileName, "GUI: " + guiMessage + Environment.NewLine);

            if (guiMessage == "quit" || guiMessage == "stop")
            {
                return;
            }
            userMove = ParseOutLastMove(guiMessage);

            guiMessage = Console.ReadLine();
            File.AppendAllText(LogFileName, "GUI: " + guiMessage + Environment.NewLine);

            // if empty then engine is playing white so make move first
            if (String.IsNullOrWhiteSpace(userMove))
            {
                ownSide = Side.White;

                moveDepthTimeAndScore = AlphaBeta2.IDASParallel(board, ownSide);

                move = moveDepthTimeAndScore.Item1;
                if (board.MakeMove(move))
                {
                    filthyMindMove = board.ConvertToAlgebraicNotation(move);
                    File.AppendAllText(LogFileName, String.Format(
                        "Filthy Mind: {0} (Depth: {1} plies; Time: {2}ms; Score: {3}){4}", filthyMindMove,
                        moveDepthTimeAndScore.Item2, moveDepthTimeAndScore.Item3, moveDepthTimeAndScore.Item4, Environment.NewLine));
                }

                // communicate move back to gui
                Console.WriteLine(BestMoveStringFormat, filthyMindMove);
            }
            else
            {
                ownSide = Side.Black;
            }

            while (true)
            {
                guiMessage = Console.ReadLine();
                File.AppendAllText(LogFileName, "GUI: " + guiMessage + Environment.NewLine);

                if (guiMessage == "quit" || guiMessage == "stop")
                {
                    break;
                }
                userMove = ParseOutLastMove(guiMessage);

                guiMessage = Console.ReadLine();
                File.AppendAllText(LogFileName, "GUI: " + guiMessage + Environment.NewLine);

                board.MakeUserMove(userMove);

                moveDepthTimeAndScore = AlphaBeta2.IDASParallel(board, ownSide);

                move = moveDepthTimeAndScore.Item1;
                if (board.MakeMove(move))
                {
                    filthyMindMove = board.ConvertToAlgebraicNotation(move);
                    File.AppendAllText(LogFileName, String.Format(
                        "Filthy Mind: {0} (Depth: {1} plies; Time: {2}ms; Score: {3}){4}", filthyMindMove,
                        moveDepthTimeAndScore.Item2, moveDepthTimeAndScore.Item3, moveDepthTimeAndScore.Item4, Environment.NewLine));
                }

                // communicate move back to gui
                Console.WriteLine(BestMoveStringFormat, filthyMindMove);

            }
        }
Example #8
0
        private static int Quiescence(Board board, sbyte side, int alpha, int beta)
        {
            // from: http://chessprogramming.wikispaces.com/Quiescence+Search
            int standingPat = Evaluation2.EvaluateFromPerspectiveOf(board, side);

            if (standingPat >= beta)
            {
                return beta;
            }

            if (alpha < standingPat)
            {
                alpha = standingPat;
            }

            sbyte oppositeSide = (sbyte)(-1 * side);

            int movesCount;

            UInt16[] moves = board.GenerateCaptureMoves(out movesCount);
            int score;
            BoardState state;
            for (int i = 0; i < movesCount; i++)
            {
                state = board.GetBoardState();
                if (!board.MakeMove(moves[i]))
                {
                    continue;
                }
                score = -Quiescence(board, oppositeSide, -beta, -alpha);
                board.RestoreState(state);

                if (score >= beta)
                {
                    return beta;
                }
                if (score > alpha)
                {
                    alpha = score;
                }
            }
            return alpha;
        }
Example #9
0
        // a depth limited quiescence to prevent this from going on and on...
        private static int Quiescence_Limited(Board board, sbyte side, int alpha, int beta, int depthLeft)
        {
            int standingPat = Evaluation2.EvaluateFromPerspectiveOf(board, side);

            if (depthLeft == 0)
            {
                return standingPat;
            }

            if (standingPat >= beta)
            {
                return beta;
            }

            if (alpha < standingPat)
            {
                alpha = standingPat;
            }

            sbyte oppositeSide = (sbyte)(-1 * side);

            int movesCount;

            UInt16[] moves = board.GenerateCaptureMoves(out movesCount);
            int score;
            BoardState state;
            for (int i = 0; i < movesCount; i++)
            {
                state = board.GetBoardState();
                if (!board.MakeMove(moves[i]))
                {
                    continue;
                }
                score = -Quiescence_Limited(board, oppositeSide, -beta, -alpha, depthLeft - 1);
                board.RestoreState(state);

                if (score >= beta)
                {
                    return beta;
                }
                if (score > alpha)
                {
                    alpha = score;
                }
            }
            return alpha;
        }
Example #10
0
        public static Tuple<UInt16, int> RootAlphaBetaTT(Board board, sbyte side, int depth)
        {
            int movesCount;
            UInt16[] moves = board.GenerateMoves(out movesCount);

            //nodesCount = moves.Count;

            UInt16 bestMove = moves[0];
            int maxScore = Constants.NegativeInfinity;
            int score;
            sbyte oppositeSide = (sbyte)(side * -1);
            BoardState state;
            // Search search = new Search();

            for (int i = 0; i < movesCount; i++)
            {
                state = board.GetBoardState();
                if (!board.MakeMove(moves[i]))
                {
                    continue;
                }
                score = -AlphaBetaTT(board, Constants.NegativeInfinity, Constants.PositiveInfinity, (byte)(depth - 1), oppositeSide,
                    new UInt16[depth], 0);

                board.RestoreState(state);
                if (score > maxScore)
                {
                    maxScore = score;
                    bestMove = moves[i];
                }
            }
            return new Tuple<UInt16, int>(bestMove, maxScore);
        }
Example #11
0
        public static Tuple<UInt16, int> RootAlphaBetaTTParallel(Board board, sbyte side, int depth, 
            int alpha = Constants.NegativeInfinity, int beta = Constants.PositiveInfinity)
        {
            int movesCount;
            UInt16[] moves = board.GenerateMoves(out movesCount);

            UInt16 bestMove = moves[0];
            int maxScore = Constants.NegativeInfinity;
            sbyte oppositeSide = (sbyte)(side * -1);

            int[] scores = new int[movesCount];
            Board[] boards = new Board[movesCount];
            // Search[] searches = new Search[moves.Count];

            Parallel.For(0, movesCount, i =>
            {
                boards[i] = new Board(board.GetBoardState());
            });

            Parallel.For(0, movesCount, i =>
            {
                if (!boards[i].MakeMove(moves[i]))
                {
                    scores[i] = Constants.NegativeInfinity;
                    return;
                }

                scores[i] = -AlphaBetaTT(boards[i], -beta, -alpha, (byte)(depth - 1), oppositeSide,
                    new UInt16[depth], 0);

            });

            for (int i = 0; i < scores.Length; i++)
            {
                if (scores[i] > maxScore)
                {
                    maxScore = scores[i];
                    bestMove = moves[i];
                }
            }

            return new Tuple<UInt16, int>(bestMove, maxScore);
        }
Example #12
0
        public void Game6VsTitan_BadMoveLostQueen()
        {
            Board board = new Board();

            board.MakeUserMove("b1c3 ");
            board.MakeUserMove("d7d5");

            board.MakeUserMove("e2e3 ");
            board.MakeUserMove("b8c6");

            board.MakeUserMove("f1b5 ");
            board.MakeUserMove("a7a6");

            board.MakeUserMove("b5c6 ");
            board.MakeUserMove("b7c6");

            board.MakeUserMove("d2d4");
            board.MakeUserMove("e7e5");

            board.MakeUserMove("d4e5 ");
            board.MakeUserMove("d8g5");

            board.MakeUserMove("e1f1 ");
            board.MakeUserMove("g5e5");

            board.MakeUserMove("g1f3 ");
            board.MakeUserMove("e5h5");

            board.MakeUserMove("d1d4 ");
            board.MakeUserMove("c8f5");

            board.MakeUserMove("d4a4 ");
            board.MakeUserMove("f5d7");

            board.MakeUserMove("a4b3 ");
            board.MakeUserMove("a6a5");

            board.MakeUserMove("b3b7  ");
            board.MakeUserMove("a8c8");

            board.MakeUserMove("c3e2  ");
            board.MakeUserMove("f8d6");

            board.MakeUserMove("e2f4  ");
            board.MakeUserMove("h5f5");

            board.MakeUserMove("f3d4  ");
            board.MakeUserMove("f5f6 ");

            board.MakeUserMove("d4c6 ");
            board.MakeUserMove("d6f4");

            board.MakeUserMove("c6a7  ");
            board.MakeUserMove("f4e3");

            board.MakeUserMove("c1e3  ");
            board.MakeUserMove("c8d8");

            board.MakeUserMove("a1e1  ");
            board.MakeUserMove("g8e7");

            board.MakeUserMove("e3c5  ");
            board.MakeUserMove("d7e6");

            board.MakeUserMove("c5e7  ");
            board.MakeUserMove("e8e7");

            board.MakeUserMove("b7c7   ");
            board.MakeUserMove("e7e8");

            board.MakeUserMove("a7c6   ");
            board.MakeUserMove("d5d4");

            board.MakeUserMove("h1g1   ");
            board.MakeUserMove("g7g6");

            board.MakeUserMove("c2c3   ");
            board.MakeUserMove("d8a8");

            board.MakeUserMove("c7b7   ");
            board.MakeUserMove("a8d8");

            board.MakeUserMove("c6d8   ");
            board.MakeUserMove("f6d8");

            board.MakeUserMove("b7b5   ");
            board.MakeUserMove("e8f8");

            board.MakeUserMove("e1d1   ");
            board.MakeUserMove("e6a2");

            board.MakeUserMove("d1d4   ");
            board.MakeUserMove("d8c7");

            board.MakeUserMove("b5a6   ");
            board.MakeUserMove("f8g7");

            board.MakeUserMove("f2f4    ");
            board.MakeUserMove("h8d8");

            // Generate move here for white to play
            Tuple<UInt16, int> moveAndScore = AlphaBeta2.RootAlphaBetaTTParallel(board, 1, 7);
            board.MakeMove(moveAndScore.Item1);

            // following was bad move by FM
            board.MakeUserMove("d4d8");
            board.MakeUserMove("a2c4");
        }
Example #13
0
        public static Tuple<UInt16, int, long, int> IterativeDeepeningParallel(Board board, sbyte side)
        {
            // NOTE: following are dummy values to prevent compiler error.
            Tuple<UInt16, int> moveAndScore = new Tuple<UInt16, int>(0, -10000000);

            Stopwatch sw = new Stopwatch();

            int depth;

            sw.Start();
            for (depth = MinDepth; depth <= MaxDepth; depth++)
            {
                moveAndScore = RootAlphaBetaTTParallel(board, side, depth);
                if (sw.ElapsedMilliseconds >= TimeLimitInMilliseconds)
                {
                    sw.Stop();
                    break;
                }
            }

            return new Tuple<ushort, int, long, int>(moveAndScore.Item1, depth, sw.ElapsedMilliseconds, moveAndScore.Item2);
        }
Example #14
0
        public void Game7VsTitan_NotCheckmating()
        {
            Board board = new Board();

            board.MakeUserMove("d2d4  ");
            board.MakeUserMove("d7d5");

            board.MakeUserMove("c2c3  ");
            board.MakeUserMove("g8f6");

            board.MakeUserMove("g2g3  ");
            board.MakeUserMove("e7e6");

            board.MakeUserMove("c1g5  ");
            board.MakeUserMove("f8d6");

            board.MakeUserMove("e2e4 ");
            board.MakeUserMove("d5e4");

            board.MakeUserMove("b1d2  ");
            board.MakeUserMove("d6e7");

            board.MakeUserMove("d1a4  ");
            board.MakeUserMove("d8d7");

            board.MakeUserMove("a4c2  ");
            board.MakeUserMove("e8g8");

            board.MakeUserMove("f1h3  ");
            board.MakeUserMove("b8c6");

            board.MakeUserMove("g5f6  ");
            board.MakeUserMove("g7f6");

            board.MakeUserMove("c2e4  ");
            board.MakeUserMove("f6f5");

            board.MakeUserMove("e4e3   ");
            board.MakeUserMove("b7b5");

            board.MakeUserMove("h3g2   ");
            board.MakeUserMove("c8b7");

            board.MakeUserMove("g1f3   ");
            board.MakeUserMove("f7f6");

            board.MakeUserMove("f3h4   ");
            board.MakeUserMove("f8b8 ");

            board.MakeUserMove("d2b3  ");
            board.MakeUserMove("b5b4");

            board.MakeUserMove("b3c5   ");
            board.MakeUserMove("e7c5");

            board.MakeUserMove("d4c5   ");
            board.MakeUserMove("a7a5");

            board.MakeUserMove("a2a3   ");
            board.MakeUserMove("e6e5");

            board.MakeUserMove("a1d1   ");
            board.MakeUserMove("d7e6");

            board.MakeUserMove("g2d5   ");
            board.MakeUserMove("e6d5");

            board.MakeUserMove("d1d5    ");
            board.MakeUserMove("c6e7");

            board.MakeUserMove("d5d7    ");
            board.MakeUserMove("b7h1");

            board.MakeUserMove("d7e7    ");
            board.MakeUserMove("b4a3 ");

            board.MakeUserMove("e3h6    ");
            board.MakeUserMove("g8h8");

            // Generate move here for white to play
            Tuple<UInt16, int> moveAndScore = AlphaBeta2.RootAlphaBetaTT(board, 1, 6);
                // AlphaBeta2.RootAlphaBetaTTParallel(board, 1, 6);
            board.MakeMove(moveAndScore.Item1);

            // following was bad move by FM
            board.MakeUserMove("d4d8");
            board.MakeUserMove("a2c4");
        }
Example #15
0
        public void Defect2VsTitan()
        {
            Board board = new Board();

            board.MakeUserMove("e2e4");
            board.MakeUserMove("c7c6");

            board.MakeUserMove("b1c3");
            board.MakeUserMove("d7d5");

            board.MakeUserMove("e4d5");
            board.MakeUserMove("c6d5");

            board.MakeUserMove("f1b5");
            board.MakeUserMove("b8c6");

            board.MakeUserMove("d2d4");
            board.MakeUserMove("a7a6");

            board.MakeUserMove("b5c6");
            board.MakeUserMove("b7c6");

            board.MakeUserMove("a2a3");
            board.MakeUserMove("g8f6");

            board.MakeUserMove("g1e2");
            board.MakeUserMove("e7e6");

            board.MakeUserMove("e1g1");
            board.MakeUserMove("f8e7");

            board.MakeUserMove("c1g5");
            board.MakeUserMove("e8g8");

            board.MakeUserMove("d1d3");
            board.MakeUserMove("c8b7");

            board.MakeUserMove("h2h3");
            board.MakeUserMove("f8e8");

            board.MakeUserMove("a3a4");
            board.MakeUserMove("h7h6");

            board.MakeUserMove("g5f6");
            board.MakeUserMove("e7f6");

            board.MakeUserMove("c3d1");
            board.MakeUserMove("e6e5");

            board.MakeUserMove("d4e5");
            board.MakeUserMove("f6e5");
            board.MakeUserMove("c2c3");
            board.MakeUserMove("c6c5");

            board.MakeUserMove("d3c2");
            board.MakeUserMove("d5d4");

            board.MakeUserMove("c2b3");
            board.MakeUserMove("b7d5");

            board.MakeUserMove("c3c4");
            board.MakeUserMove("a8b8");

            board.MakeUserMove("b3d3");
            board.MakeUserMove("d5e4");

            board.MakeUserMove("d3d2");
            board.MakeUserMove("d8d6");

            board.MakeUserMove("f2f4");
            board.MakeUserMove("d6g6");

            board.MakeUserMove("g2g4");
            board.MakeUserMove("e5d6");
            board.MakeUserMove("a1a3");
            board.MakeUserMove("g6e6");

            board.MakeUserMove("b2b3");
            board.MakeUserMove("e4c6");

            board.MakeUserMove("e2g3");
            board.MakeUserMove("f7f6");

            board.MakeUserMove("d2c1");
            board.MakeUserMove("a6a5");

            board.MakeUserMove("c1d2");
            board.MakeUserMove("d6c7");

            board.MakeUserMove("d2c1");
            board.MakeUserMove("c7d6");

            board.MakeUserMove("c1d2");
            board.MakeUserMove("b8a8");

            board.MakeUserMove("a3a1");
            board.MakeUserMove("g7g6");
            board.MakeUserMove("d2c2");
            board.MakeUserMove("e6f7");

            board.MakeUserMove("c2d2");
            board.MakeUserMove("f7b7");

            board.MakeUserMove("d2b2");
            board.MakeUserMove("b7d7");

            // Generate move here for white to play
            Tuple<UInt16, int> moveAndScore = AlphaBeta2.RootAlphaBetaTTParallel(board, 1, 6);
            board.MakeMove(moveAndScore.Item1);
        }
Example #16
0
        static void Main(string[] args)
        {
            // variables
            sbyte ownSide;
            Board board = new Board();
            Stack<BoardState> undoStack = new Stack<BoardState>();

            // int depth = 6;
            UInt16 move;
            Tuple<UInt16, int, long, int> moveDepthTimeAndScore;

            string opponentMoveString;

            Console.WriteLine("Filthy Mind Chess");
            Console.WriteLine();

            /*********** Input opponent side ************/
            while (true)
            {
                Console.Write("Choose your side (w/b): ");
                char opponentSideChar = Console.ReadKey().KeyChar;
                Console.WriteLine();
                if (opponentSideChar == 'w')
                {
                    ownSide = Side.Black;
                    break;
                }
                else if (opponentSideChar == 'b')
                {
                    ownSide = Side.White;
                    break;
                }
                else
                {
                    Console.WriteLine("Invalid side.");
                }
            }
            /*************** End of input opponent side ******************/

            /*************** Start game *******************/
            Console.WriteLine("Start playing.");
            Console.WriteLine();
            if (ownSide == Side.White)
            {
                moveDepthTimeAndScore = AlphaBeta2.IDASParallel(board, ownSide);
                    // AlphaBeta2.IterativeDeepeningParallel(board, ownSide);
                    // AlphaBeta2.RootAlphaBetaTTParallel(board, ownSide, depth).Item1;
                move = moveDepthTimeAndScore.Item1;
                if (board.MakeMove(move))
                {
                    Console.WriteLine("Filthy Mind: {0} (Depth: {1} plies; Time: {2}ms; Score: {3})", board.ConvertToAlgebraicNotation(move),
                        moveDepthTimeAndScore.Item2, moveDepthTimeAndScore.Item3, moveDepthTimeAndScore.Item4);
                }
            }
            while (true)
            {
                Console.Write("You: ");
                opponentMoveString = Console.ReadLine();
                if (opponentMoveString.ToLower() == "exit")
                {
                    break;
                }

                if (opponentMoveString.ToLower() == "fen")
                {
                    Console.WriteLine("Board Position: {0}", board.ToString());
                    continue;
                }

                if (opponentMoveString.Trim().ToLower() == "undo")
                {
                    if (undoStack.Count > 0)
                    {
                        board.RestoreState(undoStack.Pop());
                        Console.WriteLine("Undid last move.");
                    }
                    else
                    {
                        Console.WriteLine("Nothing to undo!");
                    }
                    continue;
                }

                try
                {
                    undoStack.Push(board.GetBoardState());

                    if (!board.MakeUserMove(opponentMoveString))
                    {
                        Console.WriteLine("Failed to make move. Try again.");
                        undoStack.Pop();
                        continue;
                    }
                }
                catch (Exception ex)
                {
                    undoStack.Pop();
                    Console.WriteLine("ERROR: {0}", ex.Message);
                    continue;
                }
                // make move for own side
                moveDepthTimeAndScore = AlphaBeta2.IDASParallel(board, ownSide);
                    // AlphaBeta2.IterativeDeepeningParallel(board, ownSide);
                    // AlphaBeta2.RootAlphaBetaTTParallel(board, ownSide, depth).Item1;

                move = moveDepthTimeAndScore.Item1;
                if (board.MakeMove(move))
                {
                    Console.WriteLine("Filthy Mind: {0} (Depth: {1} plies; Time: {2}ms; Score: {3})", board.ConvertToAlgebraicNotation(move),
                        moveDepthTimeAndScore.Item2, moveDepthTimeAndScore.Item3, moveDepthTimeAndScore.Item4);
                }
            }
            Console.WriteLine("End of the game. Press any key to close the window.");
            Console.ReadKey();
            /*************** End of game ******************/
        }
Example #17
0
        private static int EvaluateForWhite(Board board)
        {
            int score = 0;

            // pawns
            byte[] pieceIndices = BitHelper.GetSetBitIndexes2(board.PieceToBitboard[Constants.WhitePawnNumber + 6]);
            int opponentPiecesCount = BitHelper.GetNumberOfSetBits(board.PieceToBitboard[Constants.BlackPawnNumber + 6]);
            score += CalculateScore(pieceIndices, opponentPiecesCount, PawnValue, WhitePawnSquareTable);

            // rooks
            pieceIndices = BitHelper.GetSetBitIndexes2(board.PieceToBitboard[Constants.WhiteRookNumber + 6]);
            opponentPiecesCount = BitHelper.GetNumberOfSetBits(board.PieceToBitboard[Constants.BlackRookNumber + 6]);
            score += CalculateScore(pieceIndices, opponentPiecesCount, RookValue, WhiteRookSquareTable);

            // knights
            pieceIndices = BitHelper.GetSetBitIndexes2(board.PieceToBitboard[Constants.WhiteKnightNumber + 6]);
            opponentPiecesCount = BitHelper.GetNumberOfSetBits(board.PieceToBitboard[Constants.BlackKnightNumber + 6]);
            score += CalculateScore(pieceIndices, opponentPiecesCount, KnightValue, WhiteKnightSquareTable);

            // bishops
            pieceIndices = BitHelper.GetSetBitIndexes2(board.PieceToBitboard[Constants.WhiteBishopNumber + 6]);
            opponentPiecesCount = BitHelper.GetNumberOfSetBits(board.PieceToBitboard[Constants.BlackBishopNumber + 6]);
            score += CalculateScore(pieceIndices, opponentPiecesCount, BishopValue, WhiteBishopSquareTable);

            // queens
            pieceIndices = BitHelper.GetSetBitIndexes2(board.PieceToBitboard[Constants.WhiteQueenNumber + 6]);
            opponentPiecesCount = BitHelper.GetNumberOfSetBits(board.PieceToBitboard[Constants.BlackQueenNumber + 6]);
            score += CalculateScore(pieceIndices, opponentPiecesCount, QueenValue, WhiteQueenSquareTable);

            // king
            int[] kingSquareTable = (board.GetGameStage() == Constants.GameStage_Middle) ? WhiteKingMiddleGameSquareTable :
                WhiteKingEndGameSquareTable;
            pieceIndices = BitHelper.GetSetBitIndexes2(board.PieceToBitboard[Constants.WhiteKingNumber + 6]);
            opponentPiecesCount = BitHelper.GetNumberOfSetBits(board.PieceToBitboard[Constants.BlackKingNumber + 6]);
            score += CalculateScore(pieceIndices, opponentPiecesCount, KingValue, kingSquareTable);

            return score;
        }
Example #18
0
 public static int EvaluateFromPerspectiveOf(Board board, int side)
 {
     if (side == Side.White)
     {
         return EvaluateForWhite(board);
     }
     else
     {
         return EvaluateForBlack(board);
     }
 }
Example #19
0
        public void WhenPlayingAgainstHammad()
        {
            Board board = new Board();

            board.MakeUserMove("d2d4");
            board.MakeUserMove("g8f6");

            board.MakeUserMove("g1f3");
            board.MakeUserMove("d7d5");

            board.MakeUserMove("b1c3");
            board.MakeUserMove("b8c6");

            board.MakeUserMove("c1g5");
            board.MakeUserMove("f6e4");

            board.MakeUserMove("d1d2");
            board.MakeUserMove("e4d2");

            board.MakeUserMove("e1d2");
            board.MakeUserMove("h7h6");

            board.MakeUserMove("g5f4");
            board.MakeUserMove("e7e6");

            board.MakeUserMove("f4e5");
            board.MakeUserMove("f8b4");

            // now do search
            Tuple<UInt16, int> moveAndScore = AlphaBeta2.RootAlphaBetaTTParallel(board, -1, 6);
            board.MakeMove(moveAndScore.Item1);
        }
Example #20
0
        public void TestQuiescenceDepth()
        {
            Board board = new Board();

            // Generate move here for white to play
            Tuple<UInt16, int> moveAndScore = AlphaBeta2.RootAlphaBetaTT(board, 1, 6);
            // AlphaBeta2.RootAlphaBetaTTParallel(board, 1, 6);
            board.MakeMove(moveAndScore.Item1);

            // following was bad move by FM
            board.MakeUserMove("d4d8");
            board.MakeUserMove("a2c4");
        }
Example #21
0
        // Iterative Deepening Aspiration Search Parallel
        public static Tuple<UInt16, int, long, int> IDASParallel(Board board, sbyte side)
        {
            // threshold value of one-third of a pawn value (100) based on http://www.frayn.net/beowulf/theory.html#aspiration
            int threshold = 30;

            // NOTE: following are dummy values to prevent compiler error.
            Tuple<UInt16, int> moveAndScore = new Tuple<UInt16, int>(0, -10000000);

            Stopwatch sw = new Stopwatch();

            int depth, depthSearched = 0;

            moveAndScore = RootAlphaBetaTTParallel(board, side, MinDepth, Constants.NegativeInfinity, Constants.PositiveInfinity);
            int best = moveAndScore.Item2;
            sw.Start();
            for (depth = MinDepth + 1; depth <= MaxDepth; depth++)
            {
                moveAndScore = RootAlphaBetaTTParallel(board, side, depth, best - threshold, best + threshold);
                if (moveAndScore.Item2 <= (best - threshold)) // failed low
                {
                    moveAndScore = RootAlphaBetaTTParallel(board, side, depth, Constants.NegativeInfinity, moveAndScore.Item2);
                }
                else if (moveAndScore.Item2 >= (best + threshold)) // failed high
                {
                    moveAndScore = RootAlphaBetaTTParallel(board, side, depth, moveAndScore.Item2, Constants.PositiveInfinity);
                }
                //else
                //{
                best = moveAndScore.Item2;
                //}
                depthSearched = depth;
                if (sw.ElapsedMilliseconds >= TimeLimitInMilliseconds)
                {
                    sw.Stop();
                    break;
                }
            }

            return new Tuple<ushort, int, long, int>(moveAndScore.Item1, depthSearched, sw.ElapsedMilliseconds, best);
        }
Example #22
0
        public void Defect3VsTitan_Quiesc()
        {
            Board board = new Board();

            board.MakeUserMove("g1f3");
            board.MakeUserMove("g8f6");

            board.MakeUserMove("d2d4");
            board.MakeUserMove("e7e6");

            board.MakeUserMove("c1g5");
            board.MakeUserMove("c7c5");

            board.MakeUserMove("b1c3");
            board.MakeUserMove("c5d4");

            board.MakeUserMove("f3d4");
            board.MakeUserMove("e6e5");

            board.MakeUserMove("d4b3");
            board.MakeUserMove("f8e7");

            board.MakeUserMove("g5f6");
            board.MakeUserMove("e7f6");

            board.MakeUserMove("e2e4");
            board.MakeUserMove("e8g8");

            board.MakeUserMove("f1c4");
            board.MakeUserMove("b8c6");

            board.MakeUserMove("e1g1");
            board.MakeUserMove("d7d6");

            board.MakeUserMove("f1e1");
            board.MakeUserMove("f6g5");

            board.MakeUserMove("d1d3");
            bool success = board.MakeUserMove("d1d3");

            // Generate move here for white to play
            Tuple<UInt16, int> moveAndScore = AlphaBeta2.RootAlphaBetaTTParallel(board, 1, 6);
            board.MakeMove(moveAndScore.Item1);
        }
Example #23
0
        public static int AlphaBetaTT(Board board, int alpha, int beta, byte depthLeft, sbyte side, UInt16[] killers, int level)
        {
            int score;
            TranspositionTableEntry entry = transpositionTable.Retrieve(board.ZobristHash);

            if (entry.IsValid() && (TranspositionTableEntryHelper.GetDepthSearched(entry.Data) >= depthLeft))
            {
                if (TranspositionTableEntryHelper.GetEntryType(entry.Data) == TranspositionTableEntryHelper.EntryTypeExactValue)
                {
                    return TranspositionTableEntryHelper.GetScore(entry.Data);
                }
                if ((TranspositionTableEntryHelper.GetEntryType(entry.Data) == TranspositionTableEntryHelper.EntryTypeLowerBound) &&
                    (TranspositionTableEntryHelper.GetScore(entry.Data) > alpha))
                {
                    alpha = TranspositionTableEntryHelper.GetScore(entry.Data);
                }
                else if ((TranspositionTableEntryHelper.GetEntryType(entry.Data) == TranspositionTableEntryHelper.EntryTypeUpperBound) &&
                    (TranspositionTableEntryHelper.GetScore(entry.Data) < beta))
                {
                    beta = TranspositionTableEntryHelper.GetScore(entry.Data);
                }
                if (alpha >= beta)
                {
                    return TranspositionTableEntryHelper.GetScore(entry.Data);
                }
            }
            if (depthLeft == 0)
            {
                score = Quiescence_Limited(board, side, alpha, beta, (level + 1) % 2); // the last arg ensures that quiescence evaluates opponent's move as the last one.
                    // Quiescence(board, side, alpha, beta);
                    // Evaluation2.EvaluateFromPerspectiveOf(board, side);

                if (score <= alpha)
                {
                    transpositionTable.Add(new TranspositionTableEntry(board.ZobristHash,
                        TranspositionTableEntryHelper.ComposeData(score, TranspositionTableEntryHelper.InvalidMove,
                            depthLeft, TranspositionTableEntryHelper.EntryTypeLowerBound)));
                }
                else if (score >= beta)
                {
                    transpositionTable.Add(new TranspositionTableEntry(board.ZobristHash,
                        TranspositionTableEntryHelper.ComposeData(score, TranspositionTableEntryHelper.InvalidMove,
                            depthLeft, TranspositionTableEntryHelper.EntryTypeUpperBound)));
                }
                else
                {
                    transpositionTable.Add(new TranspositionTableEntry(board.ZobristHash,
                        TranspositionTableEntryHelper.ComposeData(score, TranspositionTableEntryHelper.InvalidMove,
                            depthLeft, TranspositionTableEntryHelper.EntryTypeExactValue)));
                }

                return score;
            }

            int movesCount;
            UInt16[] moves = board.GenerateMoves(out movesCount);

            #region Move Ordering
            // this is the index with which a good move will be swapped with...
            int indexToSwapWith = 0;

            /*************** Transposition Table Reordering **************/
            // NOTE (17 Jul 2013): There appears to be no gain from transposition table re-ordering, therefore
            //              commenting it out.

            //if (entry.IsValid())
            //{
            //    UInt16 bestMoveFromTable = TranspositionTableEntryHelper.GetBestMove(entry.Data);
            //    if (bestMoveFromTable != TranspositionTableEntryHelper.InvalidMove)
            //    {
            //        for (int i = 0; i < movesCount; i++)
            //        {
            //            if (moves[i] == bestMoveFromTable)
            //            {
            //                // swap...
            //                UInt16 temp = moves[i];
            //                moves[i] = moves[indexToSwapWith];
            //                moves[indexToSwapWith] = temp;
            //                indexToSwapWith++;
            //                break;
            //            }
            //        }
            //    }
            //}
            /*************** End of Transposition Table Reordering **************/

            /*************** Killer Heuristic Reordering *****************/
            if (killers[level] != 0)
            {
                for (int i = 0; i < movesCount; i++)
                {
                    if (killers[level] == moves[i])
                    {
                        // if killer move found then swap that with the first move.
                        UInt16 temp = moves[i];
                        moves[i] = moves[indexToSwapWith];
                        moves[indexToSwapWith] = temp;
                        indexToSwapWith++;
                        break;
                    }
                }
            }
            // set killer for next level to 0
            killers[level + 1] = 0;
            /*************** End of Killer Heuristic Reordering *****************/

            #endregion
            // NOTE: diluting negative infinity by level so that the farther away the checkmate is from current
            //          board position the lower will be the score. this is to get the engine to checkmate opponent
            //          as soon as possible rather than wasting time in capture or other moves which ultimately lead to
            //          checkmate but are not the fastest route to checkmakte.
            int bestScore = Constants.NegativeInfinity + level;
            UInt16 bestMove = TranspositionTableEntryHelper.InvalidMove;

            BoardState state;
            sbyte oppositeSide = (sbyte)(-1 * side);

            for (int i = 0; i < movesCount; i++)
            {
                state = board.GetBoardState();
                if (!board.MakeMove(moves[i]))
                {
                    continue;
                }
                score = -AlphaBetaTT(board, -beta, -alpha, (byte)(depthLeft - 1), oppositeSide, killers, level + 1);
                board.RestoreState(state);

                if (score > bestScore)
                {
                    bestScore = score;
                    bestMove = moves[i];
                }
                if (bestScore > alpha)
                {
                    alpha = bestScore;
                }
                if (bestScore >= beta)
                {
                    // beta-cutoff, therefore update killer for this level
                    killers[level] = moves[i];
                    break;
                }
            }

            // following nested ifs check for stalemate.
            if (bestScore == (Constants.NegativeInfinity + level))
            {
                if (!board.IsInCheck(side))
                {
                    bestScore = Constants.DrawScore;
                }
            }

            if (bestScore <= alpha) // lower bound value
            {
                transpositionTable.Add(new TranspositionTableEntry(board.ZobristHash,
                        TranspositionTableEntryHelper.ComposeData(bestScore, bestMove,
                            depthLeft, TranspositionTableEntryHelper.EntryTypeLowerBound)));
            }
            else if (bestScore >= beta) // upper bound value
            {
                transpositionTable.Add(new TranspositionTableEntry(board.ZobristHash,
                        TranspositionTableEntryHelper.ComposeData(bestScore, bestMove,
                            depthLeft, TranspositionTableEntryHelper.EntryTypeUpperBound)));
            }
            else // true minimax value
            {
                transpositionTable.Add(new TranspositionTableEntry(board.ZobristHash,
                        TranspositionTableEntryHelper.ComposeData(bestScore, bestMove,
                            depthLeft, TranspositionTableEntryHelper.EntryTypeExactValue)));
            }

            return bestScore;
        }
Example #24
0
 public static Tuple<UInt16, int> IterativeDeepening(Board board, sbyte side, int depth)
 {
     // NOTE: following are dummy values to prevent compiler error.
     Tuple<UInt16, int> moveAndScore = new Tuple<UInt16, int>(0, -10000000);
     for (int i = 2; i <= depth; i++)
     {
         moveAndScore = RootAlphaBetaTT(board, side, i);
     }
     return moveAndScore;
 }
Example #25
0
        public static void MakeSomeMoves(Board board)
        {
            List<UInt64> hashesSoFar = new List<UInt64>();
            hashesSoFar.Add(board.ZobristHash);
            bool success;

            board.MakeUserMove("e2e4");

            if (hashesSoFar.Contains(board.ZobristHash))
            {
                throw new InvalidOperationException("Hash Already Included!!");
            }
            hashesSoFar.Add(board.ZobristHash);

            string fenString = board.ToString();
            Debug.WriteLine(fenString);

            board.MakeUserMove("c7c5");
            if (hashesSoFar.Contains(board.ZobristHash))
            {
                throw new InvalidOperationException("Hash Already Included!!");
            }
            hashesSoFar.Add(board.ZobristHash);

            fenString = board.ToString();
            Debug.WriteLine(fenString);

            board.MakeUserMove("g1f3");
            if (hashesSoFar.Contains(board.ZobristHash))
            {
                throw new InvalidOperationException("Hash Already Included!!");
            }
            hashesSoFar.Add(board.ZobristHash);

            fenString = board.ToString();
            Debug.WriteLine(fenString);

            board.MakeUserMove("b8c6");
            if (hashesSoFar.Contains(board.ZobristHash))
            {
                throw new InvalidOperationException("Hash Already Included!!");
            }
            hashesSoFar.Add(board.ZobristHash);

            fenString = board.ToString();
            Debug.WriteLine(fenString);

            board.MakeUserMove("d2d4");
            if (hashesSoFar.Contains(board.ZobristHash))
            {
                throw new InvalidOperationException("Hash Already Included!!");
            }
            hashesSoFar.Add(board.ZobristHash);

            fenString = board.ToString();
            Debug.WriteLine(fenString);

            board.MakeUserMove("e7e6");
            if (hashesSoFar.Contains(board.ZobristHash))
            {
                throw new InvalidOperationException("Hash Already Included!!");
            }
            hashesSoFar.Add(board.ZobristHash);

            fenString = board.ToString();
            Debug.WriteLine(fenString);

            board.MakeUserMove("c1e3");
            if (hashesSoFar.Contains(board.ZobristHash))
            {
                throw new InvalidOperationException("Hash Already Included!!");
            }
            hashesSoFar.Add(board.ZobristHash);

            fenString = board.ToString();
            Debug.WriteLine(fenString);

            board.MakeUserMove("g7g6");
            if (hashesSoFar.Contains(board.ZobristHash))
            {
                throw new InvalidOperationException("Hash Already Included!!");
            }
            hashesSoFar.Add(board.ZobristHash);

            fenString = board.ToString();
            Debug.WriteLine(fenString);

            board.MakeUserMove("d4c5");
            if (hashesSoFar.Contains(board.ZobristHash))
            {
                throw new InvalidOperationException("Hash Already Included!!");
            }
            hashesSoFar.Add(board.ZobristHash);

            fenString = board.ToString();
            Debug.WriteLine(fenString);

            board.MakeUserMove("f8g7");
            if (hashesSoFar.Contains(board.ZobristHash))
            {
                throw new InvalidOperationException("Hash Already Included!!");
            }
            hashesSoFar.Add(board.ZobristHash);

            board.MakeUserMove("f1c4");
            if (hashesSoFar.Contains(board.ZobristHash))
            {
                throw new InvalidOperationException("Hash Already Included!!");
            }
            hashesSoFar.Add(board.ZobristHash);

            board.MakeUserMove("g8f6");
            if (hashesSoFar.Contains(board.ZobristHash))
            {
                throw new InvalidOperationException("Hash Already Included!!");
            }
            hashesSoFar.Add(board.ZobristHash);

            board.MakeUserMove("b1c3");
            if (hashesSoFar.Contains(board.ZobristHash))
            {
                throw new InvalidOperationException("Hash Already Included!!");
            }
            hashesSoFar.Add(board.ZobristHash);

            board.MakeUserMove("b7b6");
            if (hashesSoFar.Contains(board.ZobristHash))
            {
                throw new InvalidOperationException("Hash Already Included!!");
            }
            hashesSoFar.Add(board.ZobristHash);

            board.MakeUserMove("d1d2");
            if (hashesSoFar.Contains(board.ZobristHash))
            {
                throw new InvalidOperationException("Hash Already Included!!");
            }
            hashesSoFar.Add(board.ZobristHash);

            board.MakeUserMove("c8b7");

            board.MakeUserMove("e3f4");
            if (hashesSoFar.Contains(board.ZobristHash))
            {
                throw new InvalidOperationException("Hash Already Included!!");
            }
            hashesSoFar.Add(board.ZobristHash);

            fenString = board.ToString();
            Debug.WriteLine(fenString);

            success = board.MakeUserMove("d8e7");
            if (hashesSoFar.Contains(board.ZobristHash))
            {
                throw new InvalidOperationException("Hash Already Included!!");
            }
            hashesSoFar.Add(board.ZobristHash);

            success = board.MakeUserMove("e4e5");
            if (hashesSoFar.Contains(board.ZobristHash))
            {
                throw new InvalidOperationException("Hash Already Included!!");
            }
            hashesSoFar.Add(board.ZobristHash);

            success = board.MakeUserMove("d7d5");
            if (hashesSoFar.Contains(board.ZobristHash))
            {
                throw new InvalidOperationException("Hash Already Included!!");
            }
            hashesSoFar.Add(board.ZobristHash);

            fenString = board.ToString();
            Debug.WriteLine(fenString);
        }
Example #26
0
        static void Main(string[] args)
        {
            // variables
            sbyte opponentSide, ownSide;
            Board board = new Board();
            Move move;
            int depth = 4;
            string opponentMoveString;

            Console.WriteLine("Filthy Mind Chess");
            Console.WriteLine();

            /*********** Input opponent side ************/
            while (true)
            {
                Console.Write("Choose your side (w/b): ");
                char opponentSideChar = Console.ReadKey().KeyChar;
                Console.WriteLine();
                if (opponentSideChar == 'w')
                {
                    opponentSide = Side.White;
                    ownSide = Side.Black;
                    break;
                }
                else if (opponentSideChar == 'b')
                {
                    opponentSide = Side.Black;
                    ownSide = Side.White;
                    break;
                }
                else
                {
                    Console.WriteLine("Invalid side.");
                }
            }
            /*************** End of input opponent side ******************/

            /*************** Start game *******************/
            Console.WriteLine("Start playing.");
            Console.WriteLine();
            if (ownSide == Side.White)
            {
                move = Search.RootAlphaBetaParallel(board, ownSide, depth).Item1;
                if (board.MakeMove(move))
                {
                    Console.WriteLine("Filthy Mind: {0}", move.ToString());
                }
            }
            while (true)
            {
                Console.Write("You: ");
                opponentMoveString = Console.ReadLine();
                if (opponentMoveString.ToLower() == "exit")
                {
                    break;
                }
                try
                {
                    move = new Move(opponentSide, opponentMoveString);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("ERROR: {0}", ex.Message);
                    continue;
                }
                if (!board.MakeMove(move))
                {
                    Console.WriteLine("Failed to make move. Try again.");
                    continue;
                }
                // make move for own side
                move = Search.RootAlphaBetaParallel(board, ownSide, depth).Item1;
                if (board.MakeMove(move))
                {
                    Console.WriteLine("Filthy Mind: {0}", move.ToString());
                }
            }
            Console.WriteLine("End of the game. Press any key to close the window.");
            Console.ReadKey();
            /*************** End of game ******************/
        }