Exemple #1
0
        private List <ChessMove> MakeMove(ChessMove move, bool validateCheck)
        {
            var executedMoves  = new List <ChessMove>();
            var boardChanges   = new List <ChessBoardChange>();
            var availableMoves = GetAvailableMoves(CurrentPlayer, move.From.HorizontalLocation, move.From.VerticalLocation, validateCheck);

            ChessMove selectedMove = availableMoves.Where(o => o.CompareTo(move) == 0).FirstOrDefault();

            if (selectedMove == null)
            {
                throw new ArgumentOutOfRangeException("move", "Invalid move!");
            }

            executedMoves.Add(selectedMove);

            switch (selectedMove.SpecialMove)
            {
            case ChessSpecialMove.EnPassant:
                var enPassantPiece = _pieces[selectedMove.To.HorizontalLocation, selectedMove.From.VerticalLocation];
                executedMoves.Add(
                    new ChessMove(
                        enPassantPiece.Rank, enPassantPiece.Player,
                        selectedMove.To.HorizontalLocation, selectedMove.From.VerticalLocation,
                        ChessBoardLocation.OUTSIDE_BOARD, ChessBoardLocation.OUTSIDE_BOARD, ChessSpecialMove.Capture));

                _pieces[selectedMove.To.HorizontalLocation, selectedMove.From.VerticalLocation] = ChessBoardPiece.Empty;

                // Capture in board change (in en passant case):
                boardChanges.Add(new ChessBoardChange(selectedMove.To.HorizontalLocation, selectedMove.From.VerticalLocation, PieceSelection.Capture));
                break;

            case ChessSpecialMove.Castling:
                int rookStartColumn;
                int rookEndColumn;
                if (selectedMove.From.HorizontalLocation < selectedMove.To.HorizontalLocation)
                {
                    // Right hand side castling
                    rookStartColumn = 7;
                    rookEndColumn   = selectedMove.To.HorizontalLocation - 1;
                }
                else
                {
                    // Left hand side castling
                    rookStartColumn = 0;
                    rookEndColumn   = selectedMove.To.HorizontalLocation + 1;
                }

                var rookPiece = _pieces[rookStartColumn, selectedMove.From.VerticalLocation];
                executedMoves.Add(
                    new ChessMove(
                        rookPiece.Rank, rookPiece.Player,
                        rookStartColumn, selectedMove.From.VerticalLocation,
                        rookEndColumn, selectedMove.To.VerticalLocation, ChessSpecialMove.Castling));

                _pieces[rookStartColumn, selectedMove.From.VerticalLocation] = ChessBoardPiece.Empty;
                _pieces[rookEndColumn, selectedMove.From.VerticalLocation]   = new ChessBoardPiece(rookPiece.Player, rookPiece.Rank);
                break;

            case ChessSpecialMove.Promotion:
                executedMoves.Add(
                    new ChessMove(
                        selectedMove.Rank, selectedMove.Player,
                        selectedMove.From.HorizontalLocation, selectedMove.From.VerticalLocation,
                        ChessBoardLocation.OUTSIDE_BOARD, ChessBoardLocation.OUTSIDE_BOARD, ChessSpecialMove.PromotionOut));

                executedMoves.Add(
                    new ChessMove(
                        PieceRank.Queen, selectedMove.Player,
                        ChessBoardLocation.OUTSIDE_BOARD, ChessBoardLocation.OUTSIDE_BOARD,
                        selectedMove.To.HorizontalLocation, selectedMove.To.VerticalLocation, ChessSpecialMove.PromotionIn));

                // Use default promotion to queen:
                ChessBoardPiece piece = _pieces[selectedMove.From.HorizontalLocation, selectedMove.From.VerticalLocation];
                piece = new ChessBoardPiece(piece.Player, PieceRank.Queen);
                _pieces[selectedMove.From.HorizontalLocation, selectedMove.From.VerticalLocation] = piece;
                break;

            case ChessSpecialMove.Check:
                break;

            case ChessSpecialMove.CheckMate:
                break;

            case ChessSpecialMove.None:
                break;
            }

            if (_pieces[selectedMove.To.HorizontalLocation, selectedMove.To.VerticalLocation].Rank != PieceRank.None)
            {
                // Capture so let's store it
                var capturePiece = _pieces[selectedMove.To.HorizontalLocation, selectedMove.To.VerticalLocation];
                executedMoves.Add(
                    new ChessMove(
                        capturePiece.Rank, capturePiece.Player,
                        selectedMove.To.HorizontalLocation, selectedMove.To.VerticalLocation,
                        ChessBoardLocation.OUTSIDE_BOARD, ChessBoardLocation.OUTSIDE_BOARD, ChessSpecialMove.Capture));

                // Capture in board change:
                boardChanges.Add(new ChessBoardChange(selectedMove.To.HorizontalLocation, selectedMove.To.VerticalLocation, PieceSelection.Capture));
            }
            else
            {
                // Move to as board change:
                boardChanges.Add(new ChessBoardChange(selectedMove.To.HorizontalLocation, selectedMove.To.VerticalLocation, PieceSelection.PreviousMoveTo));
            }

            _pieces[selectedMove.To.HorizontalLocation, selectedMove.To.VerticalLocation]     = _pieces[selectedMove.From.HorizontalLocation, selectedMove.From.VerticalLocation];
            _pieces[selectedMove.From.HorizontalLocation, selectedMove.From.VerticalLocation] = ChessBoardPiece.Empty;

            // Move from as board change:
            boardChanges.Add(new ChessBoardChange(selectedMove.From.HorizontalLocation, selectedMove.From.VerticalLocation, PieceSelection.PreviousMoveFrom));

            _previousMove = selectedMove;
            CurrentPlayer = CurrentPlayer == PiecePlayer.White ? PiecePlayer.Black : PiecePlayer.White;

            _moves.Push(executedMoves);
            _boardChanges.Push(boardChanges);

            return(executedMoves);
        }
Exemple #2
0
        private void GetKingCastlingMove(PiecePlayer player, List <ChessMove> moves, int column, int row, int rookColumn, bool validateCheck)
        {
            var rookPosition = _pieces[rookColumn, row];

            if (rookPosition.Player != player || rookPosition.Rank != PieceRank.Rook)
            {
                // Not current players rook
                return;
            }

            var rookRow = player == PiecePlayer.White ? 1 : 8;

            // Rook is at start location. Has it moved earlier?
            var rooksEarlierMove = _moves.Where(
                m => m.First().Player == player && m.First().Rank == PieceRank.Rook &&
                m.First().From.VerticalLocation == rookRow &&
                m.First().From.HorizontalLocation == rookColumn).FirstOrDefault();

            if (rooksEarlierMove != null)
            {
                // Rook has already moved so castling is not anymore available
                return;
            }

            bool ownKingUnderThreat = false;

            ChessMove[] opponentMoves = new ChessMove[0];
            if (validateCheck == true)
            {
                opponentMoves = GetBoardThreats(
                    out ownKingUnderThreat,
                    CurrentPlayer == PiecePlayer.White ? PiecePlayer.Black : PiecePlayer.White);
            }

            if (ownKingUnderThreat == false)
            {
                // Set defaults to left hand side rook castling
                int delta       = -2;
                int startColumn = 2;
                int endColumn   = column;

                if (rookColumn > endColumn)
                {
                    delta       = 2;
                    startColumn = column + 1;
                    endColumn   = rookColumn;
                }

                for (int currentColumn = startColumn; currentColumn < endColumn; currentColumn++)
                {
                    if (_pieces[currentColumn, row].Player != PiecePlayer.None)
                    {
                        return;
                    }

                    ChessMove opponentMove = opponentMoves.Where(
                        o => o.To.HorizontalLocation == currentColumn && o.To.VerticalLocation == row).FirstOrDefault();
                    if (opponentMove != null)
                    {
                        return;
                    }
                }

                // This castling move is valid
                moves.Add(new ChessMove(PieceRank.King, player, column, row, column + delta, row, ChessSpecialMove.Castling));
            }
        }
Exemple #3
0
 public List <ChessMove> MakeMove(ChessMove move)
 {
     return(MakeMove(move, true));
 }
Exemple #4
0
        private ChessMove[] GetAvailableMoves(PiecePlayer player, int column, int row, bool validateCheck)
        {
            List <ChessMove> moves = new List <ChessMove>();

            if (player == PiecePlayer.None)
            {
                // Game over already
                return(moves.ToArray());
            }

            if (_pieces[column, row].Player == player)
            {
                switch (_pieces[column, row].Rank)
                {
                case PieceRank.Pawn:
                    GetPawnMoves(player, moves, column, row);
                    break;

                case PieceRank.Knight:
                    GetKnightMove(player, moves, column, row);
                    break;

                case PieceRank.Bishop:
                    GetBishopMove(player, moves, column, row);
                    break;

                case PieceRank.Rook:
                    GetRookMove(player, moves, column, row);
                    break;

                case PieceRank.Queen:
                    GetQueenMove(player, moves, column, row);
                    break;

                case PieceRank.King:
                    GetKingMove(player, moves, column, row, validateCheck);
                    break;

                default:
                    break;
                }

                // Validate all moves
                for (int i = moves.Count - 1; i >= 0; i--)
                {
                    bool      invalidMove = false;
                    ChessMove move        = moves[i];

                    if (move.To.HorizontalLocation < 0 || move.To.HorizontalLocation > BOARD_SIZE - 1)
                    {
                        // Out of bounds
                        invalidMove = true;
                    }
                    else if (move.To.VerticalLocation < 0 || move.To.VerticalLocation > BOARD_SIZE - 1)
                    {
                        // Out of bounds
                        invalidMove = true;
                    }
                    else if (_pieces[move.To.HorizontalLocation, move.To.VerticalLocation].Player == player)
                    {
                        // Already occupied by team mate
                        invalidMove = true;
                    }

                    if (invalidMove == false && validateCheck == true)
                    {
                        // Let's see if this move would cause check
                        MakeMove(move, false);
                        GetBoardThreats(out var ownKingUnderThreat);
                        if (ownKingUnderThreat == true)
                        {
                            invalidMove = true;
                        }

                        Undo();
                    }

                    if (invalidMove == true)
                    {
                        moves.RemoveAt(i);
                    }
                }
            }

            return(moves.ToArray());
        }