예제 #1
0
        public override List <Move> FindMoves(Board board)
        {
            var moves = new List <Move>();

            int[] indices = new int[] { -2, -1, 1, 2 };
            foreach (int x in indices)
            {
                foreach (int y in indices)
                {
                    if (Math.Abs(x) == Math.Abs(y))
                    {
                        continue;
                    }
                    if (!Position.IsOnBoard((int)Position.Rank + y, (int)Position.File + x))
                    {
                        continue;
                    }
                    var  newPos        = Position.MoveHoriz(x).MoveVert(y);
                    bool enemyOccupied = (board[newPos]?.Color.Opposite() == this.Color);
                    moves.Add(MoveBuilder.CreateNormalMove(this, newPos, enemyOccupied));
                }
            }

            return(moves);
        }
예제 #2
0
        private List <Move> GetMovesWithDirection(Board board, int vertIncrement, int horizIncrement)
        {
            var moves = new List <Move>();

            int r = (int)Position.Rank;
            int f = (int)Position.File;

            while (true)
            {
                r = r + vertIncrement;
                f = f + horizIncrement;

                bool validPosition = (f <= 8 && f >= 1) && (r <= 8 && r >= 1);
                if (!validPosition)
                {
                    break;
                }

                var newPos       = new Position((File)f, (Rank)r);
                var currentPiece = board[newPos];
                if (currentPiece != null)
                {
                    if (currentPiece.Color != this.Color)
                    {
                        // We can't go any further, but we can take!
                        moves.Add(MoveBuilder.CreateNormalMove(this,
                                                               newPos, true));
                    }
                    break;
                }
                moves.Add(MoveBuilder.CreateNormalMove(this,
                                                       newPos, false));
            }
            return(moves);
        }
        private static Move DetermineMove(Board board, UCIChessMove uciMove)
        {
            string from      = uciMove.From;
            string to        = uciMove.To;
            var    fromPos   = Position.Parse(from);
            var    toPos     = Position.Parse(to);
            var    fromPiece = board[fromPos];

            int fileDiff = Math.Abs((int)fromPiece.Position.File - (int)toPos.File);

            if (fromPiece.Type == PieceType.King && (fileDiff == 3 || fileDiff == 4))
            {
                King king = (King)fromPiece;
                Rook rook;
                if (fileDiff == 4)
                {
                    rook = (Rook)board[File.A, fromPiece.Position.Rank];
                }
                else
                {
                    rook = (Rook)board[File.H, fromPiece.Position.Rank];
                }

                return(MoveBuilder.CreateCastleMove(king, rook));
            }

            if (uciMove.PromotionChar != null)
            {
                string promotionChar = uciMove.PromotionChar.ToUpper();
                var    promotionType = (from p in (PieceType[])Enum.GetValues(typeof(PieceType))
                                        where p.ToNotationLetter().ToUpper() == promotionChar.ToUpper()
                                        select p).First();
                var promotionMoves = MoveBuilder.CreatePromotionMoves((Pawn)fromPiece, toPos, board[toPos] != null);
                return((from m in promotionMoves
                        where m.Promotion.NewPieceType.Type == promotionType
                        select m).First());
            }

            // Check for en passant
            var existingPieceRank = fromPiece.Position.Rank;
            var isCorrectRank     = fromPiece.Color == PieceColor.Black ? existingPieceRank == Rank._4 : existingPieceRank == Rank._5;

            try
            {
                int vertDir          = fromPiece.Color == PieceColor.White ? -1 : 1;
                var existingPieceTo  = board[toPos];
                var capturedPiecePos = toPos.MoveVert(vertDir);
                var capturedPiece    = board[capturedPiecePos];
                if (capturedPiece.Color == fromPiece.Color.Opposite() &&
                    capturedPiece.MoveHistory.Count == 1)
                {
                    // This is an en passant
                    return(MoveBuilder.CreateEnPassantMove((Pawn)fromPiece, toPos, capturedPiecePos));
                }
            }
            catch { }

            // Only other option is that this is a normal move.
            return(MoveBuilder.CreateNormalMove(fromPiece, toPos, board[toPos] != null));
        }
예제 #4
0
        private List <Move> GetMovesInDirection(Board board, int vert, int horiz)
        {
            var moves       = new List <Move>();
            int currentRank = (int)Position.Rank;
            int currentFile = (int)Position.File;
            int magnitude   = 1;

            while (true)
            {
                int newRank = currentRank + magnitude * vert;
                int newFile = currentFile + magnitude * horiz;
                var newPos  = new Position((File)newFile, (Rank)newRank);

                if (!Position.IsOnBoard(newPos))
                {
                    break;
                }
                var currentPiece = board[newPos];
                if (currentPiece != null)
                {
                    if (currentPiece.Color != this.Color)
                    {
                        // We can take!
                        moves.Add(MoveBuilder.CreateNormalMove(this, newPos, true));
                    }
                    break;
                }
                moves.Add(MoveBuilder.CreateNormalMove(this, newPos, false));
                magnitude++;
            }

            return(moves);
        }
예제 #5
0
        private List <Move> GetCapturingMoves(Board board)
        {
            var capturingMoves = new List <Move>();

            if (Position.File != File.A)
            {
                var leftDiagPosition = Position
                                       .MoveVert(IncrementDirection)
                                       .MoveHoriz(-1);
                if (IsPositionEnemyOccupied(board, leftDiagPosition))
                {
                    capturingMoves.Add(MoveBuilder.CreateNormalMove(this, leftDiagPosition, true));
                }
            }
            if (Position.File != File.H)
            {
                var rightDiagPosition = Position
                                        .MoveVert(IncrementDirection)
                                        .MoveHoriz(1);
                if (IsPositionEnemyOccupied(board, rightDiagPosition))
                {
                    capturingMoves.Add(MoveBuilder.CreateNormalMove(this, rightDiagPosition, true));
                }
            }

            return(capturingMoves);
        }
예제 #6
0
        private List <Move> GetAdvancingMoves(Board board)
        {
            var moves = new List <Move>();

            bool canMoveTwo = false;

            if ((Color == PieceColor.White && Position.Rank == Rank._2) ||
                (Color == PieceColor.Black && Position.Rank == Rank._7))
            {
                canMoveTwo = true;
            }

            var singleMovePos = Position.MoveVert(IncrementDirection);

            if (board[singleMovePos] == null)
            {
                moves.Add(MoveBuilder.CreateNormalMove(this, singleMovePos, false));
            }
            else
            {
                // Can't move two if you can't move one
                canMoveTwo = false;
            }
            if (canMoveTwo)
            {
                var moveTwoPos = Position.MoveVert(IncrementDirection * 2);
                if (board[moveTwoPos] == null)
                {
                    moves.Add(MoveBuilder.CreateNormalMove(this, moveTwoPos, false));
                }
            }

            return(moves);
        }
예제 #7
0
        public void KingCannotCastleIfRookAlreadyMoved()
        {
            var kingBoard = CreateBoardWithWhiteKingAt(new Position(File.E, Rank._1));

            kingBoard.AddPiece(new PieceBuilder(PieceType.Rook)
                               .As(PieceColor.White)
                               .At(new Position(File.A, Rank._1))
                               .Create());

            var rookStart = (from p in kingBoard.WhitePieces where p.Type == PieceType.Rook select p).First();

            kingBoard = kingBoard.PerformMove(MoveBuilder.CreateNormalMove(
                                                  rookStart, rookStart.Position.MoveVert(1), false));

            var rookMoveBack = (from p in kingBoard.WhitePieces where p.Type == PieceType.Rook select p).First();

            kingBoard = kingBoard.PerformMove(MoveBuilder.CreateNormalMove(
                                                  rookMoveBack, rookMoveBack.Position.MoveVert(-1), false));

            var rookBackWhereHeStarted = (from p in kingBoard.WhitePieces where p.Type == PieceType.Rook select p).First();

            Assert.Equal(new Position(File.A, Rank._1), rookBackWhereHeStarted.Position);
            var moves       = kingBoard.GetPossibleMoves(PieceColor.White);
            var castleMoves = (from m in moves
                               where m.Type == MoveType.Castle
                               select m).ToList();

            Assert.Equal(castleMoves.Count, 0);
        }
예제 #8
0
        private Move CheckCastleWithRookLocation(Board board, Position rookPos)
        {
            var pieceInPos = board[rookPos];

            if (pieceInPos == null)
            {
                return(null);
            }
            if (pieceInPos.Type != PieceType.Rook)
            {
                return(null);
            }
            if (pieceInPos.Color != this.Color)
            {
                return(null);
            }
            if (pieceInPos.MoveHistory != null && pieceInPos.MoveHistory.Count > 0)
            {
                return(null);
            }

            int startFile = (int)rookPos.File;
            int myFile    = (int)Position.File;
            int increment = (myFile > startFile) ? 1 : -1;

            // Rook is eligible. Check pieces in between.
            for (int f = startFile + increment; f != myFile; f += increment)
            {
                var pieceInFile = board[(File)f, Position.Rank];
                if (pieceInFile != null)
                {
                    return(null);
                }
                bool kingWillPassThroughThisSquare = Math.Abs(myFile - f) <= 2;
                if (kingWillPassThroughThisSquare)
                {
                    var fakeMove = MoveBuilder.CreateNormalMove(this,
                                                                new Position((File)f, Position.Rank), false);
                    if (board.DoesMovePutKingInCheck(this.Color, fakeMove))
                    {
                        return(null);
                    }
                }
            }

            return(MoveBuilder.CreateCastleMove(this, (Rook)pieceInPos));
        }
예제 #9
0
        public void KingCannotMoveIntoCheck()
        {
            var board = Board.NewEmptyBoard();
            var king  = new PieceBuilder(PieceType.King)
                        .As(PieceColor.White)
                        .At(new Position(File.D, Rank._1))
                        .Create();

            board.AddPiece(king);
            board.AddPiece(new PieceBuilder(PieceType.Rook)
                           .As(PieceColor.Black)
                           .At(new Position(File.E, Rank._8))
                           .Create());

            var move = MoveBuilder.CreateNormalMove(king,
                                                    new Position(File.E, Rank._1), false);

            bool putsMeInCheck = board.DoesMovePutKingInCheck(PieceColor.White, move);

            Assert.True(putsMeInCheck);
        }
예제 #10
0
        private List <Move> FindKingNormalMoves(Board board)
        {
            var moves = new List <Move>();

            for (int x = -1; x <= 1; x++)
            {
                for (int y = -1; y <= 1; y++)
                {
                    // Don't consider 'not moving'
                    if (x == 0 && y == 0)
                    {
                        continue;
                    }
                    // Would this move take us 'out of bounds'?
                    if (!Position.IsOnBoard((int)Position.Rank + y, (int)Position.File + x))
                    {
                        continue;
                    }

                    var newPos        = Position.MoveHoriz(x).MoveVert(y);
                    var existingPiece = board[newPos];
                    if (existingPiece != null)
                    {
                        if (existingPiece.Color != this.Color)
                        {
                            // We can take!
                            moves.Add(MoveBuilder.CreateNormalMove(this, newPos, true));
                        }
                    }
                    else
                    {
                        moves.Add(MoveBuilder.CreateNormalMove(this, newPos, false));
                    }
                }
            }
            return(moves);
        }
예제 #11
0
        private List <Move> GetMovesInDirection <T>(Board board, bool positive)
        {
            var moves = new List <Move>();

            bool isFile       = typeof(T) == typeof(File);
            int  currentValue = isFile
                ? (int)Position.File
                : (int)Position.Rank;
            int incrementValue = positive ? 1 : -1;

            for (int r = currentValue + incrementValue; r <= 8 && r >= 1; r += incrementValue)
            {
                Position newPos;
                if (isFile)
                {
                    newPos = new Position((File)r, Position.Rank);
                }
                else
                {
                    newPos = new Position(Position.File, (Rank)r);
                }
                var newPosPiece = board[newPos];
                if (newPosPiece != null)
                {
                    if (newPosPiece.Color != this.Color)
                    {
                        // Its not null, but its capturable
                        moves.Add(MoveBuilder.CreateNormalMove(this, newPos, true));
                    }
                    break;
                }
                moves.Add(MoveBuilder.CreateNormalMove(this, newPos, false));
            }

            return(moves);
        }