Пример #1
0
        /// <summary>
        /// KIF/KI2形式の指し手を与えて、Moveに変換する。指し手の合法性のチェックはここでは行わない。
        /// 変換に失敗したときはMove.NONEが返る。
        /// </summary>
        /// <param name="pos"></param>
        /// <param name="kifMove"></param>
        /// <returns></returns>
        public static Move FromKif(this Position pos, string kifMove)
        {
            // match.Group[1]: ([▲△▼▽☗☖⛊⛉]?)
            // match.Group[2]: ([1-9123456789一二三四五六七八九]{2}同?)
            // match.Group[3]: (同)
            // match.Group[4]: ([歩香桂銀金角飛玉王と杏圭全馬竜龍]|成[香桂銀])
            // match.Group[5]: ([右左]?[上寄引]?|直)
            // match.Group[6]: (成|不成|打)?
            // match.Group[7]: (\([1-9]{2}\))?
            Match match = new Regex(@"([▲△▼▽☗☖⛊⛉]?)(?:([1-9123456789一二三四五六七八九]{2}同?)|(同))[  ]*([歩香桂銀金角飛玉王と杏圭全馬竜龍]|成[香桂銀])(直|[右左]?[上寄引]?)(成|不成|打)?(\([1-9]{2}\))?").Match(kifMove);

            if (!match.Success)
            {
                return(Move.NONE);
            }
            Color  c0 = pos.sideToMove;
            Color  c1 = FromColor(match.Groups[1].Value);
            Square sq0;
            Square sq1 = match.Groups[3].Value == "同" ? pos.State().lastMove.To() : FromSquare(match.Groups[2].Value);

            if (sq1 == Square.NB)
            {
                return(Move.NONE);
            }
            Piece pt1 = FromKifPieceType(match.Groups[4].Value);

            // 駒打ち
            if (match.Groups[6].Value == "打")
            {
                return(Util.MakeMoveDrop(pt1, sq1));
            }
            // 成チェック
            bool isPromote = (match.Groups[6].Value == "成");

            // KIF形式で元座標が示されている場合
            if (match.Groups[7].Value.Length == 4)
            {
                sq0 = FromSquare(match.Groups[7].Value.Substring(1, 2));
                return(isPromote ? Util.MakeMovePromote(sq0, sq1) : Util.MakeMove(sq0, sq1));
            }
            // KI2棋譜用処理
            // 駒の移動範囲を調べるため、着手前の駒を求める
            Piece    pt0    = isPromote ? pt1.RawPieceType() : pt1;
            Bitboard sameBB = pos.AttackersTo(c0, sq1) & pos.Pieces(c0, pt0);

            if (sameBB.IsZero())
            {
                return(Move.NONE);
            }
            if (sameBB.IsOne())
            {
                sq0 = sameBB.Pop();
                return(isPromote ? Util.MakeMovePromote(sq0, sq1) : Util.MakeMove(sq0, sq1));
            }
            Bitboard bb;

            switch (match.Groups[5].Value)
            {
            case "右":
                sq0 = rightMost(c0, sameBB);
                break;

            case "左":
                sq0 = leftMost(c0, sameBB);
                break;

            case "直":
                bb = (KifUtil.lineDirBB(c0, sq1, Direct.D) & sameBB);
                if (!bb.IsOne())
                {
                    return(Move.NONE);
                }
                sq0 = bb.Pop();
                break;

            case "上":
                bb = (KifUtil.dirBB(c0, sq1, Direct.D) & sameBB);
                if (!bb.IsOne())
                {
                    return(Move.NONE);
                }
                sq0 = bb.Pop();
                break;

            case "引":
                bb = (KifUtil.dirBB(c0, sq1, Direct.U) & sameBB);
                if (!bb.IsOne())
                {
                    return(Move.NONE);
                }
                sq0 = bb.Pop();
                break;

            case "寄":
                bb = (Bitboard.RankBB(sq1.ToRank()) & sameBB);
                if (!bb.IsOne())
                {
                    return(Move.NONE);
                }
                sq0 = bb.Pop();
                break;

            case "右上":
                bb  = (KifUtil.dirBB(c0, sq1, Direct.D) & sameBB);
                sq0 = rightMost(c0, bb);
                break;

            case "左上":
                bb  = (KifUtil.dirBB(c0, sq1, Direct.D) & sameBB);
                sq0 = leftMost(c0, bb);
                break;

            case "右引":
                bb  = (KifUtil.dirBB(c0, sq1, Direct.U) & sameBB);
                sq0 = rightMost(c0, bb);
                break;

            case "左引":
                bb  = (KifUtil.dirBB(c0, sq1, Direct.U) & sameBB);
                sq0 = leftMost(c0, bb);
                break;

            case "右寄":
                bb  = (Bitboard.RankBB(sq1.ToRank()) & sameBB);
                sq0 = rightMost(c0, bb);
                break;

            case "左寄":
                bb  = (Bitboard.RankBB(sq1.ToRank()) & sameBB);
                sq0 = leftMost(c0, bb);
                break;

            default: return(Move.NONE);
            }
            if (sq0 == Square.NB)
            {
                return(Move.NONE);
            }
            return(isPromote ? Util.MakeMovePromote(sq0, sq1) : Util.MakeMove(sq0, sq1));
        }
Пример #2
0
        static string fromSqFormat_KI2(Position pos, Move move)
        {
            Color    c = pos.sideToMove;
            Square   fromSq = move.From(), toSq = move.To();
            Piece    p = pos.PieceOn(fromSq), pt = p.PieceType();
            Bitboard sameBB = pos.AttackersTo(c, toSq) & pos.Pieces(c, pt);

            if (!sameBB.IsSet(fromSq))
            {
                return("");
            }
            if (sameBB.IsOne())
            {
                return("");
            }
            if (KifUtil.checkBB(sameBB, Bitboard.RankBB(toSq.ToRank()), fromSq))
            {
                return("寄");
            }
            if (KifUtil.checkBB(sameBB, KifUtil.dirBB(c, toSq, Direct.D), fromSq))
            {
                return("上");
            }
            if (KifUtil.checkBB(sameBB, KifUtil.dirBB(c, toSq, Direct.U), fromSq))
            {
                return("引");
            }
            if (KifUtil.checkBB(sameBB, KifUtil.lineDirBB(c, toSq, Direct.D), fromSq) && (
                    pt == Piece.SILVER || pt == Piece.GOLD ||
                    pt == Piece.PRO_PAWN || pt == Piece.PRO_LANCE || pt == Piece.PRO_KNIGHT || pt == Piece.PRO_SILVER
                    ))
            {
                return("直");
            }
            if (KifUtil.checkBB(sameBB, KifUtil.dirOrBB(c, fromSq, Direct.L), fromSq))
            {
                return("左");
            }
            if (KifUtil.checkBB(sameBB, KifUtil.dirOrBB(c, fromSq, Direct.R), fromSq))
            {
                return("右");
            }
            if (KifUtil.checkBB(sameBB, KifUtil.lineDirOrBB(c, fromSq, Direct.L) & Bitboard.RankBB(toSq.ToRank()), fromSq))
            {
                return("左寄");
            }
            if (KifUtil.checkBB(sameBB, KifUtil.lineDirOrBB(c, fromSq, Direct.R) & Bitboard.RankBB(toSq.ToRank()), fromSq))
            {
                return("右寄");
            }
            if (KifUtil.checkBB(sameBB, KifUtil.dirBB(c, toSq, Direct.D) & KifUtil.dirOrBB(c, fromSq, Direct.L), fromSq))
            {
                return("左上");
            }
            if (KifUtil.checkBB(sameBB, KifUtil.dirBB(c, toSq, Direct.D) & KifUtil.dirOrBB(c, fromSq, Direct.R), fromSq))
            {
                return("右上");
            }
            if (KifUtil.checkBB(sameBB, KifUtil.dirBB(c, toSq, Direct.U) & KifUtil.dirOrBB(c, fromSq, Direct.L), fromSq))
            {
                return("左引");
            }
            if (KifUtil.checkBB(sameBB, KifUtil.dirBB(c, toSq, Direct.U) & KifUtil.dirOrBB(c, fromSq, Direct.R), fromSq))
            {
                return("右引");
            }
            // 正常な局面・指し手でここに到達する筈は無い
            return("");
        }