예제 #1
0
 /// <summary>get only LEGAL Operations by testing with domove</summary>
 public override int GenerateMoves(Board board, int[] moves, int index)
 {
     int lastIndex = base.GenerateMoves(board, moves, index);
     int j = index;
     for (int i = 0; i < lastIndex; i++)
     {
         if (board.DoMove(moves[i], false))
         {
             moves[j++] = moves[i];
             board.UndoMove();
         }
     }
     return j;
 }
예제 #2
0
파일: Move.cs 프로젝트: rayokota/carballo
        /// <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;
        }