Example #1
0
        public bool CanAttack(ChessColor attacker, ChessPieceCoord victim)
        {
            for (uint x = 0; x < Chess.BoardSize; x++)
            {
                for (uint y = 0; y < Chess.BoardSize; y++)
                {
                    var piece = Board[x + y * Chess.BoardSize];
                    if (piece == null)
                    {
                        continue;
                    }

                    if (piece.Color != attacker)
                    {
                        continue;
                    }

                    if (piece.CanAttack(victim))
                    {
                        // the knight can jump over other pieces and the pawn can only attack a single space
                        if (piece.Type == ChessPieceType.Knight || piece.Type == ChessPieceType.Pawn)
                        {
                            return(true);
                        }

                        var range = Chess.PieceOffsets[piece.Type];
                        for (var i = 0; i < range.Count; i++)
                        {
                            var from = piece.Coord;
                            var to   = new ChessPieceCoord(from);

                            while (true)
                            {
                                to.MoveOffset(range[i]);
                                if (!to.IsValid())
                                {
                                    break;
                                }

                                var toPiece = GetPiece(to);
                                if (toPiece != null)
                                {
                                    if (to.Equals(victim))
                                    {
                                        return(true);
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            return(false);
        }
Example #2
0
        public void GenerateMoves(BasePiece piece, bool single, List <ChessMove> storage)
        {
            var color = piece.Color;

            if (piece.Type == ChessPieceType.Pawn)
            {
                // single
                var from = new ChessPieceCoord(piece.Coord);
                var to   = new ChessPieceCoord(from);
                to.MoveOffset(Chess.PawnOffsets[(int)color, 0]);

                if (GetPiece(to) == null)
                {
                    BuildMove(storage, ChessMoveFlag.Normal, color, piece.Type, from, to);

                    // second
                    to = new ChessPieceCoord(from);
                    to.MoveOffset(Chess.PawnOffsets[(int)color, 1]);

                    if (GetPiece(to) == null && from.Rank == (color == ChessColor.White ? 2 : 7))
                    {
                        BuildMove(storage, ChessMoveFlag.BigPawn, color, piece.Type, from, to);
                    }
                }

                // capture
                for (uint i = 2; i < 4; i++)
                {
                    to = new ChessPieceCoord(from);
                    to.MoveOffset(Chess.PawnOffsets[(int)color, i]);
                    if (!to.IsValid())
                    {
                        continue;
                    }

                    var toPiece = GetPiece(to);
                    if (toPiece != null && toPiece.Color != color)
                    {
                        BuildMove(storage, ChessMoveFlag.Capture, color, piece.Type, from, to);
                    }
                    else if (to.Equals(EnPassantCoord))
                    {
                        BuildMove(storage, ChessMoveFlag.EnPassantCapture, color, piece.Type, from, EnPassantCoord);
                    }
                }
            }
            else
            {
                var range = Chess.PieceOffsets[piece.Type];
                for (var i = 0; i < range.Count; i++)
                {
                    var from = piece.Coord;
                    var to   = new ChessPieceCoord(from);

                    while (true)
                    {
                        to.MoveOffset(range[i]);
                        if (!to.IsValid())
                        {
                            break;
                        }

                        var toPiece = GetPiece(to);
                        if (toPiece != null)
                        {
                            if (toPiece.Color != color)
                            {
                                BuildMove(storage, ChessMoveFlag.Capture, color, piece.Type, from, to);
                            }
                            break;
                        }

                        BuildMove(storage, ChessMoveFlag.Normal, color, piece.Type, from, to);

                        // Knights and Kings can't move more than once
                        if (piece.Type == ChessPieceType.Knight || piece.Type == ChessPieceType.King)
                        {
                            break;
                        }
                    }
                }
            }

            // only check for castling during full board generation or for a single king
            if (!single || piece.Type == ChessPieceType.King)
            {
                if ((Castling[(int)color] & ChessMoveFlag.KingSideCastle | ChessMoveFlag.QueenSideCastle) != 0)
                {
                    var king      = GetPiece(color, ChessPieceType.King);
                    var kingCoord = king.Coord;

                    var opColor = Chess.InverseColor(color);

                    if ((Castling[(int)color] & ChessMoveFlag.KingSideCastle) != 0)
                    {
                        var castlingToK = new ChessPieceCoord(kingCoord);    // destination king
                        castlingToK.MoveOffset(2, 0);
                        var castlingToR = new ChessPieceCoord(kingCoord);    // destination rook
                        castlingToR.MoveOffset(1, 0);

                        if (GetPiece(castlingToR) == null &&
                            GetPiece(castlingToK) == null &&
                            !CanAttack(opColor, kingCoord) &&
                            !CanAttack(opColor, castlingToR) &&
                            !CanAttack(opColor, castlingToK))
                        {
                            BuildMove(storage, ChessMoveFlag.KingSideCastle, color, ChessPieceType.King, kingCoord, castlingToK);
                        }
                    }

                    if ((Castling[(int)color] & ChessMoveFlag.QueenSideCastle) != 0)
                    {
                        var castlingToK = new ChessPieceCoord(kingCoord);    // destination king
                        castlingToK.MoveOffset(-2, 0);
                        var castlingToR = new ChessPieceCoord(kingCoord);    // destination rook
                        castlingToR.MoveOffset(-1, 0);
                        var castlingToI = new ChessPieceCoord(kingCoord);    // intermediate
                        castlingToI.MoveOffset(-3, 0);

                        if (GetPiece(castlingToR) == null &&
                            GetPiece(castlingToK) == null &&
                            GetPiece(castlingToI) == null &&
                            !CanAttack(opColor, kingCoord) &&
                            !CanAttack(opColor, castlingToR) &&
                            !CanAttack(opColor, castlingToK))
                        {
                            BuildMove(storage, ChessMoveFlag.QueenSideCastle, color, ChessPieceType.King, kingCoord, castlingToK);
                        }
                    }
                }
            }
        }