Beispiel #1
0
        /// <summary>
        /// Slide along the path steps until you hit something. Return path to point and if it ends attacking with the attack.
        /// </summary>
        private static List <position_t> Slide(ChessBoard board, Player p, position_t pos, position_t step)
        {
            List <position_t> moves = new List <position_t>();

            for (int i = 1; i < 8; i++)
            {
                position_t moved = new position_t(pos.letter + i * step.letter, pos.number + i * step.number);

                if (moved.letter < 0 || moved.letter > 7 || moved.number < 0 || moved.number > 7)
                {
                    break;
                }

                if (board.Grid[moved.number][moved.letter].piece != Piece.NONE)
                {
                    if (board.Grid[moved.number][moved.letter].player != p)
                    {
                        moves.Add(moved);
                    }
                    break;
                }
                moves.Add(moved);
            }
            return(moves);
        }
Beispiel #2
0
        /// <summary>
        /// Checks to see if the king for a player is in check. This function
        /// works by pretending the king is each of the different board pieces and seeing if it can attack
        /// any of the same type of price from its current position.
        /// </summary>
        /// <param name="b">Board state</param>
        /// <param name="king">the currnet player</param>
        /// <returns>Is in check</returns>
        public static bool isCheck(ChessBoard b, Player king)
        {
            if (b.Kings.Count == 0)
            {
                return(true);
            }

            position_t king_pos = b.Kings[king];

            if (king_pos.number < 0 || king_pos.letter < 0)
            {
                return(true);
            }

            Piece[] pieces = { Piece.PAWN, Piece.ROOK, Piece.KNIGHT, Piece.BISHOP, Piece.QUEEN, Piece.KING };

            ChessBoard tempBoard = new ChessBoard(b);

            for (int i = 0; i < 6; i++)
            {
                tempBoard.Grid[king_pos.number][king_pos.letter] = new piece_t(pieces[i], king);
                List <position_t> moves = getLegalMove(tempBoard, king_pos, false);
                foreach (var move in moves)
                {
                    if (b.Grid[move.number][move.letter].piece == pieces[i] &&
                        b.Grid[move.number][move.letter].player != king)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Beispiel #3
0
        /// <summary>
        /// Get any legal move from the current position on the provided board.
        /// </summary>
        /// <param name="board">The state of the game.</param>
        /// <param name="pos">The piece/position to check for valid moves.</param>
        /// <param name="verify_check">Whether or not to recurse and check if the current move puts you in check.</param>
        /// <returns>A list of positions the piece can move to.</returns>
        public static List <position_t> getLegalMove(ChessBoard board, position_t pos, bool verify_check = true)
        {
            piece_t p = board.Grid[pos.number][pos.letter];

            if (p.piece == Piece.NONE)
            {
                return(new List <position_t>());
            }

            switch (p.piece)
            {
            case Piece.PAWN:
                return(LegalMoveSet.Pawn(board, pos, verify_check));

            case Piece.ROOK:
                return(LegalMoveSet.Rook(board, pos, verify_check));

            case Piece.KNIGHT:
                return(LegalMoveSet.Knight(board, pos, verify_check));

            case Piece.BISHOP:
                return(LegalMoveSet.Bishop(board, pos, verify_check));

            case Piece.QUEEN:
                return(LegalMoveSet.Queen(board, pos, verify_check));

            case Piece.KING:
                return(LegalMoveSet.King(board, pos, verify_check));

            default:
                return(new List <position_t>());
            }
        }
Beispiel #4
0
        private static List <position_t> Rook(ChessBoard board, position_t pos, bool verify_check = true)
        {
            List <position_t> moves = new List <position_t>();

            piece_t p = board.Grid[pos.number][pos.letter];

            if (p.piece == Piece.NONE)
            {
                return(moves);
            }

            // slide along vert/hor for possible moves
            moves.AddRange(Slide(board, p.player, pos, new position_t(1, 0)));
            moves.AddRange(Slide(board, p.player, pos, new position_t(-1, 0)));
            moves.AddRange(Slide(board, p.player, pos, new position_t(0, 1)));
            moves.AddRange(Slide(board, p.player, pos, new position_t(0, -1)));

            if (verify_check)// make sure each move doesn't put us in check
            {
                for (int i = moves.Count - 1; i >= 0; i--)
                {
                    ChessBoard b2 = LegalMoveSet.move(board, new move_t(pos, moves[i]));
                    if (isCheck(b2, p.player))
                    {
                        moves.RemoveAt(i);
                    }
                }
            }
            return(moves);
        }
Beispiel #5
0
        private static List <position_t> Knight(ChessBoard board, position_t pos, bool verify_check = true)
        {
            List <position_t> moves = new List <position_t>();

            piece_t p = board.Grid[pos.number][pos.letter];

            if (p.piece == Piece.NONE)
            {
                return(moves);
            }

            // collect all relative moves possible
            List <position_t> relative = new List <position_t>();

            relative.Add(new position_t(2, 1));
            relative.Add(new position_t(2, -1));

            relative.Add(new position_t(-2, 1));
            relative.Add(new position_t(-2, -1));

            relative.Add(new position_t(1, 2));
            relative.Add(new position_t(-1, 2));

            relative.Add(new position_t(1, -2));
            relative.Add(new position_t(-1, -2));

            // iterate moves
            foreach (position_t move in relative)
            {
                position_t moved = new position_t(move.letter + pos.letter, move.number + pos.number);

                // bounds check
                if (moved.letter < 0 || moved.letter > 7 || moved.number < 0 || moved.number > 7)
                {
                    continue;
                }

                // if empty space or attacking
                if (board.Grid[moved.number][moved.letter].piece == Piece.NONE ||
                    board.Grid[moved.number][moved.letter].player != p.player)
                {
                    moves.Add(moved);
                }
            }

            if (verify_check)// make sure each move doesn't put us in check
            {
                for (int i = moves.Count - 1; i >= 0; i--)
                {
                    ChessBoard b2 = LegalMoveSet.move(board, new move_t(pos, moves[i]));
                    if (isCheck(b2, p.player))
                    {
                        moves.RemoveAt(i);
                    }
                }
            }
            return(moves);
        }
Beispiel #6
0
        private static bool allowCastle(ChessBoard board, Player player, position_t pos, bool isRight)
        {
            bool isValid = true;
            int  rookPos;
            int  kingDirection;

            if (isRight)
            {
                rookPos       = 7;
                kingDirection = 1;
            }
            else
            {
                rookPos       = 0;
                kingDirection = -1;
            }

            //Check for valid right castling
            // Is the peice at H,7 a rook owned by the player and has it moved
            if (board.Grid[pos.number][rookPos].piece == Piece.ROOK &&
                board.Grid[pos.number][rookPos].player == player && board.Grid[pos.number][rookPos].lastPosition.Equals(new position_t(-1, -1)))
            {
                // Check that the adjacent two squares are empty
                for (int i = 0; i < 2; i++)
                {
                    if (board.Grid[pos.number][pos.letter + (i + 1) * kingDirection].piece != Piece.NONE)
                    {
                        isValid = false;
                        break;
                    }
                }

                // Don't bother running secondary checks if the way isn't even clear
                if (isValid)
                {
                    for (int i = 0; i < 2; i++)
                    {
                        // Move kings postion over i squares to check if king is passing over an attackable
                        // square
                        ChessBoard b2 = LegalMoveSet.move(board, new move_t(pos, new position_t(pos.letter + (i + 1) * kingDirection, pos.number)));

                        // Attackable square is in between king and rook so
                        // its not possible to castle to the right rook
                        if (isCheck(b2, player))
                        {
                            isValid = false;
                            break;
                        }
                    }
                }
            }
            else
            {
                isValid = false;
            }
            return(isValid);
        }
Beispiel #7
0
        public void SetPiece(Piece piece, Player player, int letter, int number)
        {
            // set grid values
            Grid[number][letter].piece  = piece;
            Grid[number][letter].player = player;

            // add piece to list
            Pieces[player].Add(new position_t(letter, number));

            // update king position
            if (piece == Piece.KING)
            {
                Kings[player] = new position_t(letter, number);
            }
        }
Beispiel #8
0
        public void SetRandomPlacement()
        {
            //Add the pieces via using the SetPiece() method
            //Check for placement, then add:
            Random r = new Random();
            int    letter = r.Next(0, 8), number = 0;

            //Pawns

            for (int i = 0; i < 8; i++)
            {
                SetPiece(Piece.PAWN, Player.WHITE, i, 1);
                SetPiece(Piece.PAWN, Player.BLACK, i, 6);
            }

            //Kings
            AssignPiece(Piece.KING, out letter, out number);
            Kings[Player.WHITE] = new position_t(letter, number);
            Kings[Player.BLACK] = new position_t(letter, Mirror(number));

            //Rooks
            AssignPiece(Piece.ROOK, out letter, out number);
            AssignPiece(Piece.ROOK, out letter, out number);

            //Bishops
            AssignPiece(Piece.BISHOP, out letter, out number);
            BishopPos = new position_t(letter, number);
            //Somehow.. get where the bishop was placed.
            AssignPiece(Piece.BISHOP, out letter, out number);


            //Queens
            AssignPiece(Piece.QUEEN, out letter, out number);


            //Knights
            AssignPiece(Piece.KNIGHT, out letter, out number);
            AssignPiece(Piece.KNIGHT, out letter, out number);
        }
Beispiel #9
0
        private static List <position_t> Pawn(ChessBoard board, position_t pos, bool verify_check = true)
        {
            List <position_t> moves = new List <position_t>();

            piece_t p = board.Grid[pos.number][pos.letter];

            if (p.piece == Piece.NONE)
            {
                return(moves);
            }

            // gather relative moves
            List <position_t> relative = new List <position_t>();

            relative.Add(new position_t(-1, 1 * ((p.player == Player.BLACK) ? -1 : 1)));
            relative.Add(new position_t(0, 1 * ((p.player == Player.BLACK) ? -1 : 1)));
            relative.Add(new position_t(0, 2 * ((p.player == Player.BLACK) ? -1 : 1)));
            relative.Add(new position_t(1, 1 * ((p.player == Player.BLACK) ? -1 : 1)));

            // iterate moves
            foreach (position_t move in relative)
            {
                position_t moved = new position_t(move.letter + pos.letter, move.number + pos.number);

                // bounds check
                if (moved.letter < 0 || moved.letter > 7 || moved.number < 0 || moved.number > 7)
                {
                    continue;
                }

                // double forward move
                if (moved.letter == pos.letter && board.Grid[moved.number][moved.letter].piece == Piece.NONE && Math.Abs(moved.number - pos.number) == 2)
                {
                    // check the first step
                    int  step        = -((moved.number - pos.number) / (Math.Abs(moved.number - pos.number)));
                    bool hasnt_moved = pos.number == ((p.player == Player.BLACK) ? 6 : 1);
                    if (board.Grid[moved.number + step][moved.letter].piece == Piece.NONE && hasnt_moved)
                    {
                        moves.Add(moved);
                    }
                }
                // if it's not blocked we can move forward
                else if (moved.letter == pos.letter && board.Grid[moved.number][moved.letter].piece == Piece.NONE)
                {
                    moves.Add(moved);
                }
                // angled attack
                else if (moved.letter != pos.letter && board.Grid[moved.number][moved.letter].piece != Piece.NONE && board.Grid[moved.number][moved.letter].player != p.player)
                {
                    moves.Add(moved);
                }
                // en passant
                else if (isEnPassant(board, new move_t(pos, moved)))
                {
                    moves.Add(moved);
                }
            }

            if (verify_check)// make sure each move doesn't put us in check
            {
                for (int i = moves.Count - 1; i >= 0; i--)
                {
                    ChessBoard b2 = LegalMoveSet.move(board, new move_t(pos, moves[i]));
                    if (isCheck(b2, p.player))
                    {
                        moves.RemoveAt(i);
                    }
                }
            }
            return(moves);
        }
Beispiel #10
0
        private static List <position_t> King(ChessBoard board, position_t pos, bool verify_check = true)
        {
            List <position_t> moves = new List <position_t>();

            piece_t p = board.Grid[pos.number][pos.letter];

            if (p.piece == Piece.NONE)
            {
                return(moves);
            }

            // collect all relative moves possible
            List <position_t> relative = new List <position_t>();

            relative.Add(new position_t(-1, 1));
            relative.Add(new position_t(0, 1));
            relative.Add(new position_t(1, 1));

            relative.Add(new position_t(-1, 0));
            relative.Add(new position_t(1, 0));

            relative.Add(new position_t(-1, -1));
            relative.Add(new position_t(0, -1));
            relative.Add(new position_t(1, -1));

            // Iterate moves
            foreach (position_t move in relative)
            {
                position_t moved = new position_t(move.letter + pos.letter, move.number + pos.number);

                // bound check
                if (moved.letter < 0 || moved.letter > 7 || moved.number < 0 || moved.number > 7)
                {
                    continue;
                }

                // if it's not blocked we can move
                if (board.Grid[moved.number][moved.letter].piece == Piece.NONE || board.Grid[moved.number][moved.letter].player != p.player)
                {
                    if (verify_check) // make sure we don't put ourselves in check
                    {
                        ChessBoard b2 = LegalMoveSet.move(board, new move_t(pos, moved));
                        if (!isCheck(b2, p.player))
                        {
                            moves.Add(moved);
                        }
                    }
                    else
                    {
                        moves.Add(moved);
                    }
                }
            }

            // Castling

            /* A king can only castle if:
             * king has not moved
             * rook has not moved
             * king is not in check
             * king does not end up in check
             * king does not pass through any other peieces
             * king does not pass through any squares under attack
             * king knows secret handshake
             */
            if (verify_check)
            {
                if (!isCheck(board, p.player) &&
                    p.lastPosition.Equals(new position_t(-1, -1)))
                {
                    bool castleRight = allowCastle(board, p.player, pos, true);
                    bool castleLeft  = allowCastle(board, p.player, pos, false);

                    if (castleRight)
                    {
                        moves.Add(new position_t(6, pos.number));
                    }
                    if (castleLeft)
                    {
                        moves.Add(new position_t(2, pos.number));
                    }
                }
            }

            return(moves);
        }
Beispiel #11
0
        /// <summary>
        /// Slide along the path steps until you hit something. Return path to point and if it ends attacking with the attack.
        /// </summary>
        private static List<position_t> Slide(ChessBoard board, Player p, position_t pos, position_t step)
        {
            List<position_t> moves = new List<position_t>();
            for (int i = 1; i < 8; i++)
            {
                position_t moved = new position_t(pos.letter + i * step.letter, pos.number + i * step.number);

                if (moved.letter < 0 || moved.letter > 7 || moved.number < 0 || moved.number > 7)
                    break;

                if (board.Grid[moved.number][moved.letter].piece != Piece.NONE)
                {
                    if (board.Grid[moved.number][moved.letter].player != p)
                        moves.Add(moved);
                    break;
                }
                moves.Add(moved);
            }
            return moves;
        }
Beispiel #12
0
        public List<position_t> Select(position_t pos)
        {
            // has previously selected something
            if (this.Board.Grid[this.Selection.number][this.Selection.letter].piece != Piece.NONE
                && this.Turn == this.Board.Grid[this.Selection.number][this.Selection.letter].player
                && (this.m_nPlayers == 2 
                || this.Turn == Player.WHITE)) 
            {
                // get previous selections moves and determine if we chose a legal one by clicking
                List<position_t> moves = LegalMoveSet.getLegalMove(this.Board, this.Selection);
                foreach (position_t move in moves)
                {
                    if (move.Equals(pos))
                    {
                        // we selected a legal move so update the board
                        MakeMove(new move_t(this.Selection, pos));

                        // If piece that was just moved is a king and it moved anyhthing other than 1 square, it was 
                        // a castling move, so we need to move the rook
                        if (this.Board.Grid[pos.number][pos.letter].piece == Piece.KING && Math.Abs(pos.letter - this.Selection.letter) == 2)
                        {
                            int row = (this.Turn == Player.WHITE) ? 0 : 7;

                            // Left rook
                            if (pos.letter < 4)
                            {
                                LegalMoveSet.move(this.Board, new move_t(new position_t(0, row), new position_t(3, row)));
                            }
                            // right rook
                            else
                            {
                                LegalMoveSet.move(this.Board, new move_t(new position_t(7, row), new position_t(5, row)));
                            }
                        }
                                
                        // finish move
                        switchPlayer();
                        if (detectCheckmate()) return new List<position_t>();

                        if (this.m_nPlayers == 1) // start ai
                        {
                            new Thread(AISelect).Start(); // thread turn
                        }
                        return new List<position_t>();
                    }
                }
            }

            // first click, let's show possible moves
            if (this.Board.Grid[pos.number][pos.letter].player == this.Turn && (this.m_nPlayers == 2 || this.Turn == Player.WHITE))
            {
                List<position_t> moves = LegalMoveSet.getLegalMove(this.Board, pos);
                this.Selection = pos;
                return moves;
            }

            // reset
            this.Selection = new position_t();
            return new List<position_t>();
        }
Beispiel #13
0
        public void SetPiece(Piece piece, Player player, int letter, int number)
        {
            // set grid values
            Grid[number][letter].piece = piece;
            Grid[number][letter].player = player;

            // add piece to list
            Pieces[player].Add(new position_t(letter, number));

            // update king position
            if (piece == Piece.KING)
            {
                Kings[player] = new position_t(letter, number);
            }
        }
Beispiel #14
0
        private static List<position_t> Pawn(ChessBoard board, position_t pos, bool verify_check = true)
        {
            List<position_t> moves = new List<position_t>();

            piece_t p = board.Grid[pos.number][pos.letter];
            if (p.piece == Piece.NONE) return moves;

            // gather relative moves
            List<position_t> relative = new List<position_t>();
            relative.Add(new position_t(-1, 1 * ((p.player == Player.BLACK) ? -1 : 1)));
            relative.Add(new position_t(0, 1 * ((p.player == Player.BLACK) ? -1 : 1)));
            relative.Add(new position_t(0, 2 * ((p.player == Player.BLACK) ? -1 : 1)));
            relative.Add(new position_t(1, 1 * ((p.player == Player.BLACK) ? -1 : 1)));

            // iterate moves
            foreach (position_t move in relative)
            {
                position_t moved = new position_t(move.letter + pos.letter, move.number + pos.number);

                // bounds check
                if (moved.letter < 0 || moved.letter > 7 || moved.number < 0 || moved.number > 7)
                    continue;

                // double forward move
                if (moved.letter == pos.letter && board.Grid[moved.number][moved.letter].piece == Piece.NONE && Math.Abs(moved.number - pos.number) == 2)
                {
                    // check the first step
                    int step = -((moved.number - pos.number) / (Math.Abs(moved.number - pos.number)));
                    bool hasnt_moved = pos.number == ((p.player == Player.BLACK) ? 6 : 1);
                    if (board.Grid[moved.number + step][moved.letter].piece == Piece.NONE && hasnt_moved)
                    {
                        moves.Add(moved);
                    }
                }
                // if it's not blocked we can move forward
                else if (moved.letter == pos.letter && board.Grid[moved.number][moved.letter].piece == Piece.NONE)
                {
                    moves.Add(moved);
                }
                // angled attack
                else if (moved.letter != pos.letter && board.Grid[moved.number][moved.letter].piece != Piece.NONE && board.Grid[moved.number][moved.letter].player != p.player)
                {
                    moves.Add(moved);
                }
                // en passant
                else if(isEnPassant(board, new move_t(pos,moved)))
                {
                    moves.Add(moved);
                }
            }

            if (verify_check)// make sure each move doesn't put us in check
            {
                for (int i = moves.Count - 1; i >= 0; i--)
                {
                    ChessBoard b2 = LegalMoveSet.move(board, new move_t(pos, moves[i]));
                    if (isCheck(b2, p.player))
                    {
                        moves.RemoveAt(i);
                    }
                }
            }
            return moves;
        }
Beispiel #15
0
        private static List<position_t> Rook(ChessBoard board, position_t pos, bool verify_check = true)
        {
            List<position_t> moves = new List<position_t>();

            piece_t p = board.Grid[pos.number][pos.letter];
            if (p.piece == Piece.NONE) return moves;

            // slide along vert/hor for possible moves
            moves.AddRange(Slide(board, p.player, pos, new position_t(1, 0)));
            moves.AddRange(Slide(board, p.player, pos, new position_t(-1, 0)));
            moves.AddRange(Slide(board, p.player, pos, new position_t(0, 1)));
            moves.AddRange(Slide(board, p.player, pos, new position_t(0, -1)));

            if (verify_check)// make sure each move doesn't put us in check
            {
                for (int i = moves.Count - 1; i >= 0; i--)
                {
                    ChessBoard b2 = LegalMoveSet.move(board, new move_t(pos, moves[i]));
                    if (isCheck(b2, p.player))
                    {
                        moves.RemoveAt(i);
                    }
                }
            }
            return moves;
        }
Beispiel #16
0
        private static List<position_t> Knight(ChessBoard board, position_t pos, bool verify_check = true)
        {
            List<position_t> moves = new List<position_t>();

            piece_t p = board.Grid[pos.number][pos.letter];
            if (p.piece == Piece.NONE) return moves;

            // collect all relative moves possible
            List<position_t> relative = new List<position_t>();

            relative.Add(new position_t(2, 1));
            relative.Add(new position_t(2, -1));

            relative.Add(new position_t(-2, 1));
            relative.Add(new position_t(-2, -1));

            relative.Add(new position_t(1, 2));
            relative.Add(new position_t(-1, 2));

            relative.Add(new position_t(1, -2));
            relative.Add(new position_t(-1, -2));

            // iterate moves
            foreach (position_t move in relative)
            {
                position_t moved = new position_t(move.letter + pos.letter, move.number + pos.number);

                // bounds check
                if (moved.letter < 0 || moved.letter > 7 || moved.number < 0 || moved.number > 7)
                    continue;

                // if empty space or attacking
                if (board.Grid[moved.number][moved.letter].piece == Piece.NONE ||
                    board.Grid[moved.number][moved.letter].player != p.player) 
                    moves.Add(moved);
            }

            if (verify_check)// make sure each move doesn't put us in check
            {
                for (int i = moves.Count - 1; i >= 0; i--)
                {
                    ChessBoard b2 = LegalMoveSet.move(board, new move_t(pos, moves[i]));
                    if (isCheck(b2, p.player))
                    {
                        moves.RemoveAt(i);
                    }
                }
            }
            return moves;
        }
Beispiel #17
0
        private static bool allowCastle(ChessBoard board, Player player, position_t pos, bool isRight)
        {
            bool isValid = true;
            int rookPos;
            int kingDirection;
            if (isRight)
            {
                rookPos = 7;
                kingDirection = 1;
            }
            else
            {
                rookPos = 0;
                kingDirection = -1;
            }

            //Check for valid right castling
            // Is the peice at H,7 a rook owned by the player and has it moved
            if (board.Grid[pos.number][rookPos].piece == Piece.ROOK &&
                board.Grid[pos.number][rookPos].player == player && board.Grid[pos.number][rookPos].lastPosition.Equals(new position_t(-1,-1)))
            {
                // Check that the adjacent two squares are empty
                for (int i = 0; i < 2; i++)
                {
                    if (board.Grid[pos.number][pos.letter + (i + 1) * kingDirection].piece != Piece.NONE)
                    {
                        isValid = false;
                        break;
                    }
                }

                // Don't bother running secondary checks if the way isn't even clear
                if (isValid)
                {
                    for (int i = 0; i < 2; i++)
                    {
                        // Move kings postion over i squares to check if king is passing over an attackable
                        // square
                        ChessBoard b2 = LegalMoveSet.move(board, new move_t(pos, new position_t(pos.letter + (i + 1) * kingDirection, pos.number)));

                        // Attackable square is in between king and rook so
                        // its not possible to castle to the right rook
                        if (isCheck(b2, player))
                        {
                            isValid = false;
                            break;
                        }
                    }
                }
            }
            else
            {
                isValid = false;
            }
            return isValid;
        }
Beispiel #18
0
        private static List<position_t> King(ChessBoard board, position_t pos, bool verify_check = true)
        {
            List<position_t> moves = new List<position_t>();

            piece_t p = board.Grid[pos.number][pos.letter];
            if (p.piece == Piece.NONE) return moves;

            // collect all relative moves possible
            List<position_t> relative = new List<position_t>();

            relative.Add(new position_t(-1, 1));
            relative.Add(new position_t(0, 1));
            relative.Add(new position_t(1, 1));

            relative.Add(new position_t(-1, 0));
            relative.Add(new position_t(1, 0));

            relative.Add(new position_t(-1, -1));
            relative.Add(new position_t(0, -1));
            relative.Add(new position_t(1, -1));

            // Iterate moves
            foreach (position_t move in relative)
            {
                position_t moved = new position_t(move.letter + pos.letter, move.number + pos.number);

                // bound check
                if (moved.letter < 0 || moved.letter > 7 || moved.number < 0 || moved.number > 7)
                    continue;

                // if it's not blocked we can move
                if (board.Grid[moved.number][moved.letter].piece == Piece.NONE || board.Grid[moved.number][moved.letter].player != p.player)
                {
                    if (verify_check) // make sure we don't put ourselves in check
                    {
                        ChessBoard b2 = LegalMoveSet.move(board, new move_t(pos, moved));
                        if(!isCheck(b2, p.player))
                        {
                            moves.Add(moved);
                        }
                    }
                    else
                    {
                        moves.Add(moved);
                    }
                }
            }
			
			// Castling
            /* A king can only castle if:
             * king has not moved
             * rook has not moved
             * king is not in check
             * king does not end up in check
             * king does not pass through any other peieces
             * king does not pass through any squares under attack
             * king knows secret handshake
             */
            if (verify_check)
            {
                if (!isCheck(board, p.player)
                    && p.lastPosition.Equals(new position_t(-1,-1)))
                {
                    bool castleRight = allowCastle(board, p.player, pos, true);
                    bool castleLeft = allowCastle(board, p.player, pos, false);

                    if (castleRight)
                    {
                        moves.Add(new position_t(6, pos.number));
                    }
                    if (castleLeft)
                    {
                        moves.Add(new position_t(2, pos.number));
                    }
                }
            }

            return moves;
        }
Beispiel #19
0
        public List <position_t> Select(position_t pos)
        {
            // has previously selected something
            if (this.Board.Grid[this.Selection.number][this.Selection.letter].piece != Piece.NONE &&
                this.Turn == this.Board.Grid[this.Selection.number][this.Selection.letter].player &&
                (this.m_nPlayers == 2 ||
                 this.Turn == Player.WHITE))
            {
                // get previous selections moves and determine if we chose a legal one by clicking
                List <position_t> moves = LegalMoveSet.getLegalMove(this.Board, this.Selection);
                foreach (position_t move in moves)
                {
                    if (move.Equals(pos))
                    {
                        // we selected a legal move so update the board
                        MakeMove(new move_t(this.Selection, pos));

                        // If piece that was just moved is a king and it moved anyhthing other than 1 square, it was
                        // a castling move, so we need to move the rook
                        if (this.Board.Grid[pos.number][pos.letter].piece == Piece.KING && Math.Abs(pos.letter - this.Selection.letter) == 2)
                        {
                            int row = (this.Turn == Player.WHITE) ? 0 : 7;

                            // Left rook
                            if (pos.letter < 4)
                            {
                                LegalMoveSet.move(this.Board, new move_t(new position_t(0, row), new position_t(3, row)));
                            }
                            // right rook
                            else
                            {
                                LegalMoveSet.move(this.Board, new move_t(new position_t(7, row), new position_t(5, row)));
                            }
                        }

                        // finish move
                        switchPlayer();
                        if (detectCheckmate())
                        {
                            return(new List <position_t>());
                        }

                        if (this.m_nPlayers == 1)         // start ai
                        {
                            new Thread(AISelect).Start(); // thread turn
                        }
                        return(new List <position_t>());
                    }
                }
            }

            // first click, let's show possible moves
            if (this.Board.Grid[pos.number][pos.letter].player == this.Turn && (this.m_nPlayers == 2 || this.Turn == Player.WHITE))
            {
                List <position_t> moves = LegalMoveSet.getLegalMove(this.Board, pos);
                this.Selection = pos;
                return(moves);
            }

            // reset
            this.Selection = new position_t();
            return(new List <position_t>());
        }
Beispiel #20
0
        /// <summary>
        /// Get any legal move from the current position on the provided board.
        /// </summary>
        /// <param name="board">The state of the game.</param>
        /// <param name="pos">The piece/position to check for valid moves.</param>
        /// <param name="verify_check">Whether or not to recurse and check if the current move puts you in check.</param>
        /// <returns>A list of positions the piece can move to.</returns>
        public static List<position_t> getLegalMove(ChessBoard board, position_t pos, bool verify_check = true)
        {
            piece_t p = board.Grid[pos.number][pos.letter];
            if (p.piece == Piece.NONE) return new List<position_t>();

            switch (p.piece)
            {
                case Piece.PAWN:
                    return LegalMoveSet.Pawn(board, pos, verify_check);
                case Piece.ROOK:
                    return LegalMoveSet.Rook(board, pos, verify_check);
                case Piece.KNIGHT:
                    return LegalMoveSet.Knight(board, pos, verify_check);
                case Piece.BISHOP:
                    return LegalMoveSet.Bishop(board, pos, verify_check);
                case Piece.QUEEN:
                    return LegalMoveSet.Queen(board, pos, verify_check);
                case Piece.KING:
                    return LegalMoveSet.King(board, pos, verify_check);
                default:
                    return new List<position_t>();
            }
        }