예제 #1
0
        // Filters out moves that would result in a check on the king.
        public static void checkFilter(ref List <Tuple <uint, uint> > moves, Board board, Piece piece)
        {
            string colour = piece.getColour();

            // Find king square
            Square kingSquare = null;

            for (uint j = 0; j < Board.BOARD_SIZE_Y; j++)
            {
                for (uint i = 0; i < Board.BOARD_SIZE_X; i++)
                {
                    kingSquare = board.getSquareAt(i, j);
                    if (kingSquare.getPiece() is King &&
                        kingSquare.getPiece().getColour() == colour)
                    {
                        break;
                    }
                }
                if (kingSquare.getPiece() is King &&
                    kingSquare.getPiece().getColour() == colour)
                {
                    break;
                }
            }

            // Get king position
            uint xKing = kingSquare.getX();
            uint yKing = kingSquare.getY();

            // Check if king has more than one threat
            if ((colour == "white" && kingSquare.getBlackCover() > 1) ||
                (colour == "black" && kingSquare.getWhiteCover() > 1))
            {
                moves.Clear();
            }
            else if ((colour == "white" && kingSquare.getBlackCover() == 1) ||
                     (colour == "black" && kingSquare.getWhiteCover() == 1))
            {
                Piece threat = null;

                // Get all squares with cover of king
                Piece possibleThreat;
                for (uint j = 0; j < Board.BOARD_SIZE_Y; j++)
                {
                    for (uint i = 0; i < Board.BOARD_SIZE_X; i++)
                    {
                        possibleThreat = board.getPieceAt(j, i);
                        if (possibleThreat != null && possibleThreat.getColour() != colour)
                        {
                            // Enemy piece, check if threat
                            List <Tuple <uint, uint> > cover = Rules.getCover(board, possibleThreat);
                            foreach (Tuple <uint, uint> t in cover)
                            {
                                if (t.Item1 == xKing && t.Item2 == yKing)
                                {
                                    // Threat
                                    threat = possibleThreat;
                                    break;
                                }
                            }
                        }
                        if (threat != null)
                        {
                            break;
                        }
                    }
                    if (threat != null)
                    {
                        break;
                    }
                }

                // Remove all moves that do not resolve the check
                List <Tuple <uint, uint> > tmpMoves = new List <Tuple <uint, uint> >(moves);
                Piece p = threat;
                if (p is Knight || p is Pawn)
                {
                    // Must take threat
                    foreach (Tuple <uint, uint> move in tmpMoves)
                    {
                        if (move.Item1 != threat.getX() ||
                            move.Item2 != threat.getY())
                        {
                            // Will not take, remove
                            moves.Remove(move);
                        }
                    }
                }

                tmpMoves = new List <Tuple <uint, uint> >(moves);
                if (p is Rook || p is Queen)
                {
                    // Must take or block threat
                    foreach (Tuple <uint, uint> move in tmpMoves)
                    {
                        if (xKing == p.getX())
                        {
                            // Same x
                            if (!(move.Item1 == xKing &&                                   // Move will move to same x
                                  ((yKing > move.Item2 && move.Item2 >= p.getY()) ||       // Move will block or take when King to the right of Rook
                                   (yKing < move.Item2 && move.Item2 <= p.getY()))))       // Move will block or take when King to the left of Rook
                            {
                                // Will not block or take
                                moves.Remove(move);
                            }
                        }
                        else if (yKing == p.getY())
                        {
                            // Same y
                            if (!(move.Item2 == yKing &&                                   // Move will move to same y
                                  ((xKing > move.Item1 && move.Item1 >= p.getX()) ||       // Move will block or take when King above Rook
                                   (xKing < move.Item1 && move.Item1 <= p.getX()))))       // Move will block or take when King below Rook
                            {
                                // Will not block or take
                                moves.Remove(move);
                            }
                        }
                    }
                }

                tmpMoves = new List <Tuple <uint, uint> >(moves);
                if ((p is Bishop || p is Queen) && !(xKing == p.getX() || yKing == p.getY()))
                {
                    // Must take or block threat
                    int xMod = (xKing > p.getX() ? -1 : 1);
                    int yMod = (yKing > p.getY() ? -1 : 1);

                    // Step from King to Threat
                    int steps = (int)Math.Abs((int)xKing - (uint)p.getX());
                    foreach (Tuple <uint, uint> move in tmpMoves)
                    {
                        // Search for any blocking or taking moves
                        int  x             = (int)xKing;
                        int  y             = (int)yKing;
                        bool foundGoodMove = false;
                        for (int i = 0; i < steps; i++)
                        {
                            x += xMod;
                            y += yMod;

                            if (move.Item1 == x && move.Item2 == y)
                            {
                                foundGoodMove = true;
                                break;
                            }
                        }

                        // Remove if no good move
                        if (!foundGoodMove)
                        {
                            moves.Remove(move);
                        }
                    }
                }
            }



            // ----------------------------------------------------------------------------------------



            // Make sure that no new check is created by a move
            if (board.getSquareAt(piece.getX(), piece.getY()).getEnemyCover(colour))
            {
                // Empty list of squares with cover of this square
                List <Piece> threats = new List <Piece>();

                // Get all squares with cover of self
                Piece p;
                for (uint j = 0; j < Board.BOARD_SIZE_X; j++)
                {
                    for (uint i = 0; i < Board.BOARD_SIZE_Y; i++)
                    {
                        p = board.getPieceAt(j, i);
                        if (p != null && p.getColour() != colour)
                        {
                            // Remove impossible cases
                            if (p is King || p is Knight || p is Pawn)
                            {
                                continue;
                            }

                            // Enemy piece, check if threat
                            List <Tuple <uint, uint> > cover = Rules.getCover(board, p);
                            foreach (Tuple <uint, uint> t in cover)
                            {
                                if (t.Item1 == piece.getX() && t.Item2 == piece.getY())
                                {
                                    // Threat
                                    threats.Add(p);
                                }
                            }
                        }
                    }
                }

                // Check each threat for possible new check
                Piece realThreat = null;
                int   xMod = 0, yMod = 0;
                foreach (Piece threat in threats)
                {
                    int threatX = (int)threat.getX();
                    int threatY = (int)threat.getY();

                    int x = (int)piece.getX();
                    int y = (int)piece.getY();

                    // Find relative position of the threat
                    if (threatX > x)
                    {
                        xMod = -1;              // Threat to the right
                    }
                    else if (threatX == x)
                    {
                        xMod = 0;                     // Threat at same x
                    }
                    else
                    {
                        xMod = 1;   // Treat to the left
                    }
                    if (threatY > y)
                    {
                        yMod = -1;              // Threat above
                    }
                    else if (threatY == y)
                    {
                        yMod = 0;                     // Threat at same y
                    }
                    else
                    {
                        yMod = 1;   // Treat below
                    }
                    // Step from self away from threat.
                    // If king is the first piece found, this is the real threatening piece.
                    Piece firstPiece;
                    while (true)
                    {
                        x += xMod;
                        y += yMod;

                        if (!board.withinBoard(x, y))
                        {
                            break;
                        }

                        firstPiece = board.getPieceAt((uint)x, (uint)y);
                        if (firstPiece != null)
                        {
                            if (firstPiece is King && firstPiece.getColour() == piece.getColour())
                            {
                                // This is the friendly king.
                                realThreat = threat;
                            }
                            break;
                        }
                    }

                    if (realThreat != null)
                    {
                        // Real threat found.
                        break;
                    }
                }

                // If a real new threat is found; remove any moves that do not end on the
                // line between this and king.
                if (realThreat != null)
                {
                    int x = (int)realThreat.getX();
                    int y = (int)realThreat.getY();
                    List <Tuple <uint, uint> > possibleMoves = new List <Tuple <uint, uint> >();

                    // First get all the squares that are on a line between the threat piece and the king,
                    // including the threat, excluding the king.
                    while (true)
                    {
                        possibleMoves.Add(new Tuple <uint, uint>((uint)x, (uint)y));
                        x += xMod;
                        y += yMod;
                        if (x == xKing && y == yKing)
                        {
                            // End of possible moves.
                            break;
                        }
                    }

                    // Remove any moves not in possible list.
                    List <Tuple <uint, uint> > tmp = new List <Tuple <uint, uint> >(moves);
                    foreach (Tuple <uint, uint> move in tmp)
                    {
                        if (!possibleMoves.Contains(move))
                        {
                            moves.Remove(move);
                        }
                    }
                }
            }
        }
예제 #2
0
        private static void checkFilter(ref List <Tuple <uint, uint> > moves, Board board, Piece king)
        {
            uint kx = king.getX();
            uint ky = king.getY();

            List <Piece> threats = new List <Piece>();

            // Make sure no new checks are created by King moving.
            if (board.getSquareAt(kx, ky).getEnemyCover(king.getColour()))
            {
                // King is in check, get all threats
                for (uint y = 0; y < Board.BOARD_SIZE_Y; y++)
                {
                    for (uint x = 0; x < Board.BOARD_SIZE_X; x++)
                    {
                        Piece p = board.getPieceAt(x, y);
                        if (p != null && p.getColour() != king.getColour())
                        {
                            List <Tuple <uint, uint> > cover = Rules.getCover(board, p);
                            if (cover.Contains(new Tuple <uint, uint>(kx, ky)))
                            {
                                threats.Add(p);
                            }
                        }
                    }
                }
            }

            foreach (Piece threat in threats)
            {
                if (threat is Pawn || threat is King || threat is Knight)
                {
                    continue;
                }

                // Get relative position of threat
                uint tx = threat.getX();
                uint ty = threat.getY();
                int  xMod;
                int  yMod;

                if (tx > kx)
                {
                    xMod = -1;
                }
                else if (tx < kx)
                {
                    xMod = 1;
                }
                else
                {
                    xMod = 0;
                }

                if (ty > ky)
                {
                    yMod = -1;
                }
                else if (ty < ky)
                {
                    yMod = 1;
                }
                else
                {
                    yMod = 0;
                }

                // Get square on the other side of king relative to the threat.
                int x = (int)kx + xMod;
                int y = (int)ky + yMod;
                if (board.withinBoard(x, y))
                {
                    List <Tuple <uint, uint> > tmp = new List <Tuple <uint, uint> >(moves);
                    foreach (Tuple <uint, uint> move in tmp)
                    {
                        if (move.Item1 == x && move.Item2 == y)
                        {
                            moves.Remove(move);
                        }
                    }
                }
            }
        }