Пример #1
0
 /*
  * Create an ASCII representation of a position
  */
 public static String asciiBoard(Position position)
 {
     StringBuilder boardRepresentation = new StringBuilder(400);
     String newLine = Environment.NewLine;
     boardRepresentation.Append("    +----+----+----+----+----+----+----+----+");
     boardRepresentation.Append(newLine);
     for (int rank = 7; rank >= 0; rank--)
     {
         boardRepresentation.Append("    |");
         for (int file = 0; file < 8; file++)
         {
             boardRepresentation.Append(" ");
             PieceType piece = position.getPiece(Position.getSquare(file, rank));
             if (piece == PieceType.Empty)
             {
                 Boolean isDark = Position.darkSquare(file, rank);
                 boardRepresentation.Append(isDark ? ".. |" : "   |");
             }
             else
             {
                 //A black piece has prefaced with a *
                 boardRepresentation.Append(((int)piece < 6) ? ' ' : '*');
                 String pieceName = "" + piece;
                 boardRepresentation.Append(pieceName);
                 boardRepresentation.Append(" |");
             }
         }
         boardRepresentation.Append(newLine);
         boardRepresentation.Append("    +----+----+----+----+----+----+----+----+");
         boardRepresentation.Append(newLine);
     }
     return boardRepresentation.ToString();
 }
Пример #2
0
 /*
  * Returns true if a move results in a caputre for a given
  * position
  */
 public static Boolean isMoveCapture(Move move, Position position)
 {
     if (position.getPiece(move.destination) == PieceType.Empty)
     {
         //Deal with En Passant capture
         PieceType piece = position.getPiece(move.origin);
         if ((piece == (position.whiteMove ? PieceType.P : PieceType.p)) && (move.destination == position.getEpSquare()))
         {
             return true;
         }
         else
         {
             return false;
         }
     }
     else
     {
         return true;
     }
 }
Пример #3
0
        /*
         * Converts a move object into a UCI move string (long algebraic
         * notation), a move list can be supplied to search through.
         */
        public static String moveObjectToString(Move move, Position position, ArrayList moves)
        {
            if ((move == null) || move.Equals(new Move(0, 0, 0)))
            {
                return "--";
            }
            StringBuilder moveString = new StringBuilder();
            int whiteKingOrigin = Position.getSquare(4, 0);
            int blackKingOrigin = Position.getSquare(4, 7);
            if ((move.origin == whiteKingOrigin) && (position.getPiece(whiteKingOrigin) == PieceType.K))
            {
                //Check white castle
                if (move.destination == Position.getSquare(6, 0))
                {
                    moveString.Append("O-O");
                }
                else if (move.destination == Position.getSquare(2, 0))
                {
                    moveString.Append("O-O-O");
                }
            }
            else if ((move.origin == blackKingOrigin) && (position.getPiece(blackKingOrigin) == PieceType.k))
            {
                //Check black castle
                if (move.destination == Position.getSquare(6, 7))
                {
                    moveString.Append("O-O");
                }
                else if (move.destination == Position.getSquare(2, 7))
                {
                    moveString.Append("O-O-O");
                }
            }
            if (moveString.Length == 0)
            {
                PieceType piece = position.getPiece(move.origin);
                moveString.Append("" + piece);

                int originFile = Position.getRank(move.origin);
                int originRank = Position.getFile(move.origin);
                int destinationFile = Position.getRank(move.destination);
                int destinationRank = Position.getFile(move.destination);

                //Long Algebraic Notation-----
                moveString.Append((char)(originFile + 'a'));
                moveString.Append((char)(originRank + '1'));
                moveString.Append(isMoveCapture(move, position) ? 'x' : '-');
                //----------------------------
                moveString.Append((char)(destinationFile + 'a'));
                moveString.Append((char)(destinationRank + '1'));
                if (move.promoteTo != PieceType.Empty)
                {
                    moveString.Append("" + piece);
                }
            }
            UnMakeInfo unMake = new UnMakeInfo();
            position.makeMove(move, unMake);
            Boolean inCheck = MoveGenerator.inCheck(position);
            if (inCheck)
            {
                ArrayList nextMoves = MoveGenerator.mgInstance.legalMoves(position);
                if (nextMoves.Count == 0)
                {
                    moveString.Append('#');
                }
                else
                {
                    moveString.Append('+');
                }
            }
            position.unMakeMove(move, unMake);

            return moveString.ToString();
        }
Пример #4
0
        /*
         * Converts a UCI move string (long algebraic notation into
         * a move object, a list of moves can be supplied to search
         * through.
         */
        public static Move moveStringToObject(String moveString, Position position, ArrayList moves)
        {
            if (moveString.Equals("--"))
            {
                return new Move(0, 0, 0);
            }

            moveString = moveString.Replace("=", "");
            moveString = moveString.Replace("\\+", "");
            moveString = moveString.Replace("#", "");
            Boolean whiteToMove = position.whiteMove;

            MoveComposition moveComp = new MoveComposition();
            Boolean capture = false;
            if (moveString.Equals("O-O") || moveString.Equals("0-0") || moveString.Equals("o-o"))
            {
                moveComp.piece = whiteToMove ? PieceType.K : PieceType.k;
                moveComp.originFile = 4;
                moveComp.destinationFile = 6;
                moveComp.originRank = moveComp.destinationRank = whiteToMove ? 0 : 7;
                moveComp.promotionPiece = PieceType.Empty;
            }
            else if (moveString.Equals("O-O-O") || moveString.Equals("0-0-0") || moveString.Equals("o-o-o"))
            {
                moveComp.piece = whiteToMove ? PieceType.K : PieceType.k;
                moveComp.originFile = 4;
                moveComp.destinationFile = 2;
                moveComp.originRank = moveComp.destinationRank = whiteToMove ? 0 : 7;
                moveComp.promotionPiece = PieceType.Empty;
            }
            else
            {
                Boolean attackToSquare = false;
                for (int i = 0; i < moveString.Length; i++)
                {
                    char c = moveString[i];
                    if (i == 0)
                    {
                        PieceType piece = charToPieceType(c);
                        if (piece != PieceType.Empty)
                        {
                            moveComp.piece = piece;
                            continue;
                        }
                    }
                    int tempFile = c - 'a';
                    if ((tempFile >= 0) && (tempFile < 8))
                    {
                        if (attackToSquare || (moveComp.originFile >= 0))
                        {
                            moveComp.destinationFile = tempFile;
                        }
                        else
                        {
                            moveComp.originFile = tempFile;
                        }
                    }
                    int tempRank = c - '1';
                    if ((tempRank >= 0) && (tempFile < 8))
                    {
                        if (attackToSquare || (moveComp.originRank >= 0))
                        {
                            moveComp.destinationRank = tempRank;
                        }
                        else
                        {
                            moveComp.originRank = tempRank;
                        }
                    }

                    if ((c == 'x') || (c == '-'))
                    {
                        attackToSquare = true;
                        if (c == 'x')
                        {
                            capture = true;
                        }
                    }

                    if (i == moveString.Length - 1)
                    {
                        PieceType promotionPiece = charToPieceType(c);
                        if (promotionPiece != PieceType.Empty)
                        {
                            moveComp.promotionPiece = promotionPiece;
                        }
                    }
                }
                if ((moveComp.originFile >= 0) && (moveComp.destinationFile < 0))
                {
                    moveComp.destinationFile = moveComp.originFile;
                    moveComp.originFile = -1;
                }
                if ((moveComp.originRank >= 0) && (moveComp.destinationRank < 0))
                {
                    moveComp.destinationRank = moveComp.originRank;
                    moveComp.originFile = -1;
                }

                if (moveComp.piece == PieceType.Empty)
                {
                    Boolean haveAll = (moveComp.originFile >= 0) && (moveComp.destinationFile >= 0) &&
                                      (moveComp.originRank >= 0) && (moveComp.destinationRank >= 0);
                    if (!haveAll)
                    {
                        moveComp.piece = whiteToMove ? PieceType.P : PieceType.p;
                    }
                }
            }

            if (moves == null)
            {
                moves = MoveGenerator.mgInstance.legalMoves(position);
            }
            ArrayList matches = new ArrayList(2);
            foreach (Move listMove in moves)
            {
                PieceType piece = position.getPiece(listMove.origin);
                Boolean match = true;
                if ((moveComp.piece >= 0) && (moveComp.piece != piece))
                {
                    match = false;
                }
                if ((moveComp.originFile >= 0) && (moveComp.originFile != Position.getFile(listMove.origin)))
                {
                    match = false;
                }
                if ((moveComp.originRank >= 0) && (moveComp.originRank != Position.getRank(listMove.origin)))
                {
                    match = false;
                }
                if ((moveComp.destinationFile >= 0) && (moveComp.destinationFile != Position.getFile(listMove.destination)))
                {
                    match = false;
                }
                if ((moveComp.destinationRank >= 0) && (moveComp.destinationRank != Position.getRank(listMove.destination)))
                {
                    match = false;
                }
                if ((moveComp.promotionPiece >= 0) && (moveComp.promotionPiece != listMove.promoteTo))
                {
                    match = false;
                }
                if (match)
                {
                    matches.Add(listMove);
                }
            }

            int numMatches = matches.Count;
            if (numMatches == 0)
            {
                return null;
            }
            else if (numMatches == 1)
            {
                return (Move)matches[0];
            }
            if (!capture)
            {
                return null;
            }

            Move move = null;
            foreach (Move listMove in matches)
            {
                PieceType capturedPiece = position.getPiece(listMove.destination);
                if (capturedPiece != PieceType.Empty)
                {
                    if (move == null)
                    {
                        move = listMove;
                    }
                    else
                    {
                        return null;
                    }
                }
            }
            return move;
        }
Пример #5
0
        /*
         * Parse a FEN string and return a position object
         */
        public static Position convertFENToPosition(String fen)
        {
            Position position = new Position();
            String[] terms = fen.Split(' ');
            if (terms.Length < 2)
            {
                System.Console.WriteLine("Too few terms");
            }
            for (int i = 0; i < terms.Length; i++)
            {
                terms[i] = terms[i].Trim();
            }

            //Piece placement
            int rank = 7;
            int file = 0;
            for (int i = 0; i < terms[0].Length; i++)
            {
                char c = (char)terms[0].ToCharArray().GetValue(i);
                switch (c)
                {
                    case '1': file += 1; break;
                    case '2': file += 2; break;
                    case '3': file += 3; break;
                    case '4': file += 4; break;
                    case '5': file += 5; break;
                    case '6': file += 6; break;
                    case '7': file += 7; break;
                    case '8': file += 8; break;
                    case '/': rank--; file = 0; break;
                    case 'P': setPieceSafely(position, file, rank, PieceType.P); file++; break;
                    case 'N': setPieceSafely(position, file, rank, PieceType.N); file++; break;
                    case 'B': setPieceSafely(position, file, rank, PieceType.B); file++; break;
                    case 'R': setPieceSafely(position, file, rank, PieceType.R); file++; break;
                    case 'Q': setPieceSafely(position, file, rank, PieceType.Q); file++; break;
                    case 'K': setPieceSafely(position, file, rank, PieceType.K); file++; break;
                    case 'p': setPieceSafely(position, file, rank, PieceType.p); file++; break;
                    case 'n': setPieceSafely(position, file, rank, PieceType.n); file++; break;
                    case 'b': setPieceSafely(position, file, rank, PieceType.b); file++; break;
                    case 'r': setPieceSafely(position, file, rank, PieceType.r); file++; break;
                    case 'q': setPieceSafely(position, file, rank, PieceType.q); file++; break;
                    case 'k': setPieceSafely(position, file, rank, PieceType.k); file++; break;
                    default: throw new ParserError("Invalid Piece", position);
                }
            }

            //Active Colour
            if (terms[1].Length > 0)
            {
                Boolean whiteToMove;
                char c = (char)terms[1].ToCharArray().GetValue(0);
                switch (c)
                {
                    case 'w': whiteToMove = true; break;
                    case 'b': whiteToMove = false; break;
                    default: throw new ParserError("Invalid Active Colour", position);
                }
                position.setWhiteMove(whiteToMove);
            }
            else
            {
                throw new ParserError("Invalid Active Colour", position);
            }

            //Castling Rights
            int castleMask = 0;
            if (terms.Length > 2)
            {
                for (int i = 0; i < terms[2].Length; i++)
                {
                    char c = (char)terms[2].ToCharArray().GetValue(i);
                    switch (c)
                    {
                        case 'K':
                            castleMask |= (1 << Position.H1_CASTLE);
                            break;
                        case 'Q':
                            castleMask |= (1 << Position.A1_CASTLE);
                            break;
                        case 'k':
                            castleMask |= (1 << Position.H8_CASTLE);
                            break;
                        case 'q':
                            castleMask |= (1 << Position.A8_CASTLE);
                            break;
                        case '-':
                            break;
                        default:
                            throw new ParserError("Invalid castling flags", position);
                    }

                }
            }
            position.setCastleMask(castleMask);
            removeInvalidCastleFlags(position);

            //En Passant Target Square
            if (terms.Length > 3)
            {
                String epString = terms[3];
                if (!epString.Equals("-"))
                {
                    if (epString.Length < 2)
                    {
                        throw new ParserError("Invalid En Passent Square", position);
                    }
                    position.setEpSquare(getSquare(epString));
                }
            }

            try
            {
                //Halfmove Clock
                if (terms.Length > 4)
                {
                    position.halfMoveClock = Convert.ToInt32(terms[4]);
                }
                //Full Move Counter
                if (terms.Length > 5)
                {
                    position.fullMoveCounter = Convert.ToInt32(terms[5]);
                }
            }
            catch (ArgumentException ae)
            {
                //Ignore errors here since fields are optional
            }

            //Each side must have exactly one king
            int maxNumber = (int)PieceType.Empty + 1;
            int[] numPieces = new int[maxNumber];
            for (int i = 0; i < maxNumber; i++)
            {
                numPieces[i] = 0;
            }
            for (file = 0; file < 8; file++)
            {
                for (rank = 0; rank < 8; rank++)
                {
                    numPieces[(int)position.getPiece(Position.getSquare(file, rank))]++;
                }
            }
            if (numPieces[(int)PieceType.K] != 1)
            {
                throw new ParserError("Too many white kings", position);
            }
            if (numPieces[(int)PieceType.k] != 1)
            {
                throw new ParserError("Too many black kings", position);
            }

            //White must not have too many pieces
            int maxWPawns = 8;
            maxWPawns -= Math.Max(0, numPieces[(int)PieceType.N] - 2);
            maxWPawns -= Math.Max(0, numPieces[(int)PieceType.B] - 2);
            maxWPawns -= Math.Max(0, numPieces[(int)PieceType.R] - 2);
            maxWPawns -= Math.Max(0, numPieces[(int)PieceType.Q] - 1);
            if (numPieces[(int)PieceType.P] > maxWPawns)
            {
                throw new ParserError("Too many white pieces", position);
            }

            //Black must not have too many pieces
            int maxBPawns = 8;
            maxBPawns -= Math.Max(0, numPieces[(int)PieceType.n] - 2);
            maxBPawns -= Math.Max(0, numPieces[(int)PieceType.b] - 2);
            maxBPawns -= Math.Max(0, numPieces[(int)PieceType.r] - 2);
            maxBPawns -= Math.Max(0, numPieces[(int)PieceType.q] - 1);

            //Make sure king can not be captured
            Position pos2 = new Position(position);
            pos2.setWhiteMove(!position.whiteMove);
            if (MoveGenerator.inCheck(pos2))
            {
                throw new ParserError("King capture possible", position);
            }

            fixupEPSquare(position);

            return position;
        }
Пример #6
0
 /*
  * Remove castling flags that arent valid
  */
 private static void removeInvalidCastleFlags(Position position)
 {
     int castleMask = position.getCastleMask();
     int validCastle = 0;
     if (position.getPiece(4) == PieceType.K)
     {
         if (position.getPiece(0) == PieceType.R) validCastle |= (1 << Position.A1_CASTLE);
         if (position.getPiece(7) == PieceType.R) validCastle |= (1 << Position.H1_CASTLE);
     }
     if (position.getPiece(60) == PieceType.k)
     {
         if (position.getPiece(56) == PieceType.r) validCastle |= (1 << Position.A8_CASTLE);
         if (position.getPiece(63) == PieceType.r) validCastle |= (1 << Position.H8_CASTLE);
     }
     castleMask &= validCastle;
     position.setCastleMask(castleMask);
 }
Пример #7
0
 /*
  * Remove EPSquare from position if it is not legal
  */
 private static void fixupEPSquare(Position position)
 {
     int epSquare = position.getEpSquare();
     if (epSquare >= 0)
     {
         ArrayList moves = MoveGenerator.mgInstance.legalMoves(position);
         Boolean epValid = false;
         foreach (Move move in moves)
         {
             if (move.destination == epSquare)
             {
                 if (position.getPiece(move.origin) == (position.whiteMove ? PieceType.P : PieceType.p))
                 {
                     epValid = true;
                     break;
                 }
             }
         }
         if (!epValid)
         {
             position.setEpSquare(-1);
         }
     }
 }
Пример #8
0
        /*
         * Return a Forsyth-Edwards Notation string corresponding to a Position object
         */
        public static String convertPositionToFEN(Position position)
        {
            StringBuilder feNotation = new StringBuilder();
            //Piece placement
            for (int rank = 7; rank >= 0; rank--)
            {
                int emptySquares = 0;
                for (int file = 0; file < 8; file++)
                {
                    PieceType piece = position.getPiece(Position.getSquare(file, rank));
                    if (piece == PieceType.Empty)
                    {
                        emptySquares++;
                    }
                    else
                    {
                        if (emptySquares > 0)
                        {
                            feNotation.Append(emptySquares);
                            emptySquares = 0;
                        }
                        switch (piece)
                        {
                            case PieceType.K:   feNotation.Append('K'); break;
                            case PieceType.Q:   feNotation.Append('Q'); break;
                            case PieceType.R:   feNotation.Append('R'); break;
                            case PieceType.B:   feNotation.Append('B'); break;
                            case PieceType.N:   feNotation.Append('N'); break;
                            case PieceType.P:   feNotation.Append('P'); break;
                            case PieceType.k:   feNotation.Append('k'); break;
                            case PieceType.q:   feNotation.Append('q'); break;
                            case PieceType.r:   feNotation.Append('r'); break;
                            case PieceType.b:   feNotation.Append('b'); break;
                            case PieceType.n:   feNotation.Append('n'); break;
                            case PieceType.p:   feNotation.Append('p'); break;
                            default: throw new ParserError("Error creating FEN String");
                        }
                    }
                }
                if (emptySquares > 0)
                {
                    feNotation.Append(emptySquares);
                }
                if (rank > 0)
                {
                    feNotation.Append("/");
                }
            }
            //Active Colour
            feNotation.Append(position.whiteMove ? " w " : " b ");

            //Castling Rights
            Boolean anyCastle = false;
            if (position.h1Castle())
            {
                feNotation.Append('K');
                anyCastle = true;
            }
            if (position.a1Castle())
            {
                feNotation.Append('Q');
                anyCastle = true;
            }
            if (position.h8Castle())
            {
                feNotation.Append('k');
                anyCastle = true;
            }
            if (position.a8Castle())
            {
                feNotation.Append('q');
                anyCastle = true;
            }
            if (!anyCastle)
            {
                feNotation.Append('-');
            }

            //En Passant Target Square
            {
                feNotation.Append(" ");
                if (position.getEpSquare() >= 0)
                {
                    int file = Position.getFile(position.getEpSquare());
                    int rank = Position.getRank(position.getEpSquare());
                    feNotation.Append((char)(file + 'a'));
                    feNotation.Append((char)(rank + '1'));
                }
                else
                {
                    feNotation.Append('-');
                }
            }

            //Move Counters
            feNotation.Append(' ');
            feNotation.Append(position.halfMoveClock);
            feNotation.Append(' ');
            feNotation.Append(position.fullMoveCounter);

            return feNotation.ToString();
        }
Пример #9
0
        /**
         * Gets a list of all the Square numbers of Sqaures controlled by the enemy player
         */
        private List<int> getEnemyControlledSquares(Position position)
        {
            List<int> controlledSquares = new List<int>();
            for (int i = 0; i < 64; i++)
            {
                if (position.getPiece(i).Equals(PieceType.Empty)) continue;
                if ((Char.IsLower(position.getPiece(i).ToString()[0]) && position.whiteMove) | (Char.IsUpper(position.getPiece(i).ToString()[0]) && !position.whiteMove))
                {
                    controlledSquares.Add(i);
                }
            }

            return controlledSquares;
        }
Пример #10
0
 /*
  * Add all moves from a given square in direction delta
  * @param maxSteps Max steps until reaching a border, Set to 1 for non-sliding pieces
  * Returns True if the enemy king could be captured, false otherwise
  */
 private Boolean addDirection(ArrayList moveList, Position position, int square, int maxSteps, int delta)
 {
     int destination = square;
     Boolean whiteToMove = position.whiteMove;
     PieceType opppositeKing = (whiteToMove ? PieceType.k : PieceType.K);
     while (maxSteps > 0)
     {
         destination += delta;
         PieceType piece = position.getPiece(destination);
         if (piece == PieceType.Empty)
         {
             moveList.Add(getMoveObject(square, destination, PieceType.Empty));
         }
         else
         {
             //check if piece is white
             if (((int)piece < 6) != whiteToMove)
             {
                 if (piece == opppositeKing)
                 {
                     returnMoveList(moveList);
                     moveList = getMoveListObject();
                     moveList.Add(getMoveObject(square, destination, PieceType.Empty));
                     return true;
                 }
                 else
                 {
                     moveList.Add(getMoveObject(square, destination, PieceType.Empty));
                 }
             }
             break;
         }
         maxSteps--;
     }
     return false;
 }
Пример #11
0
 /*
  * Check if there is an attacking piece in a given direction starting from
  * a given square. The direction is given by delta
  * @param maxSteps Max steps until reaching a border, Set to 1 for non-sliding pieces
  * Returns the first piece in the given direction, or Empty if there is no piece
  * in that direction
  */
 private static PieceType checkDirection(Position position, int square, int maxSteps, int delta)
 {
     while (maxSteps > 0)
     {
         square += delta;
         PieceType piece = position.getPiece(square);
         if (piece != PieceType.Empty)
         {
             return piece;
         }
         maxSteps--;
     }
     return PieceType.Empty;
 }
Пример #12
0
        /*
         * Generate and return a list of psuedo-legal moves.
         * Pseudo-legal moves are those that don't necessarily defend
         * from check threats.
         */
        public ArrayList psuedoLegalMoves(Position position)
        {
            ArrayList moveList = getMoveListObject();
            Boolean whiteToMove = position.whiteMove;

            for (int file = 0; file < 8; file++)
            {
                for (int rank = 0; rank < 8; rank++)
                {
                    int square = Position.getSquare(file, rank);
                    PieceType piece = position.getPiece(square);
                    if ((piece == PieceType.Empty) || (((int)piece < 6) != whiteToMove))
                    {
                        continue;
                    }
                    if ((piece == PieceType.R) || (piece == PieceType.r) || (piece == PieceType.Q) || (piece == PieceType.q))
                    {
                        if (addDirection(moveList, position, square, 7 - file, 1)) return moveList;
                        if (addDirection(moveList, position, square, 7 - rank, 8)) return moveList;
                        if (addDirection(moveList, position, square, file, -1)) return moveList;
                        if (addDirection(moveList, position, square, rank, -8)) return moveList;
                    }
                    if ((piece == PieceType.B) || (piece == PieceType.b) || (piece == PieceType.Q) || (piece == PieceType.q))
                    {
                        if (addDirection(moveList, position, square, Math.Min(7 - file, 7 - rank), 9)) return moveList;
                        if (addDirection(moveList, position, square, Math.Min(file, 7 - rank), 7)) return moveList;
                        if (addDirection(moveList, position, square, Math.Min(file, rank), -9)) return moveList;
                        if (addDirection(moveList, position, square, Math.Min(7 - file, rank), -7)) return moveList;
                    }
                    if ((piece == PieceType.N) || (piece == PieceType.n))
                    {
                        if (file < 6 && rank < 7 && addDirection(moveList, position, square, 1, 10)) return moveList;
                        if (file < 7 && rank < 6 && addDirection(moveList, position, square, 1, 17)) return moveList;
                        if (file > 0 && rank < 6 && addDirection(moveList, position, square, 1, 15)) return moveList;
                        if (file > 1 && rank < 7 && addDirection(moveList, position, square, 1, 6)) return moveList;
                        if (file > 1 && rank > 0 && addDirection(moveList, position, square, 1, -10)) return moveList;
                        if (file > 0 && rank > 1 && addDirection(moveList, position, square, 1, -17)) return moveList;
                        if (file < 7 && rank > 1 && addDirection(moveList, position, square, 1, -15)) return moveList;
                        if (file < 6 && rank > 0 && addDirection(moveList, position, square, 1, -6)) return moveList;
                    }
                    if ((piece == PieceType.K) || (piece == PieceType.k))
                    {
                        if (file < 7 && addDirection(moveList, position, square, 1, 1)) return moveList;
                        if (file < 7 && rank < 7 && addDirection(moveList, position, square, 1, 9)) return moveList;
                        if (rank < 7 && addDirection(moveList, position, square, 1, 8)) return moveList;
                        if (file > 0 && rank < 7 && addDirection(moveList, position, square, 1, 7)) return moveList;
                        if (file > 0 && addDirection(moveList, position, square, 1, -1)) return moveList;
                        if (file > 0 && rank > 0 && addDirection(moveList, position, square, 1, -9)) return moveList;
                        if (rank > 0 && addDirection(moveList, position, square, 1, -8)) return moveList;
                        if (file < 7 && rank > 0 && addDirection(moveList, position, square, 1, -7)) return moveList;

                        int kingOrigin = whiteToMove ? Position.getSquare(4, 0) : Position.getSquare(4, 7);

                        if (Position.getSquare(file, rank) == kingOrigin)
                        {
                            int aCastle = whiteToMove ? Position.A1_CASTLE : Position.A8_CASTLE;
                            int hCastle = whiteToMove ? Position.H1_CASTLE : Position.H8_CASTLE;
                            PieceType rook = whiteToMove ? PieceType.R : PieceType.r;
                            if (((position.getCastleMask() & (1 << hCastle)) != 0) &&
                                (position.getPiece(kingOrigin + 1) == PieceType.Empty) &&
                                (position.getPiece(kingOrigin + 2) == PieceType.Empty) &&
                                (position.getPiece(kingOrigin + 3) == rook) &&
                                !squareAttacked(position, kingOrigin) &&
                                !squareAttacked(position, kingOrigin + 1) &&
                                !squareAttacked(position, kingOrigin + 2))
                            {
                                moveList.Add(getMoveObject(kingOrigin, kingOrigin + 2, PieceType.Empty));
                            }
                            if (((position.getCastleMask() & (1 << aCastle)) != 0) &&
                                (position.getPiece(kingOrigin - 1) == PieceType.Empty) &&
                                (position.getPiece(kingOrigin - 2) == PieceType.Empty) &&
                                (position.getPiece(kingOrigin - 3) == PieceType.Empty) &&
                                (position.getPiece(kingOrigin - 4) == rook) &&
                                !squareAttacked(position, kingOrigin) &&
                                !squareAttacked(position, kingOrigin - 1) &&
                                !squareAttacked(position, kingOrigin - 2))
                            {
                                moveList.Add(getMoveObject(kingOrigin, kingOrigin - 2, PieceType.Empty));
                            }
                        }
                    }

                    if ((piece == PieceType.P) || (piece == PieceType.p))
                    {
                        int rankDir = whiteToMove ? 8 : -8;
                        if (position.getPiece(square + rankDir) == PieceType.Empty)
                        {
                            //non capture moves
                            addPawnMoves(moveList, square, square + rankDir);
                            if ((rank == (whiteToMove ? 1 : 6)) &&
                                (position.getPiece(square + 2 * rankDir) == PieceType.Empty))
                            {
                                //double step moves
                                addPawnMoves(moveList, square, square + rankDir * 2);
                            }
                        }
                        //Capture to the left
                        if (file > 0)
                        {
                            int toSquare = square + rankDir - 1;
                            PieceType captured = position.getPiece(toSquare);
                            if (captured != PieceType.Empty)
                            {
                                if (((int)captured < 6) != whiteToMove)
                                {
                                    if (captured == (whiteToMove ? PieceType.k : PieceType.K))
                                    {
                                        returnMoveList(moveList);
                                        moveList = getMoveListObject();
                                        moveList.Add(getMoveObject(square, toSquare, PieceType.Empty));
                                        return moveList;
                                    }
                                    else
                                    {
                                        addPawnMoves(moveList, square, toSquare);
                                    }
                                }
                            }
                            else if (toSquare == position.getEpSquare())
                            {
                                addPawnMoves(moveList, square, toSquare);
                            }
                        }
                        //Capture to the right
                        if (file < 7)
                        {
                            int toSquare = square + rankDir + 1;
                            PieceType captured = position.getPiece(toSquare);
                            if (captured != PieceType.Empty)
                            {
                                if (((int)captured < 6) != whiteToMove)
                                {
                                     if (captured == (whiteToMove ? PieceType.k : PieceType.K))
                                    {
                                        returnMoveList(moveList);
                                        moveList = getMoveListObject();
                                        moveList.Add(getMoveObject(square, toSquare, PieceType.Empty));
                                        return moveList;
                                    }
                                    else
                                    {
                                        addPawnMoves(moveList, square, toSquare);
                                    }
                                }
                            }
                            else if (toSquare == position.getEpSquare())
                            {
                                addPawnMoves(moveList, square, toSquare);
                            }
                        }
                    }
                }
            }
            return moveList;
        }