예제 #1
0
 //checks if same colour
 public bool isSameColour(Piece P)
 {
     if (P.getColour() == this.colour)
     {
         return(true);
     }
     else
     {
         return(false);
     }
 }
예제 #2
0
        // Returns a list of all covered squares
        public static List<Tuple<uint, uint>> getCover(Board board, Piece piece)
        {
            int x, y;
            int yMod = (piece.getColour() == "white" ? 1 : -1);
            List<Tuple<uint, uint>> cover = new List<Tuple<uint, uint>>();

            x = (int)piece.getX() - 1;
            y = (int)piece.getY() + yMod;
            if (board.withinBoard(x, y))
            {
                cover.Add(new Tuple<uint, uint>((uint)x, (uint)y));
            }

            x = (int)piece.getX() + 1;
            if (board.withinBoard(x, y))
            {
                cover.Add(new Tuple<uint, uint>((uint)x, (uint)y));
            }

            return cover;
        }
예제 #3
0
 //checks if same colour
 public bool isSameColour(Piece P)
 {
     if (P.getColour() == this.colour)
         return true;
     else
         return false;
 }
예제 #4
0
        public bool makeMove(string col, Move move)
        {
            uint x1 = move.FromX;
            uint y1 = move.FromY;
            uint x2 = move.ToX;
            uint y2 = move.ToY;

            Piece  p         = getPieceAt(x1, y1);
            Square s1        = getSquareAt(x1, y1);
            Square s2        = getSquareAt(x2, y2);
            bool   castling  = false;
            bool   enPassant = false;

            // Check if squares are ok.
            if (s1 == null || s2 == null)
            {
                return(false);
            }

            // Check if piece is ok.
            if (p == null)
            {
                return(false);
            }
            if (p.getColour() != col)
            {
                return(false);
            }
            // Move is legal

            //Check if this is a castling
            if ((p is King) && (((x1 - x2) == 2) || ((x2 - x1) == 2)))
            {
                castling = true;
            }

            // Special handling for pawns
            if ((p is Pawn))
            {
                // Check double step
                if (Math.Abs((int)move.FromY - (int)move.ToY) == 2)
                {
                    ((Pawn)p).setDoubleStepTurn(getTurn());
                }

                //Check if en passant
                if ((getSquareAt(x2, y2).getPiece() == null) && (x1 != x2))
                {
                    enPassant = true;
                }
            }

            // Remove from old position
            s1.removePiece();
            // Add to new position
            if ((p is Pawn && p.getColour() == "white" && y2 == 7) ||
                (p is Pawn && p.getColour() == "black" && y2 == 0))
            {
                p = new Queen(x1, y1, p.getColour());
            }
            s2.setPiece(p);
            p.move(x2, y2);

            // Handles the special castling case
            if (castling)
            {
                uint x2rook;
                uint x1rook;
                if (x2 > x1)// Castling right
                {
                    x1rook = 7;
                    x2rook = x2 - 1;
                }
                else
                {
                    x1rook = 0;
                    x2rook = x2 + 1;
                }
                Square s3 = getSquareAt(x1rook, y1);
                Piece  p3 = s3.getPiece();
                Square s4 = getSquareAt(x2rook, y1);
                s3.removePiece();
                s4.setPiece(p3);
                p3.move(x2rook, y2);
            }

            // Handles the special en passant case
            if (enPassant)
            {
                int yMod;
                if (p.getColour() == "white")
                {
                    yMod = -1;
                }
                else
                {
                    yMod = 1;
                }
                Square s3 = getSquareAt(x2, (uint)(y2 + yMod));
                Piece  p3 = s3.getPiece();
                s3.removePiece();
            }

            updateCover();
            return(true);
        }
예제 #5
0
        // Check if black piece at x, y
        public bool isBlack(uint x, uint y)
        {
            Piece p = getPieceAt(x, y);

            return(p != null && p.getColour() == COLOUR_BLACK);
        }
예제 #6
0
        // Check if white piece at x, y
        public bool isWhite(uint x, uint y)
        {
            Piece p = getPieceAt(x, y);

            return(p != null && p.getColour() == COLOUR_WHITE);
        }
예제 #7
0
        public static List<Tuple<uint, uint>> getPossibleMoves(Board board, Piece piece)
        {
            List<Tuple<uint, uint>> moves = new List<Tuple<uint, uint>>();

            // Check down moves
            int x = (int)piece.getX();
            int y = (int)piece.getY();
            while (true)
            {
                y--;
                if (!board.withinBoard(x, y))
                {
                    break;
                }

                Piece p = board.getPieceAt((uint)x, (uint)y);
                if (p == null)
                {
                    moves.Add(new Tuple<uint, uint>((uint)x, (uint)y));
                }
                else
                {
                    if (p.getColour() != piece.getColour())
                    {
                        moves.Add(new Tuple<uint, uint>((uint)x, (uint)y));
                        break;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            // Check up moves
            x = (int)piece.getX();
            y = (int)piece.getY();
            while (true)
            {
                y++;
                if (!board.withinBoard(x, y))
                {
                    break;
                }

                Piece p = board.getPieceAt((uint)x, (uint)y);
                if (p == null)
                {
                    moves.Add(new Tuple<uint, uint>((uint)x, (uint)y));
                }
                else
                {
                    if (p.getColour() != piece.getColour())
                    {
                        moves.Add(new Tuple<uint, uint>((uint)x, (uint)y));
                        break;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            // Check right moves
            x = (int)piece.getX();
            y = (int)piece.getY();
            while (true)
            {
                x++;
                if (!board.withinBoard(x, y))
                {
                    break;
                }

                Piece p = board.getPieceAt((uint)x, (uint)y);
                if (p == null)
                {
                    moves.Add(new Tuple<uint, uint>((uint)x, (uint)y));
                }
                else
                {
                    if (p.getColour() != piece.getColour())
                    {
                        moves.Add(new Tuple<uint, uint>((uint)x, (uint)y));
                        break;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            // Check left moves
            x = (int)piece.getX();
            y = (int)piece.getY();
            while (true)
            {
                x--;
                if (!board.withinBoard(x, y))
                {
                    break;
                }

                Piece p = board.getPieceAt((uint)x, (uint)y);
                if (p == null)
                {
                    moves.Add(new Tuple<uint, uint>((uint)x, (uint)y));
                }
                else
                {
                    if (p.getColour() != piece.getColour())
                    {
                        moves.Add(new Tuple<uint, uint>((uint)x, (uint)y));
                        break;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            // Filter for check situations
            CommonRules.checkFilter(ref moves, board, piece);

            // Done, all moves found
            return moves;
        }
예제 #8
0
        // Returns a list of all possible moves
        public static List<Tuple<uint, uint>> getPossibleMoves(Board board, Piece piece)
        {
            List<Tuple<uint, uint>> tmpList = new List<Tuple<uint, uint>>();
            short yMod;
            short passantRow;
            if (piece.getColour() == "white")
            {
                yMod = 1;
                passantRow = 4;
            }
            else
            {
                yMod = -1;
                passantRow = 3;
            }

            // Take left
            if (board.withinBoard((int) piece.getX() - 1, (int) piece.getY() + yMod))
            {
                Piece P = board.getPieceAt((uint)(piece.getX() - 1), (uint)(piece.getY() + yMod));
                if (P != null)
                {
                    if (!piece.isSameColour(P))
                    {
                        tmpList.Add(new Tuple<uint, uint>((uint)(piece.getX() - 1), (uint)(piece.getY() + yMod)));
                    }
                }
            }

            //Take right
            if (board.withinBoard((int)piece.getX() + 1, (int)piece.getY() + yMod))
            {
                Piece P = board.getPieceAt((uint)(piece.getX() + 1), (uint)(piece.getY() + yMod));
                if (P != null)
                {
                    if (!piece.isSameColour(P))
                    {
                        tmpList.Add(new Tuple<uint, uint>((uint)(piece.getX() + 1), (uint)(piece.getY() + yMod)));
                    }
                }
            }

            //Move 1
            if (board.withinBoard((int)piece.getX(), (int)piece.getY() + yMod))
            {
                Piece P = board.getPieceAt(piece.getX(), (uint)(piece.getY() + yMod));
                if (P == null)
                {
                    tmpList.Add(new Tuple<uint, uint>(piece.getX(), (uint)(piece.getY() + yMod)));
                }
            }

            //Move 2 (Only first move)
            if (!piece.movedFromInit())
            {
                if (board.withinBoard((int)piece.getX(), (int)piece.getY() + 2 * yMod))
                {
                    Piece P = board.getPieceAt(piece.getX(), (uint)(piece.getY() + 2 * yMod));
                    Piece P2 = board.getPieceAt(piece.getX(), (uint)(piece.getY() + yMod));
                    if (P == null && P2 == null)
                    {
                        tmpList.Add(new Tuple<uint, uint>(piece.getX(), (uint)(piece.getY() + 2 * yMod)));
                        //((Pawn)piece).setDoubleStepTurn(board.getTurn());
                    }
                }
            }

            //En Passant
            if (piece.getY() == passantRow)
            {
                if ((piece.getX() + 1) < Board.BOARD_SIZE_X)
                {
                    Piece P1 = board.getPieceAt(piece.getX() + 1, piece.getY());

                    if (P1 != null)
                    {
                        if (P1 is Pawn)
                            if (((Pawn)P1).getDoubleStepTurn() == board.getTurn() - 1)
                                tmpList.Add(new Tuple<uint, uint>(piece.getX() + 1, (uint)(piece.getY() + yMod)));
                    }
                }

                if ((int)piece.getX() - 1 >= 0)
                {
                    Piece P2 = board.getPieceAt(piece.getX() - 1, piece.getY());
                    if (P2 != null)
                    {
                        if (P2 is Pawn)
                            if (((Pawn)P2).getDoubleStepTurn() == board.getTurn() - 1)
                                tmpList.Add(new Tuple<uint, uint>(piece.getX() - 1, (uint)(piece.getY() + yMod)));
                    }
                }

            }

            // Filter for check situations
            CommonRules.checkFilter(ref tmpList, board, piece);

            return tmpList;
        }
예제 #9
0
        public static List<Tuple<uint, uint>> getPossibleMoves(Board board, Piece piece)
        {
            List<Tuple<uint, uint>> moves = new List<Tuple<uint, uint>>();

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

            for (int i = -1; i <= 1; i++)
            {
                for (int j = -1; j <= 1; j++)
                {
                    if (i == 0 && j == 0)
                    {
                        // Standing still is not a move
                        continue;
                    }
                    int nx = x + i;
                    int ny = y + j;
                    if (board.withinBoard(nx, ny))
                    {
                        Square s = board.getSquareAt((uint)nx, (uint)ny);
                        if ((piece.getColour() == "white" && s.getBlackCover() == 0) ||
                            (piece.getColour() == "black" && s.getWhiteCover() == 0))
                        {
                            Piece p = s.getPiece();
                            if (p == null)
                            {
                                moves.Add(new Tuple<uint, uint>((uint)nx, (uint)ny));
                            }
                            else
                            {
                                if (p.getColour() != piece.getColour())
                                {
                                    moves.Add(new Tuple<uint, uint>((uint)nx, (uint)ny));
                                }
                            }
                        }
                    }
                }
            }

            // Castling
            Square tmp = board.getSquareAt(piece.getX(), piece.getY());
            if ((!piece.movedFromInit()) && (!tmp.getEnemyCover(piece.getColour())))
            {
                for (int i = 1; i < 5; i++)
                {
                    Square s = board.getSquareAt((uint)(x - i), (uint)y);
                    if ((i < 4) && ((s.getPiece() != null) || s.getEnemyCover(piece.getColour())))
                        break;
                    else if ((s.getPiece() != null) && (i == 4))
                        if ((s.getPiece() is Rook) && (!s.getPiece().movedFromInit()))
                            moves.Add(new Tuple<uint, uint>((uint)(x - 2), (uint)y));

                }
                for (int i = 1; i < 4; i++)
                {
                    Square s = board.getSquareAt((uint)(x + i), (uint)y);
                    if ((i < 3) && ((s.getPiece() != null) || s.getEnemyCover(piece.getColour())))
                        break;
                    else if ((s.getPiece() != null) && (i == 3))
                        if ((s.getPiece() is Rook) && (!s.getPiece().movedFromInit()))
                            moves.Add(new Tuple<uint, uint>((uint)(x + 2), (uint)y));

                }
            }

            // Remove squares with enemy king reach
            foreach (Tuple<uint, uint> reach in getEnemyKingReach(board, piece))
            {
                moves.Remove(reach);
            }

            // Remove any moves that create new checks
            checkFilter(ref moves, board, piece);

            // Done, all moves found
            return moves;
        }
예제 #10
0
 // Special King function used to make sure the Kings can't move next to each other
 private static List<Tuple<uint, uint>> getEnemyKingReach(Board board, Piece piece)
 {
     // Find enemy king
     List<Tuple<uint, uint>> enemyKingReach = new List<Tuple<uint, uint>>();
     bool found = false;
     for (uint j = 0; j < Board.BOARD_SIZE_Y; j++)
     {
         for (uint i = 0; i < Board.BOARD_SIZE_X; i++)
         {
             Piece p = board.getPieceAt(i, j);
             if (p != null && p is King && p.getColour() != piece.getColour())
             {
                 found = true;
                 enemyKingReach = getReach(board, p);
                 break;
             }
             if (found)
             {
                 break;
             }
         }
     }
     return enemyKingReach;
 }
예제 #11
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);
                        }
                    }
                }
            }
        }
예제 #12
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);
                        }
                    }
                }
            }
        }