Beispiel #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();
 }
Beispiel #2
0
 /*
  * Return true if the side to move is in check
  */
 public static Boolean inCheck(Position position)
 {
     int kingSquare = position.getKingSquare(position.whiteMove);
     if (kingSquare < 0)
     {
         return false;
     }
     return squareAttacked(position, kingSquare);
 }
Beispiel #3
0
 public void TestEmptyPosition()
 {
     //arrange
     String emptyFEN = "8/8/8/8/8/8/8/8 w - - 0 1";
     //act
     Position empty = new Position();
     //assert
     Assert.AreEqual(emptyFEN, FENConverter.convertPositionToFEN(empty));
 }
Beispiel #4
0
        public static Position PawnGamePosition()
        {
            Position position = new Position();
            String pawnGamePosition = "4k3/pppppppp/8/8/8/8/PPPPPPPP/4K3 w KQkq - 0 1";

            position = FENConverter.convertFENToPosition(pawnGamePosition);

            return position;
        }
Beispiel #5
0
 /*
  * Initialise board to a given position
  */
 public Position(Position position)
 {
     pieceLayout = position.pieceLayout;
     whiteMove = position.whiteMove;
     castleMask = position.castleMask;
     epSquare = position.epSquare;
     halfMoveClock = position.halfMoveClock;
     fullMoveCounter = position.fullMoveCounter;
     wKingSquare = position.wKingSquare;
     bKingSquare = position.bKingSquare;
     sameActiveColor = position.sameActiveColor;
 }
Beispiel #6
0
 /*
  * Returns true if a move is valid for a given position
  */
 public static Boolean isMoveValid(Move move, Position position)
 {
     if (move == null)
     {
         return false;
     }
     ArrayList moves = new MoveGenerator().legalMoves(position);
     foreach (Move listMove in moves)
     {
         //Move is only valid if it appears in legal moves list
         if (move.Equals(listMove))
         {
             return true;
         }
     }
     return false;
 }
Beispiel #7
0
 /*
  * Removes illegal moves from the given move list
  * The move list contains psuedo-legal moves
  * This removes the moves that don't defend from check positions
  */
 public static ArrayList removeIllegalMoves(Position position, ArrayList moveList)
 {
     ArrayList finalList = new ArrayList();
     UnMakeInfo moveInfo = new UnMakeInfo();
     int moveListCount = moveList.Count;
     for (int i = 0; i < moveListCount; i++)
     {
         Move move = (Move)moveList[i];
         position.makeMove(move, moveInfo);
         position.setWhiteMove(!position.whiteMove);
         if (!inCheck(position))
         {
             finalList.Add(move);
         }
         position.setWhiteMove(!position.whiteMove);
         position.unMakeMove(move, moveInfo);
     }
     return finalList;
 }
Beispiel #8
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;
     }
 }
Beispiel #9
0
 public ParserError(int resourceID)
     : base("")
 {
     this.pos = null;
     this.resourceID = resourceID;
 }
Beispiel #10
0
 public ParserError(String msg, Position pos)
     : base(msg)
 {
     this.pos = pos;
 }
Beispiel #11
0
 public ParserError(String msg)
     : base(msg)
 {
     this.pos = null;
 }
Beispiel #12
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;
 }
Beispiel #13
0
        /*
         * Return true if a square is attacked by the opposite side
         */
        public static Boolean squareAttacked(Position position, int square)
        {
            int file = Position.getFile(square);
            int rank = Position.getRank(square);
            Boolean isWhiteMove = position.whiteMove;

            PieceType opppositeQueen = isWhiteMove ? PieceType.q : PieceType.Q;
            PieceType opppositeRook = isWhiteMove ? PieceType.r : PieceType.R;
            PieceType opppositeBishop = isWhiteMove ? PieceType.b : PieceType.B;
            PieceType opppositeKnight = isWhiteMove ? PieceType.n : PieceType.N;

            PieceType piece;

            if (rank > 0)
            {
                piece = checkDirection(position, square, rank, -8);
                if ((piece == opppositeQueen) || (piece == opppositeRook)) return true;
                piece = checkDirection(position, square, Math.Min(file, rank), -9);
                if ((piece == opppositeQueen) || (piece == opppositeBishop)) return true;
                piece = checkDirection(position, square, Math.Min(7 - file, rank), -7);
                if ((piece == opppositeQueen) || (piece == opppositeBishop)) return true;

                if (file > 1)
                {
                    piece = checkDirection(position, square, 1, -10);
                    if (piece == opppositeKnight) return true;
                }
                if (file > 0 && rank > 1)
                {
                    piece = checkDirection(position, square, 1, -17);
                    if (piece == opppositeKnight) return true;
                }
                if (file < 7 && rank > 1)
                {
                    piece = checkDirection(position, square, 1, -15);
                    if (piece == opppositeKnight) return true;
                }
                if (file < 6)
                {
                    piece = checkDirection(position, square, 1, -6);
                    if (piece == opppositeKnight) return true;
                }

                if (!isWhiteMove)
                {
                    if (file < 7 && rank > 1)
                    {
                        piece = checkDirection(position, square, 1, -7);
                        if (piece == PieceType.P) return true;
                    }
                    if (file > 0 && rank > 1)
                    {
                        piece = checkDirection(position, square, 1, -9);
                        if (piece == PieceType.P) return true;
                    }
                }
            }
            if (rank < 7)
            {
                piece = checkDirection(position, square, 7 - rank, 8);
                if ((piece == opppositeQueen) || (piece == opppositeRook)) return true;
                piece = checkDirection(position, square, Math.Min(7 - file, 7 - rank), 9);
                if ((piece == opppositeQueen) || (piece == opppositeBishop)) return true;
                piece = checkDirection(position, square, Math.Min(file, 7 - rank), 7);
                if ((piece == opppositeQueen) || (piece == opppositeBishop)) return true;

                if (rank < 6)
                {
                    piece = checkDirection(position, square, 1, 10);
                    if (piece == opppositeKnight) return true;
                }
                if (file < 7 && rank < 6)
                {
                    piece = checkDirection(position, square, 1, 17);
                    if (piece == opppositeKnight) return true;
                }
                if (file > 0 && rank < 6)
                {
                    piece = checkDirection(position, square, 1, 15);
                    if (piece == opppositeKnight) return true;
                }
                if (file > 1)
                {
                    piece = checkDirection(position, square, 1, 6);
                    if (piece == opppositeKnight) return true;
                }

                if (isWhiteMove)
                {
                    if (file < 7 && rank < 6)
                    {
                        piece = checkDirection(position, square, 1, 9);
                        if (piece == PieceType.p) return true;
                    }
                    if (file > 0 && rank < 6)
                    {
                        piece = checkDirection(position, square, 1, 7);
                        if (piece == PieceType.p) return true;
                    }
                }
            }

            piece = checkDirection(position, square, 7 - file, 1);
            if ((piece == opppositeQueen) || (piece == opppositeRook)) return true;
            piece = checkDirection(position, square, file, -1);
            if ((piece == opppositeQueen) || (piece == opppositeRook)) return true;

            int opppositeKingSquare = position.getKingSquare(!isWhiteMove);
            if (opppositeKingSquare >= 0)
            {
                int oFile = Position.getFile(opppositeKingSquare);
                int oRank = Position.getRank(opppositeKingSquare);
                if ((Math.Abs(file - oFile) <= 1) && (Math.Abs(rank - oRank) <= 1))
                {
                    return true;
                }
            }
            return false;
        }
Beispiel #14
0
 /*
  * Converts a UCI move string (long algebraic notation) into
  * a move object
  */
 public static Move moveStringToObject(String uci, Position position)
 {
     return moveStringToObject(uci, position, null);
 }
Beispiel #15
0
 /*
  * Converts a move object into a UCI move string (long algebraic
  * notation)
  */
 public static String moveObjectToString(Move move, Position position)
 {
     return moveObjectToString(move, position, null);
 }
Beispiel #16
0
        /*
         * Convert a piece placement string to a position object
         * This does not have to adhere to the strict rules of how
         * many pieces a player must have. i.e.(player may have no king)
         * This is primarily used for testing purposes, as well as tutorial
         * scenarios.
         */
        public static Position convertPiecePlacementToPosition(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': position.setPiece(Position.getSquare(file, rank), PieceType.P); file++; break;
                    case 'N': position.setPiece(Position.getSquare(file, rank), PieceType.N); file++; break;
                    case 'B': position.setPiece(Position.getSquare(file, rank), PieceType.B); file++; break;
                    case 'R': position.setPiece(Position.getSquare(file, rank), PieceType.R); file++; break;
                    case 'Q': position.setPiece(Position.getSquare(file, rank), PieceType.Q); file++; break;
                    case 'K': position.setPiece(Position.getSquare(file, rank), PieceType.K); file++; break;
                    case 'p': position.setPiece(Position.getSquare(file, rank), PieceType.p); file++; break;
                    case 'n': position.setPiece(Position.getSquare(file, rank), PieceType.n); file++; break;
                    case 'b': position.setPiece(Position.getSquare(file, rank), PieceType.b); file++; break;
                    case 'r': position.setPiece(Position.getSquare(file, rank), PieceType.r); file++; break;
                    case 'q': position.setPiece(Position.getSquare(file, rank), PieceType.q); file++; break;
                    case 'k': position.setPiece(Position.getSquare(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
                Console.WriteLine(ae.ToString());
            }

            fixupEPSquare(position);

            return position;
        }
Beispiel #17
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();
        }
Beispiel #18
0
 public void StartPosition()
 {
     currentPosition = FENConverter.convertPiecePlacementToPosition(FENConverter.startPosition);
 }
Beispiel #19
0
 public void ClearBoard()
 {
     currentPosition = FENConverter.convertPiecePlacementToPosition(FENConverter.emptyPosition);
 }
Beispiel #20
0
 public TutorialBase()
 {
     currentPosition = FENConverter.convertPiecePlacementToPosition(FENConverter.emptyPosition);
 }
Beispiel #21
0
 public ParserError(int resourceID, Position pos)
     : base("")
 {
     this.pos = pos;
     this.resourceID = resourceID;
 }
Beispiel #22
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;
 }
Beispiel #23
0
 private void GameInit()
 {
     currentPosition = FENConverter.convertFENToPosition(FENConverter.startPosition);
     unMakeInfo = new UnMakeInfo();
     gameFinished = false;
     undoMove = false;
 }
Beispiel #24
0
 /*
  * Set a given piece in a given square
  */
 private static void setPieceSafely(Position position, int file, int rank, PieceType piece)
 {
     if (rank < 0) throw new ParserError("Too many ranks");
     if (file > 7) throw new ParserError("Too many columns");
     if ((piece == PieceType.P) || (piece == PieceType.p))
     {
         if ((rank == 0) || (rank == 7))
         {
             throw new ParserError("Pawn of first or last rank");
         }
     }
     position.setPiece(Position.getSquare(file, rank), piece);
 }
Beispiel #25
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;
        }
Beispiel #26
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;
        }
Beispiel #27
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);
         }
     }
 }
Beispiel #28
0
 /*
  * Determines if two positions are equal in the sense of the draw by
  * the repetition rule.
  * Return true if positions are equal, false otherwise.
  */
 public Boolean drawRuleEquals(Position pos)
 {
     for (int i = 0; i < 64; i++)
     {
         if (pieceLayout[i] != pos.pieceLayout[i])
             return false;
     }
     if (whiteMove != pos.whiteMove)
         return false;
     if (epSquare != pos.epSquare)
         return false;
     return true;
 }
Beispiel #29
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();
        }
Beispiel #30
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);
 }