public virtual int GenerateMoves(Board board, int[] moves, int mIndex)
 {
     this.moves = moves;
     bbAttacks = BitboardAttacks.GetInstance();
     moveIndex = mIndex;
     all = board.GetAll();
     // only for clearity
     mines = board.GetMines();
     others = board.GetOthers();
     byte index = 0;
     long square = unchecked((long)(0x1L));
     while (square != 0)
     {
         if (board.GetTurn() == ((square & board.whites) != 0))
         {
             if ((square & board.rooks) != 0)
             {
                 // Rook
                 GenerateMovesFromAttacks(Move.ROOK, index, bbAttacks.GetRookAttacks(index, all));
             }
             else
             {
                 if ((square & board.bishops) != 0)
                 {
                     // Bishop
                     GenerateMovesFromAttacks(Move.BISHOP, index, bbAttacks.GetBishopAttacks(index, all
                         ));
                 }
                 else
                 {
                     if ((square & board.queens) != 0)
                     {
                         // Queen
                         GenerateMovesFromAttacks(Move.QUEEN, index, bbAttacks.GetRookAttacks(index, all));
                         GenerateMovesFromAttacks(Move.QUEEN, index, bbAttacks.GetBishopAttacks(index, all
                             ));
                     }
                     else
                     {
                         if ((square & board.kings) != 0)
                         {
                             // King
                             GenerateMovesFromAttacks(Move.KING, index, bbAttacks.king[index]);
                         }
                         else
                         {
                             if ((square & board.knights) != 0)
                             {
                                 // Knight
                                 GenerateMovesFromAttacks(Move.KNIGHT, index, bbAttacks.knight[index]);
                             }
                             else
                             {
                                 if ((square & board.pawns) != 0)
                                 {
                                     // Pawns
                                     if ((square & board.whites) != 0)
                                     {
                                         if (((square << 8) & all) == 0)
                                         {
                                             AddMoves(Move.PAWN, index, index + 8, (square << 8), false, true, 0);
                                             // Two squares if it is in he first row
                                             if (((square & BitboardUtils.b2_d) != 0) && (((square << 16) & all) == 0))
                                             {
                                                 AddMoves(Move.PAWN, index, index + 16, (square << 16), false, false, 0);
                                             }
                                         }
                                         GeneratePawnCapturesFromAttacks(index, bbAttacks.pawnUpwards[index], board.GetPassantSquare
                                             ());
                                     }
                                     else
                                     {
                                         if ((((long)(((ulong)square) >> 8)) & all) == 0)
                                         {
                                             AddMoves(Move.PAWN, index, index - 8, ((long)(((ulong)square) >> 8)), false, true
                                                 , 0);
                                             // Two squares if it is in he first row
                                             if (((square & BitboardUtils.b2_u) != 0) && ((((long)(((ulong)square) >> 16)) & all
                                                 ) == 0))
                                             {
                                                 AddMoves(Move.PAWN, index, index - 16, ((long)(((ulong)square) >> 16)), false, false
                                                     , 0);
                                             }
                                         }
                                         GeneratePawnCapturesFromAttacks(index, bbAttacks.pawnDownwards[index], board.GetPassantSquare
                                             ());
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
         square <<= 1;
         index++;
     }
     square = board.kings & mines;
     // my king
     byte myKingIndex = unchecked((byte)(-1));
     // Castling: disabled when in check or squares attacked
     if ((((all & (board.GetTurn() ? unchecked((long)(0x06L)) : unchecked((long)(0x0600000000000000L
         )))) == 0 && (board.GetTurn() ? board.GetWhiteKingsideCastling() : board.GetBlackKingsideCastling
         ()))))
     {
         myKingIndex = BitboardUtils.Square2Index(square);
         if (!board.GetCheck() && !bbAttacks.IsIndexAttacked(board, unchecked((byte)(myKingIndex
              - 1)), board.GetTurn()) && !bbAttacks.IsIndexAttacked(board, unchecked((byte)(myKingIndex
              - 2)), board.GetTurn()))
         {
             AddMoves(Move.KING, myKingIndex, myKingIndex - 2, 0, false, false, Move.TYPE_KINGSIDE_CASTLING
                 );
         }
     }
     if ((((all & (board.GetTurn() ? unchecked((long)(0x70L)) : unchecked((long)(0x7000000000000000L
         )))) == 0 && (board.GetTurn() ? board.GetWhiteQueensideCastling() : board.GetBlackQueensideCastling
         ()))))
     {
         if (myKingIndex == -1)
         {
             myKingIndex = BitboardUtils.Square2Index(square);
         }
         if (!board.GetCheck() && !bbAttacks.IsIndexAttacked(board, unchecked((byte)(myKingIndex
              + 1)), board.GetTurn()) && !bbAttacks.IsIndexAttacked(board, unchecked((byte)(myKingIndex
              + 2)), board.GetTurn()))
         {
             AddMoves(Move.KING, myKingIndex, myKingIndex + 2, 0, false, false, Move.TYPE_QUEENSIDE_CASTLING
                 );
         }
     }
     return moveIndex;
 }
Beispiel #2
0
        /// <summary>
        /// Given a boards creates a move from a String in uci format or short
        /// algebraic form
        /// </summary>
        /// <param name="board"></param>
        /// <param name="move"></param>
        public static int GetFromString(Board board, string move, bool checkLegality)
        {
            int fromIndex = 0;
            int toIndex = 0;
            int moveType = 0;
            int pieceMoved = 0;
            // Ignore checks, captures indicators...
            move = move.Replace("+", string.Empty).Replace("x", string.Empty).Replace("-", string.Empty
                ).Replace("=", string.Empty).Replace("#", string.Empty).ReplaceAll(" ", string.Empty
                ).ReplaceAll("0", "o").ReplaceAll("O", "o");
            if ("ooo".Equals(move))
            {
                if (board.GetTurn())
                {
                    move = "e1c1";
                }
                else
                {
                    move = "e8c8";
                }
            }
            else
            {
                if ("oo".Equals(move))
                {
                    if (board.GetTurn())
                    {
                        move = "e1g1";
                    }
                    else
                    {
                        move = "e8g8";
                    }
                }
            }
            char promo = move[move.Length - 1];
            switch (System.Char.ToLower(promo))
            {
                case 'q':
                {
                    moveType = TYPE_PROMOTION_QUEEN;
                    break;
                }

                case 'n':
                {
                    moveType = TYPE_PROMOTION_KNIGHT;
                    break;
                }

                case 'b':
                {
                    moveType = TYPE_PROMOTION_BISHOP;
                    break;
                }

                case 'r':
                {
                    moveType = TYPE_PROMOTION_ROOK;
                    break;
                }
            }
            // If promotion, remove the last char
            if (moveType != 0)
            {
                move = Sharpen.Runtime.Substring(move, 0, move.Length - 1);
            }
            // To is always the last 2 characters
            toIndex = BitboardUtils.Algebraic2Index(Sharpen.Runtime.Substring(move, move.Length
                 - 2, move.Length));
            long to = unchecked((long)(0x1L)) << toIndex;
            long from = 0;
            BitboardAttacks bbAttacks = BitboardAttacks.GetInstance();
            switch (move[0])
            {
                case 'N':
                {
                    // Fills from with a mask of possible from values
                    from = board.knights & board.GetMines() & bbAttacks.knight[toIndex];
                    break;
                }

                case 'K':
                {
                    from = board.kings & board.GetMines() & bbAttacks.king[toIndex];
                    break;
                }

                case 'R':
                {
                    from = board.rooks & board.GetMines() & bbAttacks.GetRookAttacks(toIndex, board.GetAll
                        ());
                    break;
                }

                case 'B':
                {
                    from = board.bishops & board.GetMines() & bbAttacks.GetBishopAttacks(toIndex, board
                        .GetAll());
                    break;
                }

                case 'Q':
                {
                    from = board.queens & board.GetMines() & (bbAttacks.GetRookAttacks(toIndex, board
                        .GetAll()) | bbAttacks.GetBishopAttacks(toIndex, board.GetAll()));
                    break;
                }
            }
            if (from != 0)
            {
                // remove the piece char
                move = Sharpen.Runtime.Substring(move, 1);
            }
            else
            {
                // Pawn moves
                if (move.Length == 2)
                {
                    if (board.GetTurn())
                    {
                        from = board.pawns & board.GetMines() & (((long)(((ulong)to) >> 8)) | ((((long)((
                            (ulong)to) >> 8)) & board.GetAll()) == 0 ? ((long)(((ulong)to) >> 16)) : 0));
                    }
                    else
                    {
                        from = board.pawns & board.GetMines() & ((to << 8) | (((to << 8) & board.GetAll()
                            ) == 0 ? (to << 16) : 0));
                    }
                }
                if (move.Length == 3)
                {
                    // Pawn capture
                    from = board.pawns & board.GetMines() & (board.GetTurn() ? bbAttacks.pawnDownwards
                        [toIndex] : bbAttacks.pawnUpwards[toIndex]);
                }
            }
            if (move.Length == 3)
            {
                // now disambiaguate
                char disambiguate = move[0];
                int i = "abcdefgh".IndexOf(disambiguate);
                if (i >= 0)
                {
                    from &= BitboardUtils.COLUMN[i];
                }
                int j = "12345678".IndexOf(disambiguate);
                if (j >= 0)
                {
                    from &= BitboardUtils.RANK[j];
                }
            }
            // if (BitboardUtils.popCount(from) > 1) {
            // logger.error("Move NOT disambiaguated:\n"+board.toString() + "\n" +
            // in);
            // System.exit(-1);
            // return -1;
            // }
            if (move.Length == 4)
            {
                // was algebraic complete e2e4 (=UCI!)
                from = BitboardUtils.Algebraic2Square(Sharpen.Runtime.Substring(move, 0, 2));
            }
            if (from == 0)
            {
                return -1;
            }
            // Treats multiple froms, choosing the first Legal Move
            while (from != 0)
            {
                long myFrom = BitboardUtils.Lsb(from);
                from ^= myFrom;
                fromIndex = BitboardUtils.Square2Index(myFrom);
                bool capture = false;
                if ((myFrom & board.pawns) != 0)
                {
                    pieceMoved = PAWN;
                    // for passant captures
                    if ((toIndex != (fromIndex - 8)) && (toIndex != (fromIndex + 8)) && (toIndex != (
                        fromIndex - 16)) && (toIndex != (fromIndex + 16)))
                    {
                        if ((to & board.GetAll()) == 0)
                        {
                            moveType = TYPE_PASSANT;
                            capture = true;
                        }
                    }
                    // later is changed if it was not a pawn
                    // Default promotion to queen if not specified
                    if ((to & (BitboardUtils.b_u | BitboardUtils.b_d)) != 0 && (moveType < TYPE_PROMOTION_QUEEN
                        ))
                    {
                        moveType = TYPE_PROMOTION_QUEEN;
                    }
                }
                if ((myFrom & board.bishops) != 0)
                {
                    pieceMoved = BISHOP;
                }
                else
                {
                    if ((myFrom & board.knights) != 0)
                    {
                        pieceMoved = KNIGHT;
                    }
                    else
                    {
                        if ((myFrom & board.rooks) != 0)
                        {
                            pieceMoved = ROOK;
                        }
                        else
                        {
                            if ((myFrom & board.queens) != 0)
                            {
                                pieceMoved = QUEEN;
                            }
                            else
                            {
                                if ((myFrom & board.kings) != 0)
                                {
                                    pieceMoved = KING;
                                    // Only if origin square is king's initial square TODO FRC
                                    if (fromIndex == 3 || fromIndex == 3 + (8 * 7))
                                    {
                                        if (toIndex == (fromIndex + 2))
                                        {
                                            moveType = TYPE_QUEENSIDE_CASTLING;
                                        }
                                        if (toIndex == (fromIndex - 2))
                                        {
                                            moveType = TYPE_KINGSIDE_CASTLING;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                // Now set captured piece flag
                if ((to & (board.whites | board.blacks)) != 0)
                {
                    capture = true;
                }
                int moveInt = Move.GenMove(fromIndex, toIndex, pieceMoved, capture, moveType);
                if (checkLegality && board.DoMove(moveInt, false))
                {
                    board.UndoMove();
                    return moveInt;
                }
                else
                {
                    return moveInt;
                }
            }
            return -1;
        }