예제 #1
0
 private static void GenerateValidMovesKing(Piece piece, Board board, byte srcPosition)
 {
     if (piece == null)
     {
         return;
     }
     for (byte index = 0; (int)index < (int)MoveArrays.KingTotalMoves[(int)srcPosition]; ++index)
     {
         byte move = MoveArrays.KingMoves[(int)srcPosition].Moves[(int)index];
         if (piece.PieceColor == ChessPieceColor.White)
         {
             if (board.BlackAttackBoard[(int)move])
             {
                 board.WhiteAttackBoard[(int)move] = true;
                 continue;
             }
         }
         else if (board.WhiteAttackBoard[(int)move])
         {
             board.BlackAttackBoard[(int)move] = true;
             continue;
         }
         PieceValidMoves.AnalyzeMove(board, move, piece);
     }
 }
예제 #2
0
 private static void CheckValidMovesPawn(List <byte> moves, Piece pcMoving, byte srcPosition, Board board, byte count)
 {
     for (byte index = 0; (int)index < (int)count; ++index)
     {
         byte move = moves[(int)index];
         if ((int)move % 8 != (int)srcPosition % 8)
         {
             PieceValidMoves.AnalyzeMovePawn(board, move, pcMoving);
             if (pcMoving.PieceColor == ChessPieceColor.White)
             {
                 board.WhiteAttackBoard[(int)move] = true;
             }
             else
             {
                 board.BlackAttackBoard[(int)move] = true;
             }
         }
         else
         {
             if (board.Squares[(int)move].Piece != null)
             {
                 break;
             }
             pcMoving.ValidMoves.Push(move);
         }
     }
 }
예제 #3
0
        private static ResultBoards GetSortValidMoves(Board examineBoard)
        {
            ResultBoards resultBoards = new ResultBoards()
            {
                Positions = new List <Board>(30)
            };

            Search.piecesRemaining = 0;
            for (byte srcPosition = 0; (int)srcPosition < 64; ++srcPosition)
            {
                Square square = examineBoard.Squares[(int)srcPosition];
                if (square.Piece != null)
                {
                    ++Search.piecesRemaining;
                    if (square.Piece.PieceColor == examineBoard.WhoseMove)
                    {
                        foreach (byte validMove in square.Piece.ValidMoves)
                        {
                            Board board = examineBoard.FastCopy();
                            Board.MovePiece(board, srcPosition, validMove, ChessPieceType.Queen);
                            PieceValidMoves.GenerateValidMoves(board);
                            if ((!board.WhiteCheck || examineBoard.WhoseMove != ChessPieceColor.White) && (!board.BlackCheck || examineBoard.WhoseMove != ChessPieceColor.Black))
                            {
                                Evaluation.EvaluateBoardScore(board);
                                board.Score = Search.SideToMoveScore(board.Score, board.WhoseMove);
                                resultBoards.Positions.Add(board);
                            }
                        }
                    }
                }
            }
            resultBoards.Positions.Sort(new Comparison <Board>(Search.Sort));
            return(resultBoards);
        }
예제 #4
0
        private static ResultBoards GetPossibleBoards(ChessPieceColor movingSide, Board examineBoard)
        {
            //We are going to store our result boards here
            resultBoards = new ResultBoards
            {
                Positions = new List <Board>()
            };

            for (byte x = 0; x < 64; x++)
            {
                Square sqr = examineBoard.Squares[x];

                //Make sure there is a piece on the square
                if (sqr.Piece == null)
                {
                    continue;
                }

                //Make sure the color is the same color as the one we are moving.
                if (sqr.Piece.PieceColor != movingSide)
                {
                    continue;
                }

                //For each valid move for this piece
                foreach (byte dst in sqr.Piece.ValidMoves)
                {
                    //We make copies of the board and move so that we can move it without effecting the parent board
                    Board board = examineBoard.FastCopy();

                    //Make move so we can examine it
                    Board.MovePiece(board, x, dst, ChessPieceType.Queen);

                    //We Generate Valid Moves for Board
                    PieceValidMoves.GenerateValidMoves(board);


                    if (board.BlackCheck && movingSide == ChessPieceColor.Black)
                    {
                        continue;
                    }

                    if (board.WhiteCheck && movingSide == ChessPieceColor.White)
                    {
                        continue;
                    }

                    //We calculate the board score
                    Evaluation.EvaluateBoardScore(board);

                    //Invert Score to support Negamax
                    board.Score = SideToMoveScore(board.Score, GetOppositeColor(movingSide));

                    resultBoards.Positions.Add(board);
                }
            }

            return(resultBoards);
        }
예제 #5
0
        internal static bool SearchForMate(ChessPieceColor movingSide, Board examineBoard, ref bool blackMate, ref bool whiteMate, ref bool staleMate)
        {
            bool flag1 = false;
            bool flag2 = false;

            for (byte srcPosition = 0; (int)srcPosition < 64; ++srcPosition)
            {
                Square square = examineBoard.Squares[(int)srcPosition];
                if (square.Piece != null && square.Piece.PieceColor == movingSide)
                {
                    foreach (byte validMove in square.Piece.ValidMoves)
                    {
                        Board board = examineBoard.FastCopy();
                        Board.MovePiece(board, srcPosition, validMove, ChessPieceType.Queen);
                        PieceValidMoves.GenerateValidMoves(board);
                        if (!board.BlackCheck)
                        {
                            flag1 = true;
                        }
                        else if (movingSide == ChessPieceColor.Black)
                        {
                            continue;
                        }
                        if (!board.WhiteCheck)
                        {
                            flag2 = true;
                        }
                    }
                }
            }
            if (!flag1)
            {
                if (examineBoard.BlackCheck)
                {
                    blackMate = true;
                    return(true);
                }
                if (!examineBoard.WhiteMate && movingSide != ChessPieceColor.White)
                {
                    staleMate = true;
                    return(true);
                }
            }
            if (!flag2)
            {
                if (examineBoard.WhiteCheck)
                {
                    whiteMate = true;
                    return(true);
                }
                if (!examineBoard.BlackMate && movingSide != ChessPieceColor.Black)
                {
                    staleMate = true;
                    return(true);
                }
            }
            return(false);
        }
예제 #6
0
 public void InitiateBoard(string fen)
 {
     this.ChessBoard = new Board(fen);
     if (string.IsNullOrEmpty(fen))
     {
         return;
     }
     PieceValidMoves.GenerateValidMoves(this.ChessBoard);
     Evaluation.EvaluateBoardScore(this.ChessBoard);
 }
예제 #7
0
파일: Engine.cs 프로젝트: viper25/ChessCore
        public void InitiateBoard(string fen)
        {
            ChessBoard = new Board(fen);

            if (!String.IsNullOrEmpty(fen))
            {
                PieceValidMoves.GenerateValidMoves(ChessBoard);
                Evaluation.EvaluateBoardScore(ChessBoard);
            }
        }
예제 #8
0
파일: Engine.cs 프로젝트: viper25/ChessCore
        public bool MovePiece(byte srcPosition, byte dstPosition)
        {
            Piece piece = ChessBoard.Squares[srcPosition].Piece;

            PreviousChessBoard = new Board(ChessBoard);
            UndoChessBoard     = new Board(ChessBoard);
            UndoGameBook       = new List <OpeningMove>(CurrentGameBook);

            Board.MovePiece(ChessBoard, srcPosition, dstPosition, PromoteToPieceType);

            ChessBoard.LastMove.GeneratePGNString(ChessBoard);

            PieceValidMoves.GenerateValidMoves(ChessBoard);
            Evaluation.EvaluateBoardScore(ChessBoard);

            //If there is a check in place, check if this is still true;
            if (piece.PieceColor == ChessPieceColor.White)
            {
                if (ChessBoard.WhiteCheck)
                {
                    //Invalid Move
                    ChessBoard = new Board(PreviousChessBoard);
                    PieceValidMoves.GenerateValidMoves(ChessBoard);
                    return(false);
                }
            }
            else if (piece.PieceColor == ChessPieceColor.Black)
            {
                if (ChessBoard.BlackCheck)
                {
                    //Invalid Move
                    ChessBoard = new Board(PreviousChessBoard);
                    PieceValidMoves.GenerateValidMoves(ChessBoard);
                    return(false);
                }
            }

            MoveHistory.Push(ChessBoard.LastMove);
            FileIO.SaveCurrentGameMove(ChessBoard, PreviousChessBoard, CurrentGameBook, ChessBoard.LastMove);

            CheckForMate(WhoseMove, ref ChessBoard);
            PieceTakenAdd(ChessBoard.LastMove);

            if (ChessBoard.WhiteMate || ChessBoard.BlackMate)
            {
                LastMove.PgnMove += "#";
            }
            else if (ChessBoard.WhiteCheck || ChessBoard.BlackCheck)
            {
                LastMove.PgnMove += "+";
            }

            return(true);
        }
예제 #9
0
        public void AiPonderMove(BackgroundWorker worker)
        {
            this.Thinking      = true;
            this.NodesSearched = 0;
            ResultBoards resultBoards = new ResultBoards();

            resultBoards.Positions = new List <Board>();
            if (ChessEngine.Engine.Engine.CheckForMate(this.WhoseMove, ref this.ChessBoard))
            {
                this.Thinking = false;
            }
            else
            {
                MoveContent bestMove = new MoveContent();
                if ((!ChessEngine.Engine.Engine.FindPlayBookMove(ref bestMove, this.ChessBoard, (IEnumerable <OpeningMove>) this.OpeningBook) || (int)this.ChessBoard.FiftyMove > 45 || (int)this.ChessBoard.RepeatedMove >= 2) && (!ChessEngine.Engine.Engine.FindPlayBookMove(ref bestMove, this.ChessBoard, (IEnumerable <OpeningMove>) this.CurrentGameBook) || (int)this.ChessBoard.FiftyMove > 45 || (int)this.ChessBoard.RepeatedMove >= 2))
                {
                    bestMove = Search.IterativeSearch(this.ChessBoard, this.PlyDepthSearched, ref this.NodesSearched, ref this.NodesQuiessence, ref this.pvLine, worker, ref this.PlyDepthReached, ref this.RootMovesSearched, this.CurrentGameBook);
                }
                this.PreviousChessBoard = new Board(this.ChessBoard);
                this.RootMovesSearched  = (byte)resultBoards.Positions.Count;
                Board.MovePiece(this.ChessBoard, bestMove.MovingPiecePrimary.SrcPosition, bestMove.MovingPiecePrimary.DstPosition, ChessPieceType.Queen);
                this.ChessBoard.LastMove.GeneratePGNString(this.ChessBoard);
                for (byte index = 0; (int)index < 64; ++index)
                {
                    Square square = this.ChessBoard.Squares[(int)index];
                    if (square.Piece != null)
                    {
                        square.Piece.DefendedValue = (short)0;
                        square.Piece.AttackedValue = (short)0;
                    }
                }
                PieceValidMoves.GenerateValidMoves(this.ChessBoard);
                Evaluation.EvaluateBoardScore(this.ChessBoard);
                this.PieceTakenAdd(this.ChessBoard.LastMove);
                this.MoveHistory.Push(this.ChessBoard.LastMove);
                if (ChessEngine.Engine.Engine.CheckForMate(this.WhoseMove, ref this.ChessBoard))
                {
                    this.Thinking = false;
                    if (!this.ChessBoard.WhiteMate && !this.ChessBoard.BlackMate)
                    {
                        return;
                    }
                    this.LastMove.PgnMove += "#";
                }
                else
                {
                    if (this.ChessBoard.WhiteCheck || this.ChessBoard.BlackCheck)
                    {
                        this.LastMove.PgnMove += "+";
                    }
                    this.Thinking = false;
                }
            }
        }
예제 #10
0
 public void Undo()
 {
     if (this.UndoChessBoard == null)
     {
         return;
     }
     this.PieceTakenRemove(this.ChessBoard.LastMove);
     this.PieceTakenRemove(this.PreviousChessBoard.LastMove);
     this.ChessBoard      = new Board(this.UndoChessBoard);
     this.CurrentGameBook = new List <OpeningMove>((IEnumerable <OpeningMove>) this.UndoGameBook);
     PieceValidMoves.GenerateValidMoves(this.ChessBoard);
     Evaluation.EvaluateBoardScore(this.ChessBoard);
 }
예제 #11
0
파일: Engine.cs 프로젝트: viper25/ChessCore
        public void Undo()
        {
            if (UndoChessBoard != null)
            {
                PieceTakenRemove(ChessBoard.LastMove);
                PieceTakenRemove(PreviousChessBoard.LastMove);

                ChessBoard      = new Board(UndoChessBoard);
                CurrentGameBook = new List <OpeningMove>(UndoGameBook);

                PieceValidMoves.GenerateValidMoves(ChessBoard);
                Evaluation.EvaluateBoardScore(ChessBoard);
            }
        }
예제 #12
0
        public bool IsCheckMate()
        {
            bool checkMate = false;

            if ((IsBlackChecked() && WhoseMove == ChessPieceColor.Black) || (IsWhiteChecked() && WhoseMove == ChessPieceColor.White))
            {
                checkMate = true;
                DynamicArray pieceList = new DynamicArray();
                Square[]     squares   = ChessBoard.Squares;
                Board        oldBoard  = new Board(ChessBoard);

                byte[] sourcePos;
                byte[] destinationPos;

                //Find all pieces that can be moved on this turn
                for (byte i = 0; i < squares.Length; i++)
                {
                    if (squares[i].Piece != null && squares[i].Piece.PieceColor == WhoseMove && squares[i].Piece.ValidMoves.Count > 0)
                    {
                        pieceList.Add(i);
                    }
                }

                //If piecelist is empty, no moves can be made
                if (pieceList.Count == 0)
                {
                    return(false);
                }

                foreach (byte piece in pieceList)
                {
                    sourcePos = CalculateColumnAndRow(piece);
                    foreach (byte move in squares[piece].Piece.ValidMoves)
                    {
                        destinationPos = CalculateColumnAndRow(move);

                        if (MovePiece(sourcePos[0], sourcePos[1], destinationPos[0], destinationPos[1]))
                        {
                            ChessBoard = new Board(oldBoard);
                            PieceValidMoves.GenerateValidMoves(ChessBoard);
                            return(false);
                        }
                    }
                }
            }

            return(checkMate);
        }
예제 #13
0
        private static int Quiescence(Board examineBoard, int alpha, int beta, ref int nodesSearched)
        {
            nodesSearched = nodesSearched + 1;
            Evaluation.EvaluateBoardScore(examineBoard);
            examineBoard.Score = Search.SideToMoveScore(examineBoard.Score, examineBoard.WhoseMove);
            if (examineBoard.Score >= beta)
            {
                return(beta);
            }
            if (examineBoard.Score > alpha)
            {
                alpha = examineBoard.Score;
            }
            List <Search.Position> positionList = examineBoard.WhiteCheck || examineBoard.BlackCheck ? Search.EvaluateMoves(examineBoard, (byte)0) : Search.EvaluateMovesQ(examineBoard);

            if (positionList.Count == 0)
            {
                return(examineBoard.Score);
            }
            positionList.Sort(new Comparison <Search.Position>(Search.Sort));
            foreach (Search.Position position in positionList)
            {
                if (Search.StaticExchangeEvaluation(examineBoard.Squares[(int)position.DstPosition]) < 0)
                {
                    Board board = examineBoard.FastCopy();
                    Board.MovePiece(board, position.SrcPosition, position.DstPosition, ChessPieceType.Queen);
                    PieceValidMoves.GenerateValidMoves(board);
                    if ((!board.BlackCheck || examineBoard.WhoseMove != ChessPieceColor.Black) && (!board.WhiteCheck || examineBoard.WhoseMove != ChessPieceColor.White))
                    {
                        int num = -Search.Quiescence(board, -beta, -alpha, ref nodesSearched);
                        if (num >= beta)
                        {
                            Search.KillerMove[2, 0].SrcPosition = position.SrcPosition;
                            Search.KillerMove[2, 0].DstPosition = position.DstPosition;
                            return(beta);
                        }
                        if (num > alpha)
                        {
                            alpha = num;
                        }
                    }
                }
            }
            return(alpha);
        }
        public bool MovePiece(byte sourceColumn, byte sourceRow, byte destinationColumn, byte destinationRow)
        {
            byte srcPosition = (byte)(sourceColumn + (sourceRow * 8));
            byte dstPosition = (byte)(destinationColumn + (destinationRow * 8));

            Piece piece = ChessBoard.Squares[srcPosition].Piece;

            PreviousChessBoard = new Board(ChessBoard);


            Board.MovePiece(ChessBoard, srcPosition, dstPosition, ChessPieceType.Queen);

            PieceValidMoves.GenerateValidMoves(ChessBoard);


            //If there is a check in place, check if this is still true;
            if (piece.PieceColor == ChessPieceColor.White)
            {
                if (ChessBoard.WhiteCheck)
                {
                    //Invalid Move
                    ChessBoard = new Board(PreviousChessBoard);
                    PieceValidMoves.GenerateValidMoves(ChessBoard);
                    return(false);
                }
            }
            else if (piece.PieceColor == ChessPieceColor.Black)
            {
                if (ChessBoard.BlackCheck)
                {
                    //Invalid Move
                    ChessBoard = new Board(PreviousChessBoard);
                    PieceValidMoves.GenerateValidMoves(ChessBoard);
                    return(false);
                }
            }

            return(true);
        }
예제 #15
0
        public bool MovePiece(byte srcPosition, byte dstPosition)
        {
            Piece piece = this.ChessBoard.Squares[(int)srcPosition].Piece;

            this.PreviousChessBoard = new Board(this.ChessBoard);
            this.UndoChessBoard     = new Board(this.ChessBoard);
            this.UndoGameBook       = new List <OpeningMove>((IEnumerable <OpeningMove>) this.CurrentGameBook);
            Board.MovePiece(this.ChessBoard, srcPosition, dstPosition, this.PromoteToPieceType);
            this.ChessBoard.LastMove.GeneratePGNString(this.ChessBoard);
            PieceValidMoves.GenerateValidMoves(this.ChessBoard);
            Evaluation.EvaluateBoardScore(this.ChessBoard);
            if (piece.PieceColor == ChessPieceColor.White)
            {
                if (this.ChessBoard.WhiteCheck)
                {
                    this.ChessBoard = new Board(this.PreviousChessBoard);
                    PieceValidMoves.GenerateValidMoves(this.ChessBoard);
                    return(false);
                }
            }
            else if (piece.PieceColor == ChessPieceColor.Black && this.ChessBoard.BlackCheck)
            {
                this.ChessBoard = new Board(this.PreviousChessBoard);
                PieceValidMoves.GenerateValidMoves(this.ChessBoard);
                return(false);
            }
            this.MoveHistory.Push(this.ChessBoard.LastMove);
            ChessEngine.Engine.Engine.CheckForMate(this.WhoseMove, ref this.ChessBoard);
            this.PieceTakenAdd(this.ChessBoard.LastMove);
            if (this.ChessBoard.WhiteMate || this.ChessBoard.BlackMate)
            {
                this.LastMove.PgnMove += "#";
            }
            else if (this.ChessBoard.WhiteCheck || this.ChessBoard.BlackCheck)
            {
                this.LastMove.PgnMove += "+";
            }
            return(true);
        }
예제 #16
0
        internal static void GenerateValidMoves(Board board)
        {
            board.BlackCheck = false;
            board.WhiteCheck = false;
            byte num1 = 0;
            byte num2 = 0;
            int  num3 = 0;

            for (byte srcPosition = 0; (int)srcPosition < 64; ++srcPosition)
            {
                Square square = board.Squares[(int)srcPosition];
                if (square.Piece != null)
                {
                    square.Piece.ValidMoves = new Stack <byte>(square.Piece.LastValidMoveCount);
                    ++num3;
                    switch (square.Piece.PieceType)
                    {
                    case ChessPieceType.King:
                        if (square.Piece.PieceColor == ChessPieceColor.White)
                        {
                            if (square.Piece.Moved)
                            {
                                board.WhiteCanCastle = false;
                            }
                            board.WhiteKingPosition = srcPosition;
                            continue;
                        }
                        if (square.Piece.Moved)
                        {
                            board.BlackCanCastle = false;
                        }
                        board.BlackKingPosition = srcPosition;
                        continue;

                    case ChessPieceType.Queen:
                        byte num4 = 0;
                        while ((int)num4 < (int)MoveArrays.QueenTotalMoves1[(int)srcPosition] && PieceValidMoves.AnalyzeMove(board, MoveArrays.QueenMoves1[(int)srcPosition].Moves[(int)num4], square.Piece))
                        {
                            ++num4;
                        }
                        byte num5 = 0;
                        while ((int)num5 < (int)MoveArrays.QueenTotalMoves2[(int)srcPosition] && PieceValidMoves.AnalyzeMove(board, MoveArrays.QueenMoves2[(int)srcPosition].Moves[(int)num5], square.Piece))
                        {
                            ++num5;
                        }
                        byte num6 = 0;
                        while ((int)num6 < (int)MoveArrays.QueenTotalMoves3[(int)srcPosition] && PieceValidMoves.AnalyzeMove(board, MoveArrays.QueenMoves3[(int)srcPosition].Moves[(int)num6], square.Piece))
                        {
                            ++num6;
                        }
                        byte num7 = 0;
                        while ((int)num7 < (int)MoveArrays.QueenTotalMoves4[(int)srcPosition] && PieceValidMoves.AnalyzeMove(board, MoveArrays.QueenMoves4[(int)srcPosition].Moves[(int)num7], square.Piece))
                        {
                            ++num7;
                        }
                        byte num8 = 0;
                        while ((int)num8 < (int)MoveArrays.QueenTotalMoves5[(int)srcPosition] && PieceValidMoves.AnalyzeMove(board, MoveArrays.QueenMoves5[(int)srcPosition].Moves[(int)num8], square.Piece))
                        {
                            ++num8;
                        }
                        byte num9 = 0;
                        while ((int)num9 < (int)MoveArrays.QueenTotalMoves6[(int)srcPosition] && PieceValidMoves.AnalyzeMove(board, MoveArrays.QueenMoves6[(int)srcPosition].Moves[(int)num9], square.Piece))
                        {
                            ++num9;
                        }
                        byte num10 = 0;
                        while ((int)num10 < (int)MoveArrays.QueenTotalMoves7[(int)srcPosition] && PieceValidMoves.AnalyzeMove(board, MoveArrays.QueenMoves7[(int)srcPosition].Moves[(int)num10], square.Piece))
                        {
                            ++num10;
                        }
                        byte num11 = 0;
                        while ((int)num11 < (int)MoveArrays.QueenTotalMoves8[(int)srcPosition] && PieceValidMoves.AnalyzeMove(board, MoveArrays.QueenMoves8[(int)srcPosition].Moves[(int)num11], square.Piece))
                        {
                            ++num11;
                        }
                        continue;

                    case ChessPieceType.Rook:
                        if (square.Piece.Moved)
                        {
                            if (square.Piece.PieceColor == ChessPieceColor.Black)
                            {
                                ++num1;
                            }
                            else
                            {
                                ++num2;
                            }
                        }
                        byte num12 = 0;
                        while ((int)num12 < (int)MoveArrays.RookTotalMoves1[(int)srcPosition] && PieceValidMoves.AnalyzeMove(board, MoveArrays.RookMoves1[(int)srcPosition].Moves[(int)num12], square.Piece))
                        {
                            ++num12;
                        }
                        byte num13 = 0;
                        while ((int)num13 < (int)MoveArrays.RookTotalMoves2[(int)srcPosition] && PieceValidMoves.AnalyzeMove(board, MoveArrays.RookMoves2[(int)srcPosition].Moves[(int)num13], square.Piece))
                        {
                            ++num13;
                        }
                        byte num14 = 0;
                        while ((int)num14 < (int)MoveArrays.RookTotalMoves3[(int)srcPosition] && PieceValidMoves.AnalyzeMove(board, MoveArrays.RookMoves3[(int)srcPosition].Moves[(int)num14], square.Piece))
                        {
                            ++num14;
                        }
                        byte num15 = 0;
                        while ((int)num15 < (int)MoveArrays.RookTotalMoves4[(int)srcPosition] && PieceValidMoves.AnalyzeMove(board, MoveArrays.RookMoves4[(int)srcPosition].Moves[(int)num15], square.Piece))
                        {
                            ++num15;
                        }
                        continue;

                    case ChessPieceType.Bishop:
                        byte num16 = 0;
                        while ((int)num16 < (int)MoveArrays.BishopTotalMoves1[(int)srcPosition] && PieceValidMoves.AnalyzeMove(board, MoveArrays.BishopMoves1[(int)srcPosition].Moves[(int)num16], square.Piece))
                        {
                            ++num16;
                        }
                        byte num17 = 0;
                        while ((int)num17 < (int)MoveArrays.BishopTotalMoves2[(int)srcPosition] && PieceValidMoves.AnalyzeMove(board, MoveArrays.BishopMoves2[(int)srcPosition].Moves[(int)num17], square.Piece))
                        {
                            ++num17;
                        }
                        byte num18 = 0;
                        while ((int)num18 < (int)MoveArrays.BishopTotalMoves3[(int)srcPosition] && PieceValidMoves.AnalyzeMove(board, MoveArrays.BishopMoves3[(int)srcPosition].Moves[(int)num18], square.Piece))
                        {
                            ++num18;
                        }
                        byte num19 = 0;
                        while ((int)num19 < (int)MoveArrays.BishopTotalMoves4[(int)srcPosition] && PieceValidMoves.AnalyzeMove(board, MoveArrays.BishopMoves4[(int)srcPosition].Moves[(int)num19], square.Piece))
                        {
                            ++num19;
                        }
                        continue;

                    case ChessPieceType.Knight:
                        for (byte index = 0; (int)index < (int)MoveArrays.KnightTotalMoves[(int)srcPosition]; ++index)
                        {
                            PieceValidMoves.AnalyzeMove(board, MoveArrays.KnightMoves[(int)srcPosition].Moves[(int)index], square.Piece);
                        }
                        continue;

                    case ChessPieceType.Pawn:
                        if (square.Piece.PieceColor == ChessPieceColor.White)
                        {
                            PieceValidMoves.CheckValidMovesPawn(MoveArrays.WhitePawnMoves[(int)srcPosition].Moves, square.Piece, srcPosition, board, MoveArrays.WhitePawnTotalMoves[(int)srcPosition]);
                            continue;
                        }
                        if (square.Piece.PieceColor == ChessPieceColor.Black)
                        {
                            PieceValidMoves.CheckValidMovesPawn(MoveArrays.BlackPawnMoves[(int)srcPosition].Moves, square.Piece, srcPosition, board, MoveArrays.BlackPawnTotalMoves[(int)srcPosition]);
                            continue;
                        }
                        continue;

                    default:
                        continue;
                    }
                }
            }
            if ((int)num1 > 1)
            {
                board.BlackCanCastle = false;
            }
            if ((int)num2 > 1)
            {
                board.WhiteCanCastle = false;
            }
            if (num3 < 10)
            {
                board.EndGamePhase = true;
            }
            if (board.WhoseMove == ChessPieceColor.White)
            {
                PieceValidMoves.GenerateValidMovesKing(board.Squares[(int)board.BlackKingPosition].Piece, board, board.BlackKingPosition);
                PieceValidMoves.GenerateValidMovesKing(board.Squares[(int)board.WhiteKingPosition].Piece, board, board.WhiteKingPosition);
            }
            else
            {
                PieceValidMoves.GenerateValidMovesKing(board.Squares[(int)board.WhiteKingPosition].Piece, board, board.WhiteKingPosition);
                PieceValidMoves.GenerateValidMovesKing(board.Squares[(int)board.BlackKingPosition].Piece, board, board.BlackKingPosition);
            }
            if (!board.WhiteCastled && board.WhiteCanCastle && !board.WhiteCheck)
            {
                PieceValidMoves.GenerateValidMovesKingCastle(board, board.Squares[(int)board.WhiteKingPosition].Piece);
            }
            if (board.BlackCastled || !board.BlackCanCastle || board.BlackCheck)
            {
                return;
            }
            PieceValidMoves.GenerateValidMovesKingCastle(board, board.Squares[(int)board.BlackKingPosition].Piece);
        }
예제 #17
0
        internal static bool SearchForMate(ChessPieceColor movingSide, Board examineBoard, ref bool blackMate, ref bool whiteMate, ref bool staleMate)
        {
            bool foundNonCheckBlack = false;
            bool foundNonCheckWhite = false;

            for (byte x = 0; x < 64; x++)
            {
                Square sqr = examineBoard.Squares[x];

                //Make sure there is a piece on the square
                if (sqr.Piece == null)
                {
                    continue;
                }

                //Make sure the color is the same color as the one we are moving.
                if (sqr.Piece.PieceColor != movingSide)
                {
                    continue;
                }

                //For each valid move for this piece
                foreach (byte dst in sqr.Piece.ValidMoves)
                {
                    //We make copies of the board and move so that we can move it without effecting the parent board
                    Board board = examineBoard.FastCopy();

                    //Make move so we can examine it
                    Board.MovePiece(board, x, dst, ChessPieceType.Queen);

                    //We Generate Valid Moves for Board
                    PieceValidMoves.GenerateValidMoves(board);

                    if (board.BlackCheck == false)
                    {
                        foundNonCheckBlack = true;
                    }
                    else if (movingSide == ChessPieceColor.Black)
                    {
                        continue;
                    }

                    if (board.WhiteCheck == false)
                    {
                        foundNonCheckWhite = true;
                    }
                    else if (movingSide == ChessPieceColor.White)
                    {
                        continue;
                    }
                }
            }

            if (foundNonCheckBlack == false)
            {
                if (examineBoard.BlackCheck)
                {
                    blackMate = true;
                    return(true);
                }
                if (!examineBoard.WhiteMate && movingSide != ChessPieceColor.White)
                {
                    staleMate = true;
                    return(true);
                }
            }

            if (foundNonCheckWhite == false)
            {
                if (examineBoard.WhiteCheck)
                {
                    whiteMate = true;
                    return(true);
                }
                if (!examineBoard.BlackMate && movingSide != ChessPieceColor.Black)
                {
                    staleMate = true;
                    return(true);
                }
            }

            return(false);
        }
예제 #18
0
        private static int Quiescence(Board examineBoard, int alpha, int beta, ref int nodesSearched)
        {
            nodesSearched++;

            //Evaluate Score
            Evaluation.EvaluateBoardScore(examineBoard);

            //Invert Score to support Negamax
            examineBoard.Score = SideToMoveScore(examineBoard.Score, examineBoard.WhoseMove);

            if (examineBoard.Score >= beta)
            {
                return(beta);
            }

            if (examineBoard.Score > alpha)
            {
                alpha = examineBoard.Score;
            }


            List <Position> positions;


            if (examineBoard.WhiteCheck || examineBoard.BlackCheck)
            {
                positions = EvaluateMoves(examineBoard, 0);
            }
            else
            {
                positions = EvaluateMovesQ(examineBoard);
            }

            if (positions.Count == 0)
            {
                return(examineBoard.Score);
            }

            positions.Sort(Sort);

            foreach (Position move in positions)
            {
                if (StaticExchangeEvaluation(examineBoard.Squares[move.DstPosition]) >= 0)
                {
                    continue;
                }

                //Make a copy
                Board board = examineBoard.FastCopy();

                //Move Piece
                Board.MovePiece(board, move.SrcPosition, move.DstPosition, ChessPieceType.Queen);

                //We Generate Valid Moves for Board
                PieceValidMoves.GenerateValidMoves(board);

                if (board.BlackCheck)
                {
                    if (examineBoard.WhoseMove == ChessPieceColor.Black)
                    {
                        //Invalid Move
                        continue;
                    }
                }

                if (board.WhiteCheck)
                {
                    if (examineBoard.WhoseMove == ChessPieceColor.White)
                    {
                        //Invalid Move
                        continue;
                    }
                }

                int value = -Quiescence(board, -beta, -alpha, ref nodesSearched);

                if (value >= beta)
                {
                    KillerMove[2, 0].SrcPosition = move.SrcPosition;
                    KillerMove[2, 0].DstPosition = move.DstPosition;

                    return(beta);
                }
                if (value > alpha)
                {
                    alpha = value;
                }
            }

            return(alpha);
        }
예제 #19
0
        private static int AlphaBeta(Board examineBoard, byte depth, int alpha, int beta, ref int nodesSearched, ref int nodesQuiessence, ref List <Position> pvLine, bool extended)
        {
            nodesSearched++;

            if (examineBoard.FiftyMove >= 50 || examineBoard.RepeatedMove >= 3)
            {
                return(0);
            }

            //End Main Search with Quiescence
            if (depth == 0)
            {
                if (!extended && examineBoard.BlackCheck || examineBoard.WhiteCheck)
                {
                    depth++;
                    extended = true;
                }
                else
                {
                    //Perform a Quiessence Search
                    return(Quiescence(examineBoard, alpha, beta, ref nodesQuiessence));
                }
            }

            List <Position> positions = EvaluateMoves(examineBoard, depth);

            if (examineBoard.WhiteCheck || examineBoard.BlackCheck || positions.Count == 0)
            {
                if (SearchForMate(examineBoard.WhoseMove, examineBoard, ref examineBoard.BlackMate, ref examineBoard.WhiteMate, ref examineBoard.StaleMate))
                {
                    if (examineBoard.BlackMate)
                    {
                        if (examineBoard.WhoseMove == ChessPieceColor.Black)
                        {
                            return(-32767 - depth);
                        }

                        return(32767 + depth);
                    }
                    if (examineBoard.WhiteMate)
                    {
                        if (examineBoard.WhoseMove == ChessPieceColor.Black)
                        {
                            return(32767 + depth);
                        }

                        return(-32767 - depth);
                    }

                    //If Not Mate then StaleMate
                    return(0);
                }
            }

            positions.Sort(Sort);

            foreach (Position move in positions)
            {
                List <Position> pvChild = new List <Position>();

                //Make a copy
                Board board = examineBoard.FastCopy();

                //Move Piece
                Board.MovePiece(board, move.SrcPosition, move.DstPosition, ChessPieceType.Queen);

                //We Generate Valid Moves for Board
                PieceValidMoves.GenerateValidMoves(board);

                if (board.BlackCheck)
                {
                    if (examineBoard.WhoseMove == ChessPieceColor.Black)
                    {
                        //Invalid Move
                        continue;
                    }
                }

                if (board.WhiteCheck)
                {
                    if (examineBoard.WhoseMove == ChessPieceColor.White)
                    {
                        //Invalid Move
                        continue;
                    }
                }

                int value = -AlphaBeta(board, (byte)(depth - 1), -beta, -alpha, ref nodesSearched, ref nodesQuiessence, ref pvChild, extended);

                if (value >= beta)
                {
                    KillerMove[kIndex, depth].SrcPosition = move.SrcPosition;
                    KillerMove[kIndex, depth].DstPosition = move.DstPosition;

                    kIndex = ((kIndex + 1) % 2);


                    return(beta);
                }
                if (value > alpha)
                {
                    Position pvPos = new Position();

                    pvPos.SrcPosition = board.LastMove.MovingPiecePrimary.SrcPosition;
                    pvPos.DstPosition = board.LastMove.MovingPiecePrimary.DstPosition;
                    pvPos.Move        = board.LastMove.ToString();

                    pvChild.Insert(0, pvPos);

                    pvLine = pvChild;

                    alpha = (int)value;
                }
            }

            return(alpha);
        }
예제 #20
0
        private static int AlphaBeta(Board examineBoard, byte depth, int alpha, int beta, ref int nodesSearched, ref int nodesQuiessence, ref List <Search.Position> pvLine, bool extended)
        {
            nodesSearched = nodesSearched + 1;
            if ((int)examineBoard.FiftyMove >= 50 || (int)examineBoard.RepeatedMove >= 3)
            {
                return(0);
            }
            int?nullable1 = Zobrist.Search(examineBoard.ZobristHash, depth, alpha, beta);

            if (nullable1.HasValue)
            {
                return(nullable1.Value);
            }
            if ((int)depth == 0)
            {
                if (!extended && examineBoard.BlackCheck || examineBoard.WhiteCheck)
                {
                    ++depth;
                    extended = true;
                }
                else
                {
                    int score = Search.Quiescence(examineBoard, alpha, beta, ref nodesQuiessence);
                    if (score >= beta)
                    {
                        Zobrist.AddEntry(examineBoard.ZobristHash, depth, score, Zobrist.NodeType.Beta);
                    }
                    else if (score <= alpha)
                    {
                        Zobrist.AddEntry(examineBoard.ZobristHash, depth, score, Zobrist.NodeType.Alpha);
                    }
                    else
                    {
                        Zobrist.AddEntry(examineBoard.ZobristHash, depth, score, Zobrist.NodeType.Exact);
                    }
                    return(score);
                }
            }
            Zobrist.NodeType       nodeType = Zobrist.NodeType.Alpha;
            List <Search.Position> moves    = Search.EvaluateMoves(examineBoard, depth);

            if ((examineBoard.WhiteCheck || examineBoard.BlackCheck || moves.Count == 0) && Search.SearchForMate(examineBoard.WhoseMove, examineBoard, ref examineBoard.BlackMate, ref examineBoard.WhiteMate, ref examineBoard.StaleMate))
            {
                if (examineBoard.BlackMate)
                {
                    if (examineBoard.WhoseMove == ChessPieceColor.Black)
                    {
                        return(-32767 - (int)depth);
                    }
                    return((int)short.MaxValue + (int)depth);
                }
                if (!examineBoard.WhiteMate)
                {
                    return(0);
                }
                if (examineBoard.WhoseMove == ChessPieceColor.Black)
                {
                    return((int)short.MaxValue + (int)depth);
                }
                return(-32767 - (int)depth);
            }
            moves.Sort(new Comparison <Search.Position>(Search.Sort));
            foreach (Search.Position position in moves)
            {
                List <Search.Position> pvLine1 = new List <Search.Position>();
                Board board = examineBoard.FastCopy();
                Board.MovePiece(board, position.SrcPosition, position.DstPosition, ChessPieceType.Queen);
                PieceValidMoves.GenerateValidMoves(board);
                if ((!board.BlackCheck || examineBoard.WhoseMove != ChessPieceColor.Black) && (!board.WhiteCheck || examineBoard.WhoseMove != ChessPieceColor.White))
                {
                    int?nullable2 = new int?(-Search.AlphaBeta(board, (byte)((uint)depth - 1U), -beta, -alpha, ref nodesSearched, ref nodesQuiessence, ref pvLine1, extended));
                    int?nullable3 = nullable2;
                    int num1      = beta;
                    if ((nullable3.GetValueOrDefault() >= num1 ? (nullable3.HasValue ? 1 : 0) : 0) != 0)
                    {
                        Search.KillerMove[Search.kIndex, (int)depth].SrcPosition = position.SrcPosition;
                        Search.KillerMove[Search.kIndex, (int)depth].DstPosition = position.DstPosition;
                        Search.kIndex = (Search.kIndex + 1) % 2;
                        Zobrist.AddEntry(examineBoard.ZobristHash, depth, nullable2.Value, Zobrist.NodeType.Beta);
                        return(beta);
                    }
                    nullable3 = nullable2;
                    int num2 = alpha;
                    if ((nullable3.GetValueOrDefault() > num2 ? (nullable3.HasValue ? 1 : 0) : 0) != 0)
                    {
                        pvLine1.Insert(0, new Search.Position()
                        {
                            SrcPosition = board.LastMove.MovingPiecePrimary.SrcPosition,
                            DstPosition = board.LastMove.MovingPiecePrimary.DstPosition,
                            Move        = board.LastMove.ToString()
                        });
                        pvLine   = pvLine1;
                        alpha    = nullable2.Value;
                        nodeType = Zobrist.NodeType.Exact;
                    }
                }
            }
            Zobrist.AddEntry(examineBoard.ZobristHash, depth, alpha, nodeType);
            return(alpha);
        }
예제 #21
0
        public void AiPonderMove()
        {
            Thinking      = true;
            NodesSearched = 0;

            var resultBoards = new ResultBoards();

            resultBoards.Positions = new List <Board>();

            if (CheckForMate(WhoseMove, ref ChessBoard))
            {
                Thinking = false;
                return;
            }

            MoveContent bestMove = new MoveContent();

            //If there is no playbook move search for the best move
            if (FindPlayBookMove(ref bestMove, ChessBoard, OpeningBook) == false ||
                ChessBoard.FiftyMove > 45 || ChessBoard.RepeatedMove >= 2)
            {
                if (FindPlayBookMove(ref bestMove, ChessBoard, CurrentGameBook) == false ||
                    ChessBoard.FiftyMove > 45 || ChessBoard.RepeatedMove >= 2)
                {
                    bestMove = Search.IterativeSearch(ChessBoard, PlyDepthSearched, ref NodesSearched, ref NodesQuiessence, ref pvLine, ref PlyDepthReached, ref RootMovesSearched, CurrentGameBook);
                }
            }

            //Make the move
            PreviousChessBoard = new Board(ChessBoard);

            RootMovesSearched = (byte)resultBoards.Positions.Count;

            Board.MovePiece(ChessBoard, bestMove.MovingPiecePrimary.SrcPosition, bestMove.MovingPiecePrimary.DstPosition, ChessPieceType.Queen);

            ChessBoard.LastMove.GeneratePGNString(ChessBoard);

            FileIO.SaveCurrentGameMove(ChessBoard, PreviousChessBoard, CurrentGameBook, bestMove);

            for (byte x = 0; x < 64; x++)
            {
                Square sqr = ChessBoard.Squares[x];

                if (sqr.Piece == null)
                {
                    continue;
                }

                sqr.Piece.DefendedValue = 0;
                sqr.Piece.AttackedValue = 0;
            }

            PieceValidMoves.GenerateValidMoves(ChessBoard);
            Evaluation.EvaluateBoardScore(ChessBoard);

            PieceTakenAdd(ChessBoard.LastMove);

            MoveHistory.Push(ChessBoard.LastMove);

            if (CheckForMate(WhoseMove, ref ChessBoard))
            {
                Thinking = false;

                if (ChessBoard.WhiteMate || ChessBoard.BlackMate)
                {
                    LastMove.PgnMove += "#";
                }

                return;
            }

            if (ChessBoard.WhiteCheck || ChessBoard.BlackCheck)
            {
                LastMove.PgnMove += "+";
            }

            Thinking = false;
        }
예제 #22
0
        public void AiPonderMove()
        {
            Thinking = true;

            /* Fix added to prevent premature declaration of checkmate against computer's king.
             *
             * The original version only looked at squares that were available for the black king to move to PRIOR to white's latest move.
             * So... suppose you had a situation like this:
             *	r4r2/pppb1p1k/8/3p2Q1/q4P2/2np4/6PP/5RK1/ w - 0 27
             *  ... and moved the white queen from G5 to H5.
             *	At the start of white's move, the black king has 5 possible moves... 4 of which are attackable by white, and noted by
             *	GenerateValidMoves in WhiteAttackBoard[]. When AiPonderMove executes, it immediately eliminates those 4 squares as options
             *	for the black king, even though 2 of them are now safe because no white piece can attack them. However, square 7 is now
             *	directly in the queen's attack path, so it's eliminated as an option as well. Boom, premature checkmate... game over.
             *
             *	The time it takes to regenerate the valid moves is nontrivial under Android. To improve performance,
             *	my fix regenerates the valid moves ONLY when it might prevent a game-ending premature declaration
             *	of checkmate, unless the difficulty is set to Hard or VeryHard (in which case it runs every time).
             *	Even a novice player is likely to get confused if the engine declares checkmate for no apparent reason,
             *	but the bug's more insidious manifestations at the two easiest difficulty levels help to make the computer a tiny bit easier
             *	to beat by giving it a blind spot that a player can exploit, the same way HUMAN opponents have blind spots and weaknesses of their own.
             */
            if (ChessBoard.BlackMate || ChessBoard.WhiteMate || (GameDifficulty == Difficulty.VeryHard) || (GameDifficulty == Difficulty.Hard))
            {
                ChessBoard.BlackMate = false;
                ChessBoard.WhiteMate = false;
                PieceValidMoves.GenerateValidMoves(ChessBoard);
            }

            NodesSearched = 0;

            var resultBoards = new ResultBoards();

            resultBoards.Positions = new List <Board>();

            if (CheckForMate(WhoseMove, ref ChessBoard))
            {
                Thinking = false;
                return;
            }

            MoveContent bestMove = new MoveContent();

            //If there is no playbook move search for the best move
            if (FindPlayBookMove(ref bestMove, ChessBoard, OpeningBook) == false ||
                ChessBoard.FiftyMove > 45 || ChessBoard.RepeatedMove >= 2)
            {
                if (FindPlayBookMove(ref bestMove, ChessBoard, CurrentGameBook) == false ||
                    ChessBoard.FiftyMove > 45 || ChessBoard.RepeatedMove >= 2)
                {
                    bestMove = Search.IterativeSearch(ChessBoard, PlyDepthSearched, ref NodesSearched, ref NodesQuiessence, ref pvLine, ref PlyDepthReached, ref RootMovesSearched, CurrentGameBook);
                }
            }

            //Make the move
            PreviousChessBoard = new Board(ChessBoard);

            RootMovesSearched = (byte)resultBoards.Positions.Count;

            Board.MovePiece(ChessBoard, bestMove.MovingPiecePrimary.SrcPosition, bestMove.MovingPiecePrimary.DstPosition, ChessPieceType.Queen);

            ChessBoard.LastMove.GeneratePGNString(ChessBoard);

            FileIO.SaveCurrentGameMove(ChessBoard, PreviousChessBoard, CurrentGameBook, bestMove);

            for (byte x = 0; x < 64; x++)
            {
                Square sqr = ChessBoard.Squares[x];

                if (sqr.Piece == null)
                {
                    continue;
                }

                sqr.Piece.DefendedValue = 0;
                sqr.Piece.AttackedValue = 0;
            }

            PieceValidMoves.GenerateValidMoves(ChessBoard);
            Evaluation.EvaluateBoardScore(ChessBoard);

            PieceTakenAdd(ChessBoard.LastMove);

            MoveHistory.Push(ChessBoard.LastMove);

            if (CheckForMate(WhoseMove, ref ChessBoard))
            {
                Thinking = false;

                if (ChessBoard.WhiteMate || ChessBoard.BlackMate)
                {
                    LastMove.PgnMove += "#";
                }

                return;
            }

            if (ChessBoard.WhiteCheck || ChessBoard.BlackCheck)
            {
                LastMove.PgnMove += "+";
            }

            Thinking = false;
        }
예제 #23
0
파일: Engine.cs 프로젝트: viper25/ChessCore
 public void GenerateValidMoves()
 {
     PieceValidMoves.GenerateValidMoves(ChessBoard);
 }
 private void GenerateValidMoves()
 {
     PieceValidMoves.GenerateValidMoves(ChessBoard);
 }
예제 #25
0
파일: Engine.cs 프로젝트: viper25/ChessCore
        public void AiPonderMove()
        {
            Thinking = true;

            /* Fix added to prevent premature declaration of checkmate against computer's king.
             *
             * The original version only looked at squares that were available for the black king to move to PRIOR to white's latest move.
             * So... suppose you had a situation like this:
             *	r4r2/pppb1p1k/8/3p2Q1/q4P2/2np4/6PP/5RK1/ w - 0 27
             *  ... and moved the white queen from G5 to H5.
             *	At the start of white's move, the black king has 5 possible moves... 4 of which are attackable by white, and noted by
             *	GenerateValidMoves in WhiteAttackBoard[]. When AiPonderMove executes, it immediately eliminates those 4 squares as options
             *	for the black king, even though 2 of them are now safe because no white piece can attack them. However, square 7 is now
             *	directly in the queen's attack path, so it's eliminated as an option as well. Boom, premature checkmate... game over.
             */
            ChessBoard.BlackMate = false;
            ChessBoard.WhiteMate = false;
            PieceValidMoves.GenerateValidMoves(ChessBoard);

            NodesSearched = 0;

            var resultBoards = new ResultBoards();

            resultBoards.Positions = new List <Board>();

            if (CheckForMate(WhoseMove, ref ChessBoard))
            {
                Thinking = false;
                return;
            }

            MoveContent bestMove = new MoveContent();

            //If there is no playbook move search for the best move
            if (FindPlayBookMove(ref bestMove, ChessBoard, OpeningBook) == false ||
                ChessBoard.HalfMoveClock > 90 || ChessBoard.RepeatedMove >= 2)
            {
                if (FindPlayBookMove(ref bestMove, ChessBoard, CurrentGameBook) == false ||
                    ChessBoard.HalfMoveClock > 90 || ChessBoard.RepeatedMove >= 2)
                {
                    bestMove = Search.IterativeSearch(ChessBoard, PlyDepthSearched, ref NodesSearched, ref NodesQuiessence, ref pvLine, ref PlyDepthReached, ref RootMovesSearched, CurrentGameBook);
                }
            }

            //Make the move
            PreviousChessBoard = new Board(ChessBoard);

            RootMovesSearched = (byte)resultBoards.Positions.Count;

            Board.MovePiece(ChessBoard, bestMove.MovingPiecePrimary.SrcPosition, bestMove.MovingPiecePrimary.DstPosition, ChessPieceType.Queen);

            ChessBoard.LastMove.GeneratePGNString(ChessBoard);

            FileIO.SaveCurrentGameMove(ChessBoard, PreviousChessBoard, CurrentGameBook, bestMove);

            for (byte x = 0; x < 64; x++)
            {
                Square sqr = ChessBoard.Squares[x];

                if (sqr.Piece == null)
                {
                    continue;
                }

                sqr.Piece.DefendedValue = 0;
                sqr.Piece.AttackedValue = 0;
            }

            PieceValidMoves.GenerateValidMoves(ChessBoard);
            Evaluation.EvaluateBoardScore(ChessBoard);

            PieceTakenAdd(ChessBoard.LastMove);

            MoveHistory.Push(ChessBoard.LastMove);

            if (CheckForMate(WhoseMove, ref ChessBoard))
            {
                Thinking = false;

                if (ChessBoard.WhiteMate || ChessBoard.BlackMate)
                {
                    LastMove.PgnMove += "#";
                }

                return;
            }

            if (ChessBoard.WhiteCheck || ChessBoard.BlackCheck)
            {
                LastMove.PgnMove += "+";
            }

            Thinking = false;
        }
예제 #26
0
        private static ResultBoards GetSortValidMoves(Board examineBoard)
        {
            ResultBoards succ = new ResultBoards
            {
                Positions = new List <Board>(30)
            };

            piecesRemaining = 0;

            for (byte x = 0; x < 64; x++)
            {
                Square sqr = examineBoard.Squares[x];

                //Make sure there is a piece on the square
                if (sqr.Piece == null)
                {
                    continue;
                }

                piecesRemaining++;

                //Make sure the color is the same color as the one we are moving.
                if (sqr.Piece.PieceColor != examineBoard.WhoseMove)
                {
                    continue;
                }

                //For each valid move for this piece
                foreach (byte dst in sqr.Piece.ValidMoves)
                {
                    //We make copies of the board and move so that we can move it without effecting the parent board
                    Board board = examineBoard.FastCopy();

                    //Make move so we can examine it
                    Board.MovePiece(board, x, dst, ChessPieceType.Queen);

                    //We Generate Valid Moves for Board
                    PieceValidMoves.GenerateValidMoves(board);

                    //Invalid Move
                    if (board.WhiteCheck && examineBoard.WhoseMove == ChessPieceColor.White)
                    {
                        continue;
                    }

                    //Invalid Move
                    if (board.BlackCheck && examineBoard.WhoseMove == ChessPieceColor.Black)
                    {
                        continue;
                    }

                    //We calculate the board score
                    Evaluation.EvaluateBoardScore(board);

                    //Invert Score to support Negamax
                    board.Score = SideToMoveScore(board.Score, board.WhoseMove);

                    succ.Positions.Add(board);
                }
            }

            succ.Positions.Sort(Sort);
            return(succ);
        }