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; }
/// <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; }