Ejemplo n.º 1
0
        public Bitboard GetCapturesMoveBoard(Bitboard notblockers, Bitboard enemies, Square? enpassant)
        {
            if (enpassant != null)
                enemies &= new Bitboard().And((Square)enpassant);

            var bleft = Locations.Except(new File(0)).Shift(1, -1).Intersect(enemies);
            var bright = Locations.Except(new File(7)).Shift(1, 1).Intersect(enemies);
            return bleft | bright;
        }
Ejemplo n.º 2
0
 public IEnumerable<Move> GetAllMoves(
     Bitboard notblockers,
     Bitboard enemies,
     Square? enpassant
     )
 {
     return GetMovesOneSquareForward(notblockers)
         .Union(GetMovesTwoSquaresForward(notblockers))
         .Union(GetCaptures(enemies, enpassant));
 }
Ejemplo n.º 3
0
        public Bitboard GetMoveBoard(Square from, Bitboard friends, Bitboard enemies)
        {
            var allpieces = friends.And(enemies);
            var result = Bitboard.Empty.And(from.File, from.Rank);

            return result.Except(from, friends,
                from.RayTo.N.Intersect(allpieces).LowestSquare.RayTo.N,
                from.RayTo.E.Intersect(allpieces).LowestSquare.RayTo.E,
                from.RayTo.S.Intersect(allpieces).HighestSquare.RayTo.S,
                from.RayTo.W.Intersect(allpieces).HighestSquare.RayTo.W);
        }
Ejemplo n.º 4
0
        public IEnumerable<Move> GetCaptures(Bitboard enemies, Bitboard filterFrom, Bitboard filterTo, Square? enpassant = null)
        {
            if (enpassant != null)
                enemies |= new Bitboard().And((Square) enpassant);

            enemies &= filterTo;
            Bitboard l = Locations.Intersect(filterFrom);
            Bitboard bleft = l.Except(new File(7)).Shift(-1, +1).Intersect(enemies);
            Bitboard bright = l.Except(new File(0)).Shift(-1, -1).Intersect(enemies);

            return GetMoves(bleft, 7).Union(GetMoves(bright, 9));
        }
Ejemplo n.º 5
0
        public Bitboard GetMoveBoard(Bitboard notblockers, Bitboard enemies, Square? enpassant)
        {
            ulong onesquarforward = (Locations >> 8 & notblockers);

            Bitboard twosquaresforward = Locations
                .Intersect(new Rank(6))
                .Shift(-1, 0).Intersect(notblockers)
                .Shift(-1, 0).Intersect(notblockers);

            return onesquarforward | twosquaresforward |
                   GetCapturesMoveBoard(notblockers, enemies, enpassant);
        }
Ejemplo n.º 6
0
        public Bitboard Get(Square from,
            Bitboard friends,
            Bitboard enemies
            )
        {
            var allpieces = friends.And(enemies);
            var result = Bitboard.Empty.And(from.DiagonalNW, from.DiagonalNE);

            return result.Except(from, friends,
                                 from.RayTo.NE.Intersect(allpieces).LowestSquare.RayTo.NE,
                                 from.RayTo.NW.Intersect(allpieces).LowestSquare.RayTo.NW,
                                 from.RayTo.SE.Intersect(allpieces).HighestSquare.RayTo.SE,
                                 from.RayTo.SW.Intersect(allpieces).HighestSquare.RayTo.SW);
        }
Ejemplo n.º 7
0
 public static bool checkBB(Bitboard samebb, Bitboard dirbb, Square sq) => (dirbb.IsSet(sq) && (samebb & dirbb).IsOne());
Ejemplo n.º 8
0
 public BlackPawns(Bitboard locations)
     : this()
 {
     Locations = locations;
 }
Ejemplo n.º 9
0
 /// <summary>
 /// Calculates move specified in the derived class.
 /// </summary>
 /// <param name="bitboard">The bitboard.</param>
 public abstract void CalculateMove(Bitboard bitboard);
Ejemplo n.º 10
0
 private BoardBuilder(Bitboard board, bool inverted)
     : this()
 {
     this.result = board;
     this.inverted = inverted;
 }
Ejemplo n.º 11
0
 internal static Bitboard RstFile(ref Bitboard bb, SquareE sqr)
 {
     return(bb &= ~FileMask(sqr));
 }
Ejemplo n.º 12
0
 /// <summary>
 /// Helper method for derived classes, calculates move with the specified parameters.
 /// </summary>
 /// <param name="bitboard">The bitboard.</param>
 /// <param name="pieceType">The piece type.</param>
 /// <param name="from">The piece source position.</param>
 /// <param name="to">The piece destination position.</param>
 protected void CalculatePieceMove(Bitboard bitboard, PieceType pieceType, ulong from, ulong to)
 {
     CalculatePieceMove(bitboard, pieceType, from, pieceType, to);
 }
 public InternalCastlingInfo2(GameMove2 kingMove, Bitboard expectedEmptySquares)
 {
     KingMove             = kingMove;
     ExpectedEmptySquares = expectedEmptySquares;
 }
Ejemplo n.º 14
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));
        }
Ejemplo n.º 15
0
        public void GeneratePawnMoves(
            [NotNull] ICollection <GameMoveData> resultMoves,
            GameSide side,
            GeneratedMoveTypes moveTypes,
            Bitboard enPassantCaptureTarget,
            Bitboard target)
        {
            if (resultMoves is null)
            {
                throw new ArgumentNullException(nameof(resultMoves));
            }

            var pawnPiece = side.ToPiece(PieceType.Pawn);
            var pawns     = PiecePosition[pawnPiece];

            if (pawns.IsNone)
            {
                return;
            }

            var rank8 = side == GameSide.White ? Bitboards.Rank8 : Bitboards.Rank1;

            if (moveTypes.IsAnySet(GeneratedMoveTypes.Quiet))
            {
                var forwardDirection = side == GameSide.White ? ShiftDirection.North : ShiftDirection.South;
                var emptySquares     = PiecePosition[Piece.None];
                var pushes           = pawns.Shift(forwardDirection) & emptySquares;

                var targetPushes = pushes & target;
                if (targetPushes.IsAny)
                {
                    var nonPromotionPushes = targetPushes & ~rank8;
                    PopulatePawnMoves(resultMoves, nonPromotionPushes, (int)forwardDirection, GameMoveFlags.None);

                    var promotionPushes = targetPushes & rank8;
                    PopulatePawnMoves(
                        resultMoves,
                        promotionPushes,
                        (int)forwardDirection,
                        GameMoveFlags.IsPawnPromotion);
                }

                if (pushes.IsAny)
                {
                    var rank3        = side == GameSide.White ? Bitboards.Rank3 : Bitboards.Rank6;
                    var doublePushes = (pushes & rank3).Shift(forwardDirection) & emptySquares & target;
                    PopulatePawnMoves(
                        resultMoves,
                        doublePushes,
                        (int)forwardDirection << 1,
                            GameMoveFlags.None);
                }
            }

            //// ReSharper disable once InvertIf
            if (moveTypes.IsAnySet(GeneratedMoveTypes.Capture))
            {
                var enemies      = PiecePosition[side.Invert()];
                var enemyTargets = enemies & target;

                var leftCaptureOffset = side == GameSide.White ? ShiftDirection.NorthWest : ShiftDirection.SouthEast;
                PopulatePawnCaptures(resultMoves, pawns, enemyTargets, leftCaptureOffset, rank8, enPassantCaptureTarget);

                var rightCaptureOffset = side == GameSide.White ? ShiftDirection.NorthEast : ShiftDirection.SouthWest;
                PopulatePawnCaptures(resultMoves, pawns, enemyTargets, rightCaptureOffset, rank8, enPassantCaptureTarget);
            }
        }
Ejemplo n.º 16
0
        public void GenerateKnightMoves(
            [NotNull] ICollection <GameMoveData> resultMoves,
            GameSide side,
            GeneratedMoveTypes moveTypes,
            Bitboard target)
        {
            if (resultMoves is null)
            {
                throw new ArgumentNullException(nameof(resultMoves));
            }

            var emptySquares = PiecePosition[Piece.None];
            var enemies      = PiecePosition[side.Invert()];

            var internalTarget = Bitboard.None;

            if (moveTypes.IsAnySet(GeneratedMoveTypes.Quiet))
            {
                internalTarget |= emptySquares;
            }

            if (moveTypes.IsAnySet(GeneratedMoveTypes.Capture))
            {
                internalTarget |= enemies;
            }

            var actualTarget = target & internalTarget;

            if (actualTarget.IsNone)
            {
                return;
            }

            var knightPiece = side.ToPiece(PieceType.Knight);
            var knights     = PiecePosition[knightPiece];

            while (knights.IsAny)
            {
                var sourceSquareIndex = Bitboard.PopFirstSquareIndex(ref knights);
                var moves             = KnightAttacksOrMoves[sourceSquareIndex];
                var movesOnTarget     = moves & actualTarget;
                if (movesOnTarget.IsNone)
                {
                    continue;
                }

                var sourceSquare = new Square(sourceSquareIndex);
                if (moveTypes.IsAnySet(GeneratedMoveTypes.Capture))
                {
                    var captures = movesOnTarget & enemies;
                    PopulateSimpleMoves(resultMoves, sourceSquare, captures, GameMoveFlags.IsRegularCapture);
                }

                //// ReSharper disable once InvertIf
                if (moveTypes.IsAnySet(GeneratedMoveTypes.Quiet))
                {
                    var nonCaptures = movesOnTarget & emptySquares;
                    PopulateSimpleMoves(resultMoves, sourceSquare, nonCaptures, GameMoveFlags.None);
                }
            }
        }
Ejemplo n.º 17
0
        private Bitboard GetAttackersInternal(
            Square targetSquare,
            GameSide attackingSide,
            bool findFirstAttackOnly)
        {
            var result = new Bitboard();

            var targetBitboard    = targetSquare.Bitboard;
            var targetSquareIndex = targetSquare.SquareIndex;

            var opponentPawns = PiecePosition[attackingSide.ToPiece(PieceType.Pawn)];

            if (opponentPawns.IsAny)
            {
                ShiftDirection left;
                ShiftDirection right;
                if (attackingSide == GameSide.White)
                {
                    left  = ShiftDirection.SouthEast;
                    right = ShiftDirection.SouthWest;
                }
                else
                {
                    left  = ShiftDirection.NorthWest;
                    right = ShiftDirection.NorthEast;
                }

                var attackingPawns = (targetBitboard.Shift(left) | targetBitboard.Shift(right)) & opponentPawns;
                result |= attackingPawns;
                if (findFirstAttackOnly && result.IsAny)
                {
                    return(result);
                }
            }

            var opponentKnights = PiecePosition[attackingSide.ToPiece(PieceType.Knight)];

            if (opponentKnights.IsAny)
            {
                var knightAttacks    = KnightAttacksOrMoves[targetSquareIndex];
                var attackingKnights = knightAttacks & opponentKnights;
                result |= attackingKnights;
                if (findFirstAttackOnly && result.IsAny)
                {
                    return(result);
                }
            }

            var opponentKings = PiecePosition[attackingSide.ToPiece(PieceType.King)];

            if (opponentKings.IsAny)
            {
                var kingAttacks    = KingAttacksOrMoves[targetSquareIndex];
                var attackingKings = kingAttacks & opponentKings;
                result |= attackingKings;
                if (findFirstAttackOnly && result.IsAny)
                {
                    return(result);
                }
            }

            var emptySquareBitboard = PiecePosition[Piece.None];

            var opponentQueens = PiecePosition[attackingSide.ToPiece(PieceType.Queen)];
            var opponentRooks  = PiecePosition[attackingSide.ToPiece(PieceType.Rook)];

            var opponentSlidingStraightPieces = opponentQueens | opponentRooks;
            var slidingStraightAttackers      =
                GetSlidingAttackers(
                    targetSquareIndex,
                    opponentSlidingStraightPieces,
                    StraightSlidingAttacks,
                    emptySquareBitboard,
                    findFirstAttackOnly);

            result |= slidingStraightAttackers;
            if (findFirstAttackOnly && result.IsAny)
            {
                return(result);
            }

            var opponentBishops = PiecePosition[attackingSide.ToPiece(PieceType.Bishop)];

            var opponentSlidingDiagonallyPieces = opponentQueens | opponentBishops;
            var slidingDiagonallyAttackers      =
                GetSlidingAttackers(
                    targetSquareIndex,
                    opponentSlidingDiagonallyPieces,
                    DiagonallySlidingAttacks,
                    emptySquareBitboard,
                    findFirstAttackOnly);

            result |= slidingDiagonallyAttackers;

            return(result);
        }
Ejemplo n.º 18
0
        /// <summary>
        /// 仲間を支えていた駒が離れたら真だぜ☆(^▽^)www
        ///
        /// 利きテーブルをいじっているが、更新したいわけではないので、使い終わったら元に戻すぜ☆(^~^)
        /// </summary>
        /// <param name="out_ret"></param>
        /// <param name="ms_t0">移動元</param>
        /// <param name="ms_t1">移動先</param>
        /// <returns></returns>
        public static bool IsMisuteruUgoki()
        {
            // 升にある駒種類
            Komasyurui ks_t0;

            if (PureMemory.gky_ky.shogiban.ibashoBan_yk00.yomiIbashoBan.ExistsKoma(PureMemory.kifu_teban, PureMemory.ssss_ugoki_ms_src, out ks_t0))
            {
            }

            Piece km_t0 = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks_t0, PureMemory.kifu_teban);
            Piece km_t1 = km_t0;     //FIXME:成りを考慮してないぜ☆(>_<)

            int sasaeBeforeMove = 0; // 移動前に、動こうとしている駒を支えている味方の数
            int sasaeAfterMove  = 0; // 移動後の、動いた駒を支えている味方の数

            // 移動前の駒の動き(2個作っておく)
            Bitboard bbConst_kiki0 = BitboardsOmatome.KomanoUgokikataYk00.Clone_Merge(km_t0, PureMemory.ssss_ugoki_ms_src);
            Bitboard bbVar_kiki    = bbConst_kiki0.Clone();

            if (!bbConst_kiki0.IsEmpty())
            {
                // 移動する前の、利き先の 利きの数を数えておこうぜ☆(^▽^)
                Masu ms_kiki;
                while (bbVar_kiki.Ref_PopNTZ(out ms_kiki))
                {
                    // 0以上なら駒の取り合いで勝つぜ☆(^▽^)
                    // 利き重ね = 自分の利き数 - 相手の利き数
                    int kasaneGake = PureMemory.gky_ky.shogiban.kikiBan.yomiKikiBan.CountKikisuZenbu(PureMemory.kifu_teban, ms_kiki) - PureMemory.gky_ky.shogiban.kikiBan.yomiKikiBan.CountKikisuZenbu(PureMemory.kifu_aiteban, ms_kiki);
                    if (0 < kasaneGake)
                    {
                        sasaeBeforeMove++;
                    }
                }

                //────────────────────────────────────────
                // 駒は動かさず、移動前の利きを消す(減らす)ぜ☆(^▽^)
                //────────────────────────────────────────
                bbVar_kiki.Set(bbConst_kiki0);
                //ビットボード使い回し
                PureMemory.gky_ky.shogiban.kikiBan.TorinozokuKiki(km_t0, bbVar_kiki);
            }


            // 移動先での駒の動き
            Bitboard bbConst_kiki1 = BitboardsOmatome.KomanoUgokikataYk00.Clone_Merge(km_t1, PureMemory.ssss_ugoki_ms_dst);

            if (!bbConst_kiki1.IsEmpty())
            {
                // 駒を移動させた想定で、利きの数を増やすぜ☆(^▽^)
                bbVar_kiki.Set(bbConst_kiki1);
                //ビットボード使い回し
                PureMemory.gky_ky.shogiban.kikiBan.OkuKiki(km_t1, bbVar_kiki);

                // 移動した後の、利き先の 利きの数を数えておこうぜ☆(^▽^)
                bbVar_kiki.Set(bbConst_kiki1);
                Masu ms_kiki;
                while (bbVar_kiki.Ref_PopNTZ(out ms_kiki))
                {
                    // 0以上なら駒の取り合いで勝つぜ☆(^▽^)
                    // 利き重ね = 自分の利き数 - 相手の利き数
                    int kasaneGake = PureMemory.gky_ky.shogiban.kikiBan.yomiKikiBan.CountKikisuZenbu(PureMemory.kifu_teban, ms_kiki) - PureMemory.gky_ky.shogiban.kikiBan.yomiKikiBan.CountKikisuZenbu(PureMemory.kifu_aiteban, ms_kiki);
                    if (0 < kasaneGake)
                    {
                        sasaeAfterMove++;
                    }
                }
            }

            //────────────────────────────────────────
            // 利き数表をいじったんで、元に戻しておこうぜ☆(^▽^)
            //────────────────────────────────────────
            {
                bbVar_kiki.Set(bbConst_kiki1);
                if (!bbVar_kiki.IsEmpty())
                {
                    // 増やした分の重ね利きを減らして、元に戻すぜ☆(^▽^)
                    //ビットボード使い回し
                    PureMemory.gky_ky.shogiban.kikiBan.TorinozokuKiki(km_t1, bbVar_kiki);
                }
            }

            {
                bbVar_kiki.Set(bbConst_kiki0);
                // 減らした分の重ね利きを増やして、元に戻すぜ☆(^▽^)
                //ビットボード使い回し
                PureMemory.gky_ky.shogiban.kikiBan.OkuKiki(km_t0, bbVar_kiki);
            }

            return(sasaeBeforeMove - sasaeAfterMove < 0);
        }
Ejemplo n.º 19
0
 static GenerateMove03()
 {
     bbTmp_nifu = new Bitboard();
 }
Ejemplo n.º 20
0
        public string format(Position pos, Move move, Move lastMove)
        {
            StringBuilder kif = new StringBuilder();

            kif.Append(format(pos.sideToMove));
            switch (move)
            {
            case Move.NONE:
                return(kif.Append("エラー").ToString());

            case Move.NULL:
                return(kif.Append("パス").ToString());

            case Move.RESIGN:
                return(kif.Append("投了").ToString());

            case Move.WIN:
                return(kif.Append("勝ち宣言").ToString());
            }
            // 普通の指し手
            // 着手元の駒種
            Piece fromPiece     = pos.PieceOn(move.From());
            Piece fromPieceType = fromPiece.PieceType();

            if (lastMove.IsOk() && lastMove.To() == move.To())
            {
                // 一つ前の指し手の移動先と、今回の移動先が同じ場合、"同"金のように表示する。
                switch (sameposFmt)
                {
                case SamePosFormat.NONE:
                    break;

                case SamePosFormat.SHORT:
                    kif.Append("同");
                    break;

                // KIF形式では"同"の後に全角空白
                case SamePosFormat.KIFsp:
                    kif.Append("同 ");
                    break;

                // KI2形式では成香・成桂・成銀・成り動作での空白は入らない
                case SamePosFormat.KI2sp:
                    if (
                        move.IsPromote() ||
                        fromPieceType == Piece.PRO_LANCE ||
                        fromPieceType == Piece.PRO_KNIGHT ||
                        fromPieceType == Piece.PRO_SILVER
                        )
                    {
                        kif.Append("同");
                        break;
                    }
                    else
                    {
                        kif.Append("同 ");
                        break;
                    }

                // 座標 + "同"
                case SamePosFormat.Verbose:
                    kif.Append(format(move.To())).Append("同");
                    break;

                default:
                    throw new ConverterException();
                }
            }
            else
            {
                kif.Append(format(move.To()));
            }
            kif.Append(PIECE_KIF[pos.PieceOn(move.From()).ToInt()]);
            switch (fromsqFmt)
            {
            case FromSqFormat.NONE:
                break;

            case FromSqFormat.KIF:
            {
                if (move.IsDrop())
                {
                    // KIF形式では持駒からの着手は必ず"打"と表記する
                    kif.Append("打");
                }
                else
                {
                    if (move.IsPromote())
                    {
                        kif.Append("成");
                    }
                    else if (
                        !fromPiece.IsPromote() &&
                        fromPieceType != Piece.GOLD &&
                        fromPieceType != Piece.KING &&
                        (Util.CanPromote(pos.sideToMove, move.To()) ||
                         Util.CanPromote(pos.sideToMove, move.From()))
                        )
                    {
                        kif.Append("不成");
                    }
                    Square fromSquare = move.From();
                    kif.AppendFormat("({0}{1})",
                                     HW_NUMBER[move.From().ToFile().ToInt()],
                                     HW_NUMBER[move.From().ToRank().ToInt()]
                                     );
                }
                break;
            }

            case FromSqFormat.KI2:
            {
                if (move.IsDrop())
                {
                    // KI2では紛らわしくない場合、"打"と表記しない。
                    Bitboard sameBB = pos.AttackersTo(pos.sideToMove, move.To()) & pos.Pieces(pos.sideToMove, move.DroppedPiece());
                    if (!sameBB.IsZero())
                    {
                        kif.Append("打");
                    }
                    break;
                }
                kif.Append(fromSqFormat_KI2(pos, move));
                if (move.IsPromote())
                {
                    kif.Append("成");
                    break;
                }
                if (
                    !fromPiece.IsPromote() &&
                    fromPieceType != Piece.GOLD &&
                    fromPieceType != Piece.KING &&
                    (Util.CanPromote(pos.sideToMove, move.To()) ||
                     Util.CanPromote(pos.sideToMove, move.From()))
                    )
                {
                    kif.Append("不成");
                }
                break;
            }

            default:
                throw new ConverterException();
            }
            return(kif.ToString());
        }
Ejemplo n.º 21
0
        private bool IsLegal()
        {
            ColorE   color;
            Bitboard occupy;

            #region Pieces Count

            for (color = ColorE.White; color <= ColorE.Black; ++color)
            {
                occupy = Occupies[(byte)color];
                // check too many total pieces
                if (BitBoard.CountSets(occupy) > 16)
                {
                    return(false);
                }

                // check if the number of Pawns plus the number of extra Queens, Rooks, Bishops, Knights
                // (which can result only by promotion) exceeds 8

                // check too many color pieces
                if (PieceCount[(byte)color, (byte)PieceE.Pawn]
                    + Math.Max(PieceCount[(byte)color, (byte)PieceE.Queen] - 1, 0)
                    + Math.Max(PieceCount[(byte)color, (byte)PieceE.Rook] - 2, 0)
                    + Math.Max(PieceCount[(byte)color, (byte)PieceE.Bishop] - 2, 0)
                    + Math.Max(PieceCount[(byte)color, (byte)PieceE.Knight] - 2, 0)
                    > 8
                    )
                {
                    return(false);
                }

                if (PieceCount[(byte)color, (byte)PieceE.Bishop] > 1)
                {
                    Bitboard bishops = occupy & Pieces[(byte)PieceE.Bishop];

                    byte[] bishopCount = new byte[Color.Colors];

                    //SquareE[] square = BitBoard.GetSquares(occupy & board.Pieces[ (byte) PieceE.Bishop ]);
                    //foreach( SquareE sqr in square )
                    //    ++bishopCount[ (byte) Square._Color(sqr) ];

                    bishopCount[(byte)ColorE.White] = BitBoard.CountSets(BitBoard.LightSquares & bishops);
                    bishopCount[(byte)ColorE.Black] = BitBoard.CountSets(BitBoard.DarkSquares & bishops);

                    if (PieceCount[(byte)color, (byte)PieceE.Pawn]
                        + Math.Max(bishopCount[(byte)ColorE.White] - 1, 0)
                        + Math.Max(bishopCount[(byte)ColorE.Black] - 1, 0)
                        > 8)
                    {
                        Debug.Assert(false, "Illegal FEN format", "Too many Promotion Bishop of same color of " + color);
                        return(false);
                    }
                }

                // check for King
                byte king = PieceCount[(byte)color, (byte)PieceE.King];
                if (king != 1)  //Illegal King
                {
                    return(false);
                }
            }
            //

            if ((Pieces[(byte)PieceE.Pawn] & (BitBoard.Rank_1 | BitBoard.Rank_8)) != 0)
            {//Pawn rank one or eight
                return(false);
            }
            #endregion

            #region Overlapping

            Bitboard occupied = Occupied;
            if ((Occupies[(byte)ColorE.White] ^
                 Occupies[(byte)ColorE.Black]) !=
                occupied)
            {
                return(false);
            }

            if ((Pieces[(byte)PieceE.Pawn] ^
                 Pieces[(byte)PieceE.Knight] ^
                 Pieces[(byte)PieceE.Bishop] ^
                 Pieces[(byte)PieceE.Rook] ^
                 Pieces[(byte)PieceE.Queen] ^
                 Pieces[(byte)PieceE.King]) !=
                occupied)
            {
                return(false);
            }
            #endregion

            #region Castling

            color  = ColorE.White;
            occupy = Occupies[(byte)color];
            // check the white King is in place for castle
            if (Castle[(byte)color].AnyCastle)
            {
                if (BitBoard.GetSquare(occupy & Pieces[(byte)PieceE.King], SquareE.E1))
                {
                    Bitboard rooks = occupy & Pieces[(byte)PieceE.Rook];
                    // check the white Rook is in place for castle
                    if (Castle[(byte)color].ShortCastle &&
                        !BitBoard.GetSquare(rooks, SquareE.H1))
                    {
                        //Illegal WhiteShortCastle
                        return(false);
                    }
                    if (Castle[(byte)color].LongCastle &&
                        !BitBoard.GetSquare(rooks, SquareE.A1))
                    {
                        //Illegal WhiteLongCastle
                        return(false);
                    }
                }
                else    //Illegal WhiteCastle
                {
                    return(false);
                }
            }

            color  = ColorE.Black;
            occupy = Occupies[(byte)color];
            // check the black King is in place for castle
            if (Castle[(byte)color].AnyCastle)
            {
                if (BitBoard.GetSquare(occupy & Pieces[(byte)PieceE.King], SquareE.E8))
                {
                    Bitboard rooks = occupy & Pieces[(byte)PieceE.Rook];
                    // check the black Rook is in place for castle
                    if (Castle[(byte)color].ShortCastle &&
                        !BitBoard.GetSquare(rooks, SquareE.H8))
                    {
                        //Illegal BlackShortCastle
                        return(false);
                    }
                    if (Castle[(byte)color].LongCastle &&
                        !BitBoard.GetSquare(rooks, SquareE.A8))
                    {
                        //Illegal BlackLongCastle
                        return(false);
                    }
                }
                else    //Illegal BlackCastle
                {
                    return(false);
                }
            }
            #endregion

            #region EnPassant

            if (EnPassant != SquareE.NoSquare)
            {
                if (!Square.IsValid(EnPassant))
                {
                    return(false);
                }

                if (OnMove == ColorE.White &&
                    (Square._Rank(EnPassant) != RankE.Rank_6 || !BitBoard.GetSquare(Occupies[(byte)ColorE.Black] & Pieces[(byte)PieceE.Pawn], (SquareE)(EnPassant - 8)))
                    ||
                    OnMove == ColorE.Black &&
                    (Square._Rank(EnPassant) != RankE.Rank_3 || !BitBoard.GetSquare(Occupies[(byte)ColorE.White] & Pieces[(byte)PieceE.Pawn], (SquareE)(EnPassant + 8))))
                {
                    return(false);
                }
            }
            #endregion

            #region Move

            if ( //0 < HalfMove ||
                HalfMoveClock > 100)
            {
                return(false);
            }
            //if( MoveCount < 0 ) return false;
            #endregion

            #region KingCheck And Move

            /*
             * // check if the side which is not to move is in check
             * if(
             *  (board.Status.WhiteTurn && board.IsBlackKingInCheck)
             || (board.Status.BlackTurn && board.IsWhiteKingInCheck)
             ||)
             ||{
             || throw new ArgumentException(Resources.NoSideNotToMoveCheckMsg, "Board");
             ||}
             */

            #endregion

            return(true);
        }
Ejemplo n.º 22
0
 public static void Init()
 {
     Zobrist.Init();
     Bitboard.Init();
 }
Ejemplo n.º 23
0
        // TODO::
        //internal Bitboard AttacksTo( Bitboard occupied, SquareE sqr, ColorE side )
        //{
        //    //Bitboard knights, kings, bishopsQueens, rooksQueens;
        //    //knights = pieceBB[ nWhiteKnight ] | pieceBB[ nBlackKnight ];
        //    //kings = pieceBB[ nWhiteKing ] | pieceBB[ nBlackKing ];
        //    //rooksQueens =
        //    //bishopsQueens = pieceBB[ nWhiteQueen ] | pieceBB[ nBlackQueen ];
        //    //rooksQueens |= pieceBB[ nWhiteRook ] | pieceBB[ nBlackRook ];
        //    //bishopsQueens |= pieceBB[ nWhiteBishop ] | pieceBB[ nBlackBishop ];

        //    //return (arrPawnAttacks[ nWhite ][ sqr ] & pieceBB[ nBlackPawn ])
        //    //     | (arrPawnAttacks[ nBlack ][ sqr ] & pieceBB[ nWhitePawn ])
        //    //     | (arrKnightAttacks[ sqr ] & knights)
        //    //     | (arrKingAttacks[ sqr ] & kings)
        //    //     | (bishopAttacks(occupied, sqr) & bishopsQueens)
        //    //     | (rookAttacks(occupied, sqr) & rooksQueens)
        //    //     ;

        //    ColorE oppside = ColorE.NoColor;
        //    if( side == ColorE.White )
        //    {
        //        oppside = ColorE.Black;
        //    }
        //    else if( side == ColorE.Black )
        //    {
        //        oppside = ColorE.White;
        //    }

        //    Bitboard sideOccupied = Occupies[ (byte) side ];

        //    Bitboard rooksQueens = Pieces[ (byte) PieceE.Rook ] | Pieces[ (byte) PieceE.Queen ];
        //    Bitboard bishopsQueens = Pieces[ (byte) PieceE.Bishop ] | Pieces[ (byte) PieceE.Queen ];

        //    return (MoveAttack._PawnAttacks[ (byte) sqr, (byte) side ] & (Pieces[ (byte) PieceE.Pawn ] & Occupies[ (byte) oppside ]))
        //        | (MoveAttack._PawnAttacks[ (byte) sqr, (byte) oppside ] & (Pieces[ (byte) PieceE.Pawn ] & Occupies[ (byte) side ]))
        //        | (MoveAttack._KnightMoves[ (byte) sqr ] & Pieces[ (byte) PieceE.Knight ])
        //        | (MoveAttack._KingMoves[ (byte) sqr ] & Pieces[ (byte) PieceE.King ])
        //        | (MoveAttack._RookMoves[ (byte) sqr ] & rooksQueens)
        //        | (MoveAttack._BishopMoves[ (byte) sqr ] & bishopsQueens);
        //}


        public override string ToString()
        {
            StringBuilder sboard = new StringBuilder();

            sboard.AppendLine(" +-+-+-+-+-+-+-+-+");


            //SquareE begSqr = SquareE.A8;
            //SquareE endSqr = SquareE.H1;
            //for( SquareE sqr = begSqr; ; Square.BackwardInc(ref sqr) )
            //{
            //    if( (byte) sqr % File.Files == 0 )
            //    {
            //        if( sqr != begSqr ) sboard.AppendLine();
            //        sboard.Append(Rank.mapRank[ (byte) sqr / File.Files ]);
            //    }
            //    bool isPiece = false;
            //    sboard.Append(" ");
            //    for( ColorE color = ColorE.White; color <= ColorE.Black; ++color )
            //    {
            //        Bitboard occupy = Occupies[ (byte) color ];
            //        for( PieceE type = PieceE.Pawn; type <= PieceE.King; ++type )
            //        {
            //            Bitboard piece = Pieces[ (byte) type ];
            //            if( BitBoard.GetSquare(occupy & piece, sqr) )
            //            {
            //                //if( isPiece ) sboard.Append('x'); // '*'
            //                isPiece = true;
            //                sboard.Append(Piece.mapPiece[ (byte) color, (byte) type ]);
            //                break;
            //            }
            //        }
            //    }
            //    if( !isPiece )
            //        sboard.Append(".");
            //    if( sqr == endSqr )
            //        break;
            //}


            for (RankE rank = RankE.Rank_8; ; --rank)
            {
                sboard.Append(Rank.mapRank[(byte)rank]);
                for (FileE file = FileE.File_A; file <= FileE.File_H; ++file)
                {
                    bool isPiece = false;
                    sboard.Append(" ");
                    for (ColorE color = ColorE.White; color <= ColorE.Black; ++color)
                    {
                        Bitboard occupy = Occupies[(byte)color];
                        SquareE  sqr    = Square._Square(file, rank);
                        if (BitBoard.GetSquare(occupy, sqr))
                        {
                            for (PieceE type = PieceE.Pawn; type <= PieceE.King; ++type)
                            {
                                Bitboard piece = Pieces[(byte)type];
                                if (BitBoard.GetSquare(piece, sqr))  // occupy & piece
                                {
                                    //if( isPiece ) sboard.Append('x'); // '*'
                                    isPiece = true;
                                    sboard.Append(Piece.mapPiece[(byte)color, (byte)type]);
                                    break;
                                }
                            }
                        }
                    }
                    if (!isPiece)
                    {
                        sboard.Append(".");
                    }
                }
                if (rank == RankE.Rank_1)
                {
                    break;
                }
                sboard.AppendLine();
            }


            sboard.AppendLine().Append(" +-+-+-+-+-+-+-+-+").AppendLine();
            sboard.Append(" ");
            foreach (char file in File.mapFile)
            {
                sboard.Append(" " + file);
            }
            return(sboard.ToString());
        }
Ejemplo n.º 24
0
 public Bitboard Get(Square from, Bitboard friends, Bitboard enemies)
 {
     return Cache[from].Except(friends);
 }
Ejemplo n.º 25
0
        private static int CalculatePawnScores(ChessBoard cb)
        {
            var score = 0;

            // penalty for doubled pawns
            for (var i = 0; i < 8; i++)
            {
                if (BitOperations.PopCount((ulong)(cb.Pieces[White][Pawn] & Bitboard.Files[i])) > 1)
                {
                    score -= EvalConstants.PawnScores[EvalConstants.IxPawnDouble];
                }

                if (BitOperations.PopCount((ulong)(cb.Pieces[Black][Pawn] & Bitboard.Files[i])) > 1)
                {
                    score += EvalConstants.PawnScores[EvalConstants.IxPawnDouble];
                }
            }

            // bonus for connected pawns
            var pawns = Bitboard.GetWhitePawnAttacks(cb.Pieces[White][Pawn]) & cb.Pieces[White][Pawn];

            while (pawns != 0)
            {
                score += EvalConstants.PawnConnected[BitOperations.TrailingZeroCount(pawns) / 8];
                pawns &= pawns - 1;
            }

            pawns = Bitboard.GetBlackPawnAttacks(cb.Pieces[Black][Pawn]) & cb.Pieces[Black][Pawn];
            while (pawns != 0)
            {
                score -= EvalConstants.PawnConnected[7 - BitOperations.TrailingZeroCount(pawns) / 8];
                pawns &= pawns - 1;
            }

            // bonus for neighbour pawns
            pawns = Bitboard.GetPawnNeighbours(cb.Pieces[White][Pawn]) & cb.Pieces[White][Pawn];
            while (pawns != 0)
            {
                score += EvalConstants.PawnNeighbour[BitOperations.TrailingZeroCount(pawns) / 8];
                pawns &= pawns - 1;
            }

            pawns = Bitboard.GetPawnNeighbours(cb.Pieces[Black][Pawn]) & cb.Pieces[Black][Pawn];
            while (pawns != 0)
            {
                score -= EvalConstants.PawnNeighbour[7 - BitOperations.TrailingZeroCount(pawns) / 8];
                pawns &= pawns - 1;
            }

            // set outposts
            cb.PassedPawnsAndOutposts = 0;
            pawns = Bitboard.GetWhitePawnAttacks(cb.Pieces[White][Pawn]) & ~cb.Pieces[White][Pawn] &
                    ~cb.Pieces[Black][Pawn];
            while (pawns != 0)
            {
                if ((Bitboard.GetWhiteAdjacentMask(BitOperations.TrailingZeroCount(pawns)) & cb.Pieces[Black][Pawn]) ==
                    0)
                {
                    cb.PassedPawnsAndOutposts |= pawns & -pawns;
                }

                pawns &= pawns - 1;
            }

            pawns = Bitboard.GetBlackPawnAttacks(cb.Pieces[Black][Pawn]) & ~cb.Pieces[White][Pawn] &
                    ~cb.Pieces[Black][Pawn];
            while (pawns != 0)
            {
                if ((Bitboard.GetBlackAdjacentMask(BitOperations.TrailingZeroCount(pawns)) & cb.Pieces[White][Pawn]) ==
                    0)
                {
                    cb.PassedPawnsAndOutposts |= pawns & -pawns;
                }

                pawns &= pawns - 1;
            }

            int index;

            // white
            pawns = cb.Pieces[White][Pawn];
            while (pawns != 0)
            {
                index = BitOperations.TrailingZeroCount(pawns);

                // isolated pawns
                if ((Bitboard.FilesAdjacent[index & 7] & cb.Pieces[White][Pawn]) == 0)
                {
                    score -= EvalConstants.PawnScores[EvalConstants.IxPawnIsolated];
                }

                // backward pawns
                else if ((Bitboard.GetBlackAdjacentMask(index + 8) & cb.Pieces[White][Pawn]) == 0)
                {
                    if ((StaticMoves.PawnAttacks[White][index + 8] & cb.Pieces[Black][Pawn]) != 0)
                    {
                        if ((Bitboard.Files[index & 7] & cb.Pieces[Black][Pawn]) == 0)
                        {
                            score -= EvalConstants.PawnScores[EvalConstants.IxPawnBackward];
                        }
                    }
                }

                // pawn defending 2 pawns
                if (BitOperations.PopCount((ulong)(StaticMoves.PawnAttacks[White][index] & cb.Pieces[White][Pawn])) ==
                    2)
                {
                    score -= EvalConstants.PawnScores[EvalConstants.IxPawnInverse];
                }

                // set passed pawns
                if ((Bitboard.GetWhitePassedPawnMask(index) & cb.Pieces[Black][Pawn]) == 0)
                {
                    cb.PassedPawnsAndOutposts |= pawns & -pawns;
                }

                // candidate passed pawns (no pawns in front, more friendly pawns behind and adjacent than enemy pawns)
                else if (63 - BitOperations.LeadingZeroCount(
                             (ulong)((cb.Pieces[White][Pawn] | cb.Pieces[Black][Pawn]) &
                                     Bitboard.Files[index & 7])) == index)
                {
                    if (BitOperations.PopCount((ulong)(cb.Pieces[White][Pawn] &
                                                       Bitboard.GetBlackPassedPawnMask(index + 8))) >=
                        BitOperations.PopCount(
                            (ulong)(cb.Pieces[Black][Pawn] & Bitboard.GetWhitePassedPawnMask(index))))
                    {
                        score += EvalConstants.PassedCandidate[index / 8];
                    }
                }

                pawns &= pawns - 1;
            }

            // black
            pawns = cb.Pieces[Black][Pawn];
            while (pawns != 0)
            {
                index = BitOperations.TrailingZeroCount(pawns);

                // isolated pawns
                if ((Bitboard.FilesAdjacent[index & 7] & cb.Pieces[Black][Pawn]) == 0)
                {
                    score += EvalConstants.PawnScores[EvalConstants.IxPawnIsolated];
                }

                // backward pawns
                else if ((Bitboard.GetWhiteAdjacentMask(index - 8) & cb.Pieces[Black][Pawn]) == 0)
                {
                    if ((StaticMoves.PawnAttacks[Black][index - 8] & cb.Pieces[White][Pawn]) != 0)
                    {
                        if ((Bitboard.Files[index & 7] & cb.Pieces[White][Pawn]) == 0)
                        {
                            score += EvalConstants.PawnScores[EvalConstants.IxPawnBackward];
                        }
                    }
                }

                // pawn defending 2 pawns
                if (BitOperations.PopCount((ulong)(StaticMoves.PawnAttacks[Black][index] & cb.Pieces[Black][Pawn])) ==
                    2)
                {
                    score += EvalConstants.PawnScores[EvalConstants.IxPawnInverse];
                }

                // set passed pawns
                if ((Bitboard.GetBlackPassedPawnMask(index) & cb.Pieces[White][Pawn]) == 0)
                {
                    cb.PassedPawnsAndOutposts |= pawns & -pawns;
                }

                // candidate passers
                else if (BitOperations.TrailingZeroCount((cb.Pieces[White][Pawn] | cb.Pieces[Black][Pawn]) &
                                                         Bitboard.Files[index & 7]) == index)
                {
                    if (BitOperations.PopCount((ulong)(cb.Pieces[Black][Pawn] &
                                                       Bitboard.GetWhitePassedPawnMask(index - 8))) >=
                        BitOperations.PopCount(
                            (ulong)(cb.Pieces[White][Pawn] & Bitboard.GetBlackPassedPawnMask(index))))
                    {
                        score -= EvalConstants.PassedCandidate[7 - index / 8];
                    }
                }

                pawns &= pawns - 1;
            }

            return(score);
        }
Ejemplo n.º 26
0
        static PureMemory()
        {
            int taiLn = Conv_Taikyokusya.itiran.Length;

            #region 被王手判定
            // ビットボード
            hot_bb_checkerAr     = new Bitboard[taiLn];
            hot_bb_raion8KinboAr = new Bitboard[taiLn];
            hot_bb_nigemitiWoFusaideiruAiteNoKomaAr = new Bitboard[taiLn];
            hot_bb_nigereruAr = new Bitboard[taiLn];
            hot_bb_nigeroAr   = new Bitboard[taiLn];
            for (int iTai = 0; iTai < taiLn; iTai++)
            {
                hot_bb_checkerAr[iTai]     = new Bitboard();
                hot_bb_raion8KinboAr[iTai] = new Bitboard();
                hot_bb_nigemitiWoFusaideiruAiteNoKomaAr[iTai] = new Bitboard();
                hot_bb_nigereruAr[iTai] = new Bitboard();
                hot_bb_nigeroAr[iTai]   = new Bitboard();
            }

            hot_ms_raionAr             = new Masu[taiLn];
            hot_outeKomasCountAr       = new int[taiLn];
            hot_isNigerarenaiCheckerAr = new bool[taiLn];
            hot_raionCatchChosaAr      = new bool[taiLn];
            #endregion

            #region 指し手生成(シングルスレッドを想定)
            ssss_moveList             = new MoveList[PureMemory.MaxMoveDepth];
            ssss_moveListBad          = new MoveList[PureMemory.MaxMoveDepth];
            ssss_bbVar_idosaki_narazu = new Bitboard();
            ssss_bbVar_idosaki_nari   = new Bitboard();
            ssssTmp_bbVar_ibasho      = new Bitboard();

            ssss_bbBase_idosaki01_checker            = new Bitboard();
            ssss_bbBase_idosaki02_raionCatch         = new Bitboard();
            ssss_bbBase_idosaki03_nigeroTe           = new Bitboard();
            ssss_bbBase_idosaki04_try                = new Bitboard();
            ssss_bbBase_idosaki05_komaWoToruTe       = new Bitboard();
            ssss_bbBase_idosaki06_himodukiOteZasi    = new Bitboard();
            ssss_bbBase_idosaki07_suteOteZasi        = new Bitboard();
            ssss_bbBase_idosaki08_suteOteDa          = new Bitboard();
            ssss_bbBase_idosaki09_himodukiOteDa      = new Bitboard();
            ssss_bbBase_idosaki10_himodukiKanmanDa   = new Bitboard();
            ssss_bbBase_idosaki11_himodukiKanmanZasi = new Bitboard();
            ssss_bbBase_idosaki12_bottiKanmanZasi    = new Bitboard();
            ssss_bbBase_idosaki13_bottiKanmanDa      = new Bitboard();
            ssss_bbBase_idosaki14_suteKanmanZasi     = new Bitboard();
            ssss_bbBase_idosaki15_suteKanmanDa       = new Bitboard();

            ssss_movePickerWoNuketaBasho1 = "";

            for (int iFukasa = 0; iFukasa < PureMemory.MaxMoveDepth; iFukasa++)
            {
                ssss_moveList[iFukasa]    = new MoveList();
                ssss_moveListBad[iFukasa] = new MoveList();
            }
            #endregion

            #region ムーブス
            mvs_ssAr = new Move[KIFU_SIZE];
            #endregion
            #region 棋譜(コンピューター・プレイヤー同時に1つまで)
            kifu_syokiKyokumenFen = "";
            kifu_toraretaKsAr     = new Komasyurui[KIFU_SIZE];
            kifu_moveArray        = new Move[KIFU_SIZE];
            kifu_moveTypeArray    = new MoveType[KIFU_SIZE];
            // 手番☆(^~^)
            kifu_tebanAr_    = new Taikyokusya[KIFU_SIZE];
            kifu_aitebanAr_  = new Taikyokusya[KIFU_SIZE];
            kifu_nTebanAr_   = new int[KIFU_SIZE];
            kifu_nAitebanAr_ = new int[KIFU_SIZE];

            // 初期局面手番を未設定にしておいて、ResetTebanArray( ) すれば、手番配列の初期値が入るぜ☆(^~^)
            kifu_syokikyokumenTeban = Taikyokusya.Yososu;
            ResetTebanArray(Taikyokusya.T1);

            // 配列等の初期化が終わったあとで、手目をリセット
            ClearTeme(
                //kifu_syokikyokumenTeban
                );
            #endregion

            #region 現局面(棋譜カーソルが指している局面)(コンピューター・プレイヤー同時に1つまで)
            gky_kekka   = TaikyokuKekka.Karappo;
            gky_ky      = new Kyokumen();
            gky_hyokati = new Hyokati();
            Util_Control.UpdateRule(
#if DEBUG
                "static PureMemory"
#endif
                );
            #endregion

            #region 探索(tnsk)
            tnsk_kohoMove = Move.Toryo;
            #endregion
        }
Ejemplo n.º 27
0
        public static int CalculateThreats(ChessBoard cb)
        {
            var score             = 0;
            var whites            = cb.Pieces[White][All];
            var whitePawns        = cb.Pieces[White][Pawn];
            var blacks            = cb.Pieces[Black][All];
            var blackPawns        = cb.Pieces[Black][Pawn];
            var whiteAttacks      = cb.Attacks[White][All];
            var whitePawnAttacks  = cb.Attacks[White][Pawn];
            var whiteMinorAttacks = cb.Attacks[White][Knight] | cb.Attacks[White][Bishop];
            var blackAttacks      = cb.Attacks[Black][All];
            var blackPawnAttacks  = cb.Attacks[Black][Pawn];
            var blackMinorAttacks = cb.Attacks[Black][Knight] | cb.Attacks[Black][Bishop];

            // double attacked pieces
            var piece = cb.DoubleAttacks[White] & blacks;

            while (piece != 0)
            {
                score += EvalConstants.DoubleAttacked[cb.PieceIndexes[BitOperations.TrailingZeroCount(piece)]];
                piece &= piece - 1;
            }

            piece = cb.DoubleAttacks[Black] & whites;
            while (piece != 0)
            {
                score -= EvalConstants.DoubleAttacked[cb.PieceIndexes[BitOperations.TrailingZeroCount(piece)]];
                piece &= piece - 1;
            }

            if (MaterialUtil.HasPawns(cb.MaterialKey))
            {
                // unused outposts
                score += BitOperations.PopCount((ulong)(cb.PassedPawnsAndOutposts & cb.EmptySpaces &
                                                        whiteMinorAttacks & whitePawnAttacks))
                         * EvalConstants.Threats[EvalConstants.IxUnusedOutpost];
                score -= BitOperations.PopCount((ulong)(cb.PassedPawnsAndOutposts & cb.EmptySpaces &
                                                        blackMinorAttacks & blackPawnAttacks))
                         * EvalConstants.Threats[EvalConstants.IxUnusedOutpost];

                // pawn push threat
                piece  = (whitePawns << 8) & cb.EmptySpaces & ~blackAttacks;
                score += BitOperations.PopCount((ulong)(Bitboard.GetWhitePawnAttacks(piece) & blacks)) *
                         EvalConstants.Threats[EvalConstants.IxPawnPushThreat];
                piece  = Util.RightTripleShift(blackPawns, 8) & cb.EmptySpaces & ~whiteAttacks;
                score -= BitOperations.PopCount((ulong)(Bitboard.GetBlackPawnAttacks(piece) & whites)) *
                         EvalConstants.Threats[EvalConstants.IxPawnPushThreat];

                // piece attacked by pawn
                score += BitOperations.PopCount((ulong)(whitePawnAttacks & blacks & ~blackPawns)) *
                         EvalConstants.Threats[EvalConstants.IxPawnAttacks];
                score -= BitOperations.PopCount((ulong)(blackPawnAttacks & whites & ~whitePawns)) *
                         EvalConstants.Threats[EvalConstants.IxPawnAttacks];

                // multiple pawn attacks possible
                if (BitOperations.PopCount((ulong)(whitePawnAttacks & blacks)) > 1)
                {
                    score += EvalConstants.Threats[EvalConstants.IxMultiplePawnAttacks];
                }

                if (BitOperations.PopCount((ulong)(blackPawnAttacks & whites)) > 1)
                {
                    score -= EvalConstants.Threats[EvalConstants.IxMultiplePawnAttacks];
                }

                // pawn attacked
                score += BitOperations.PopCount((ulong)(whiteAttacks & blackPawns)) *
                         EvalConstants.Threats[EvalConstants.IxPawnAttacked];
                score -= BitOperations.PopCount((ulong)(blackAttacks & whitePawns)) *
                         EvalConstants.Threats[EvalConstants.IxPawnAttacked];
            }

            // minors attacked and not defended by a pawn
            score += BitOperations.PopCount((ulong)(whiteAttacks &
                                                    (cb.Pieces[Black][Knight] |
                                                     (cb.Pieces[Black][Bishop] & ~blackAttacks))))
                     * EvalConstants.Threats[EvalConstants.IxMajorAttacked];
            score -= BitOperations.PopCount((ulong)(blackAttacks &
                                                    (cb.Pieces[White][Knight] |
                                                     (cb.Pieces[White][Bishop] & ~whiteAttacks))))
                     * EvalConstants.Threats[EvalConstants.IxMajorAttacked];

            if (cb.Pieces[Black][Queen] != 0)
            {
                // queen attacked by rook
                score += BitOperations.PopCount((ulong)(cb.Attacks[White][Rook] & cb.Pieces[Black][Queen])) *
                         EvalConstants.Threats[EvalConstants.IxQueenAttacked];
                // queen attacked by minors
                score += BitOperations.PopCount((ulong)(whiteMinorAttacks & cb.Pieces[Black][Queen])) *
                         EvalConstants.Threats[EvalConstants.IxQueenAttackedMinor];
            }

            if (cb.Pieces[White][Queen] != 0)
            {
                // queen attacked by rook
                score -= BitOperations.PopCount((ulong)(cb.Attacks[Black][Rook] & cb.Pieces[White][Queen])) *
                         EvalConstants.Threats[EvalConstants.IxQueenAttacked];
                // queen attacked by minors
                score -= BitOperations.PopCount((ulong)(blackMinorAttacks & cb.Pieces[White][Queen])) *
                         EvalConstants.Threats[EvalConstants.IxQueenAttackedMinor];
            }

            // rook attacked by minors
            score += BitOperations.PopCount((ulong)(whiteMinorAttacks & cb.Pieces[Black][Rook])) *
                     EvalConstants.Threats[EvalConstants.IxRookAttacked];
            score -= BitOperations.PopCount((ulong)(blackMinorAttacks & cb.Pieces[White][Rook])) *
                     EvalConstants.Threats[EvalConstants.IxRookAttacked];

            return(score);
        }
Ejemplo n.º 28
0
 /// <summary>
 /// Does move (specified by the derived class).
 /// </summary>
 /// <param name="bitboard">The bitboard.</param>
 public void Do(Bitboard bitboard)
 {
     CalculateMove(bitboard);
     CalculateCastling(bitboard);
 }
Ejemplo n.º 29
0
        public static int CalculateOthers(ChessBoard cb)
        {
            var  score = 0;
            long piece;

            var whites           = cb.Pieces[White][All];
            var whitePawns       = cb.Pieces[White][Pawn];
            var blacks           = cb.Pieces[Black][All];
            var blackPawns       = cb.Pieces[Black][Pawn];
            var whitePawnAttacks = cb.Attacks[White][Pawn];
            var blackPawnAttacks = cb.Attacks[Black][Pawn];

            // side to move
            score += ColorFactor[cb.ColorToMove] * EvalConstants.SideToMoveBonus;

            // WHITE ROOK
            if (cb.Pieces[White][Rook] != 0)
            {
                piece = cb.Pieces[White][Rook];

                // rook battery (same file)
                if (BitOperations.PopCount((ulong)piece) == 2)
                {
                    if ((BitOperations.TrailingZeroCount(piece) & 7) ==
                        ((63 - BitOperations.LeadingZeroCount((ulong)piece)) & 7))
                    {
                        score += EvalConstants.OtherScores[EvalConstants.IxRookBattery];
                    }
                }

                // rook on 7th, king on 8th
                if (cb.KingIndex[Black] >= 56 && (piece & Bitboard.Rank7) != 0)
                {
                    score += BitOperations.PopCount((ulong)(piece & Bitboard.Rank7)) *
                             EvalConstants.OtherScores[EvalConstants.IxRook7ThRank];
                }

                // prison
                if ((piece & Bitboard.Rank1) != 0)
                {
                    var trapped = piece & EvalConstants.RookPrison[cb.KingIndex[White]];
                    if (trapped != 0)
                    {
                        if ((((trapped << 8) | (trapped << 16)) & whitePawns) != 0)
                        {
                            score += EvalConstants.OtherScores[EvalConstants.IxRookTrapped];
                        }
                    }
                }

                // rook on open-file (no pawns) and semi-open-file (no friendly pawns)
                while (piece != 0)
                {
                    if ((whitePawns & Bitboard.GetFile(piece)) == 0)
                    {
                        if ((blackPawns & Bitboard.GetFile(piece)) == 0)
                        {
                            score += EvalConstants.OtherScores[EvalConstants.IxRookFileOpen];
                        }
                        else if ((blackPawns & blackPawnAttacks & Bitboard.GetFile(piece)) == 0)
                        {
                            score += EvalConstants.OtherScores[EvalConstants.IxRookFileSemiOpenIsolated];
                        }
                        else
                        {
                            score += EvalConstants.OtherScores[EvalConstants.IxRookFileSemiOpen];
                        }
                    }

                    piece &= piece - 1;
                }
            }

            // BLACK ROOK
            if (cb.Pieces[Black][Rook] != 0)
            {
                piece = cb.Pieces[Black][Rook];

                // rook battery (same file)
                if (BitOperations.PopCount((ulong)piece) == 2)
                {
                    if ((BitOperations.TrailingZeroCount(piece) & 7) ==
                        ((63 - BitOperations.LeadingZeroCount((ulong)piece)) & 7))
                    {
                        score -= EvalConstants.OtherScores[EvalConstants.IxRookBattery];
                    }
                }

                // rook on 2nd, king on 1st
                if (cb.KingIndex[White] <= 7 && (piece & Bitboard.Rank2) != 0)
                {
                    score -= BitOperations.PopCount((ulong)(piece & Bitboard.Rank2)) *
                             EvalConstants.OtherScores[EvalConstants.IxRook7ThRank];
                }

                // prison
                if ((piece & Bitboard.Rank8) != 0)
                {
                    var trapped = piece & EvalConstants.RookPrison[cb.KingIndex[Black]];
                    if (trapped != 0)
                    {
                        if (((Util.RightTripleShift(trapped, 8) | Util.RightTripleShift(trapped, 16)) & blackPawns) !=
                            0)
                        {
                            score -= EvalConstants.OtherScores[EvalConstants.IxRookTrapped];
                        }
                    }
                }

                // rook on open-file (no pawns) and semi-open-file (no friendly pawns)
                while (piece != 0)
                {
                    // TODO JITWatch unpredictable branch
                    if ((blackPawns & Bitboard.GetFile(piece)) == 0)
                    {
                        if ((whitePawns & Bitboard.GetFile(piece)) == 0)
                        {
                            score -= EvalConstants.OtherScores[EvalConstants.IxRookFileOpen];
                        }
                        else if ((whitePawns & whitePawnAttacks & Bitboard.GetFile(piece)) == 0)
                        {
                            score -= EvalConstants.OtherScores[EvalConstants.IxRookFileSemiOpenIsolated];
                        }
                        else
                        {
                            score -= EvalConstants.OtherScores[EvalConstants.IxRookFileSemiOpen];
                        }
                    }

                    piece &= piece - 1;
                }
            }

            // WHITE BISHOP
            if (cb.Pieces[White][Bishop] != 0)
            {
                // bishop outpost: protected by a pawn, cannot be attacked by enemy pawns
                piece = cb.Pieces[White][Bishop] & cb.PassedPawnsAndOutposts & whitePawnAttacks;
                if (piece != 0)
                {
                    score += BitOperations.PopCount((ulong)piece) * EvalConstants.OtherScores[EvalConstants.IxOutpost];
                }

                piece = cb.Pieces[White][Bishop];
                if ((piece & Bitboard.WhiteSquares) != 0)
                {
                    // pawns on same color as bishop
                    score += EvalConstants.BishopPawn[
                        BitOperations.PopCount((ulong)(whitePawns & Bitboard.WhiteSquares))];

                    // attacking center squares
                    if (BitOperations.PopCount((ulong)(cb.Attacks[White][Bishop] & Bitboard.E4D5)) == 2)
                    {
                        score += EvalConstants.OtherScores[EvalConstants.IxBishopLong];
                    }
                }

                if ((piece & Bitboard.BlackSquares) != 0)
                {
                    // pawns on same color as bishop
                    score += EvalConstants.BishopPawn[
                        BitOperations.PopCount((ulong)(whitePawns & Bitboard.BlackSquares))];

                    // attacking center squares
                    if (BitOperations.PopCount((ulong)(cb.Attacks[White][Bishop] & Bitboard.D4E5)) == 2)
                    {
                        score += EvalConstants.OtherScores[EvalConstants.IxBishopLong];
                    }
                }

                // prison
                piece &= Bitboard.Rank2;
                while (piece != 0)
                {
                    if (BitOperations.PopCount(
                            (ulong)(EvalConstants.BishopPrison[BitOperations.TrailingZeroCount(piece)] & blackPawns)) == 2)
                    {
                        score += EvalConstants.OtherScores[EvalConstants.IxBishopPrison];
                    }

                    piece &= piece - 1;
                }
            }

            // BLACK BISHOP
            if (cb.Pieces[Black][Bishop] != 0)
            {
                // bishop outpost: protected by a pawn, cannot be attacked by enemy pawns
                piece = cb.Pieces[Black][Bishop] & cb.PassedPawnsAndOutposts & blackPawnAttacks;
                if (piece != 0)
                {
                    score -= BitOperations.PopCount((ulong)piece) * EvalConstants.OtherScores[EvalConstants.IxOutpost];
                }

                piece = cb.Pieces[Black][Bishop];
                if ((piece & Bitboard.WhiteSquares) != 0)
                {
                    // penalty for many pawns on same color as bishop
                    score -= EvalConstants.BishopPawn[
                        BitOperations.PopCount((ulong)(blackPawns & Bitboard.WhiteSquares))];

                    // bonus for attacking center squares
                    if (BitOperations.PopCount((ulong)(cb.Attacks[Black][Bishop] & Bitboard.E4D5)) == 2)
                    {
                        score -= EvalConstants.OtherScores[EvalConstants.IxBishopLong];
                    }
                }

                if ((piece & Bitboard.BlackSquares) != 0)
                {
                    // penalty for many pawns on same color as bishop
                    score -= EvalConstants.BishopPawn[
                        BitOperations.PopCount((ulong)(blackPawns & Bitboard.BlackSquares))];

                    // bonus for attacking center squares
                    if (BitOperations.PopCount((ulong)(cb.Attacks[Black][Bishop] & Bitboard.D4E5)) == 2)
                    {
                        score -= EvalConstants.OtherScores[EvalConstants.IxBishopLong];
                    }
                }

                // prison
                piece &= Bitboard.Rank7;
                while (piece != 0)
                {
                    if (BitOperations.PopCount(
                            (ulong)(EvalConstants.BishopPrison[BitOperations.TrailingZeroCount(piece)] & whitePawns)) == 2)
                    {
                        score -= EvalConstants.OtherScores[EvalConstants.IxBishopPrison];
                    }

                    piece &= piece - 1;
                }
            }

            // pieces supporting our pawns
            piece = (whitePawns << 8) & whites;
            while (piece != 0)
            {
                score += EvalConstants.PawnBlockage[Util.RightTripleShift(BitOperations.TrailingZeroCount(piece), 3)];
                piece &= piece - 1;
            }

            piece = Util.RightTripleShift(blackPawns, 8) & blacks;
            while (piece != 0)
            {
                score -= EvalConstants.PawnBlockage[7 - BitOperations.TrailingZeroCount(piece) / 8];
                piece &= piece - 1;
            }

            // knight outpost: protected by a pawn, cannot be attacked by enemy pawns
            piece = cb.Pieces[White][Knight] & cb.PassedPawnsAndOutposts & whitePawnAttacks;
            if (piece != 0)
            {
                score += BitOperations.PopCount((ulong)piece) * EvalConstants.OtherScores[EvalConstants.IxOutpost];
            }

            piece = cb.Pieces[Black][Knight] & cb.PassedPawnsAndOutposts & blackPawnAttacks;
            if (piece != 0)
            {
                score -= BitOperations.PopCount((ulong)piece) * EvalConstants.OtherScores[EvalConstants.IxOutpost];
            }

            // pinned-pieces
            if (cb.PinnedPieces != 0)
            {
                piece = cb.PinnedPieces & whites;
                while (piece != 0)
                {
                    score += EvalConstants.Pinned[cb.PieceIndexes[BitOperations.TrailingZeroCount(piece)]];
                    piece &= piece - 1;
                }

                piece = cb.PinnedPieces & blacks;
                while (piece != 0)
                {
                    score -= EvalConstants.Pinned[cb.PieceIndexes[BitOperations.TrailingZeroCount(piece)]];
                    piece &= piece - 1;
                }
            }

            // discovered-pieces
            if (cb.DiscoveredPieces != 0)
            {
                piece = cb.DiscoveredPieces & whites;
                while (piece != 0)
                {
                    score += EvalConstants.Discovered[cb.PieceIndexes[BitOperations.TrailingZeroCount(piece)]];
                    piece &= piece - 1;
                }

                piece = cb.DiscoveredPieces & blacks;
                while (piece != 0)
                {
                    score -= EvalConstants.Discovered[cb.PieceIndexes[BitOperations.TrailingZeroCount(piece)]];
                    piece &= piece - 1;
                }
            }

            if (cb.CastlingRights == 0)
            {
                return(score);
            }
            score += BitOperations.PopCount((ulong)(cb.CastlingRights & 12)) *
                     EvalConstants.OtherScores[EvalConstants.IxCastling];
            score -= BitOperations.PopCount((ulong)(cb.CastlingRights & 3)) *
                     EvalConstants.OtherScores[EvalConstants.IxCastling];

            return(score);
        }
Ejemplo n.º 30
0
 /// <summary>
 /// Calculates a mobility evaluation result for the specified player by adding number of possible
 /// moves for every piece with the specified color.
 /// </summary>
 /// <param name="bitboard">The bitboard.</param>
 /// <param name="color">The player color.</param>
 /// <returns>The mobility evaluation result for the specified player.</returns>
 private int GetMobilityValue(Bitboard bitboard, Color color)
 {
     return(BitOperations.Count(bitboard.AttacksSummary[(int)color]));
 }
Ejemplo n.º 31
0
 private BoardBuilder(Bitboard board, bool inverted)
     : this()
 {
     resultField = board;
     invertedField = inverted;
 }
Ejemplo n.º 32
0
 public Bitboard GetMoveBoard(Square from, Bitboard friends)
 {
     return GetMoveBoard(from, friends, 0);
 }
Ejemplo n.º 33
0
 public WhitePawns(Bitboard locations)
     : this()
 {
     this.Locations = locations;
 }
Ejemplo n.º 34
0
 public IEnumerable<Move> GetMovesOneSquareForward(Bitboard notblockers, Bitboard filterFrom, Bitboard filterTo)
 {
     Bitboard b = (Locations.Intersect(filterFrom) >> 8 & notblockers);
     return GetMoves(b.Intersect(filterTo), 8);
 }
Ejemplo n.º 35
0
 public IEnumerable<Move> GetMovesTwoSquaresForward(Bitboard notblockers)
 {
     return GetMovesTwoSquaresForward(notblockers, Bitboard.Full, Bitboard.Full);
 }
Ejemplo n.º 36
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("");
        }
Ejemplo n.º 37
0
        private IEnumerable<Move> GetMoves(Bitboard b, int offsetFrom)
        {
            foreach (var to in b.Squares)
            {
                Square from = to - offsetFrom;
                b = b.Except(to);
                if (to >= 56)
                {
                    yield return new Move(from, to, MoveTypes.PawnToQueenPromotion);
                    yield return new Move(from, to, MoveTypes.PawnToRookPromotion);
                    yield return new Move(from, to, MoveTypes.PawnToBishopPromotion);
                    yield return new Move(from, to, MoveTypes.PawnToKnightPromotion);

                }
                else
                {
                    yield return new Move(from, to);
                }
            }
        }
Ejemplo n.º 38
0
    protected override Bitboard AdditionalMoveProcessing(Bitboard movesForCurrentPosition)
    {
        // For pawns, extra moves would constitute:
        // 1. Normal attack
        // 2. En passant

        // Normal attack
        // Check the row ahead for opponent locations
        int  rowToCheck;
        Side sideToCheck;

        if (this.side == Side.Black)
        {
            rowToCheck  = this.GetCurrentPosition().GetRow() - 1;
            sideToCheck = Side.White;
        }
        else
        {
            rowToCheck  = this.GetCurrentPosition().GetRow() + 1;
            sideToCheck = Side.Black;
        }

        Bitboard friendlyLocations = this.chessBoard.GetPieceLocations(this.side);
        Bitboard opponentLocations = this.chessBoard.GetPieceLocations(sideToCheck);

        // First, remove any moves that go through friendly or opponent
        movesForCurrentPosition = movesForCurrentPosition.ComputeRayIntersections(friendlyLocations, this.GetCurrentPosition(), false);
        movesForCurrentPosition = movesForCurrentPosition.ComputeRayIntersections(opponentLocations, this.GetCurrentPosition(), false);

        if (this.GetCurrentPosition().GetColumn() > Position.min)
        {
            if (opponentLocations.ValueAtPosition(new Position(this.GetCurrentPosition().GetColumn() - 1, rowToCheck)) > 0)
            {
                movesForCurrentPosition.FlipPosition(new Position(this.GetCurrentPosition().GetColumn() - 1, rowToCheck));
            }
        }
        if (this.GetCurrentPosition().GetColumn() < Position.max)
        {
            if (opponentLocations.ValueAtPosition(new Position(this.GetCurrentPosition().GetColumn() + 1, rowToCheck)) > 0)
            {
                movesForCurrentPosition.FlipPosition(new Position(this.GetCurrentPosition().GetColumn() + 1, rowToCheck));
            }
        }

        // En passant
        rowToCheck = this.GetCurrentPosition().GetRow();

        if (this.GetCurrentPosition().GetColumn() > Position.min)
        {
            if (opponentLocations.ValueAtPosition(new Position(this.GetCurrentPosition().GetColumn() - 1, rowToCheck)) > 0)
            {
                // Also check if the piece at this location is a pawn which has just performed a double jump
                AbstractPiece passedPiece = this.chessBoard.GetPieceAtPosition(new Position(this.GetCurrentPosition().GetColumn() - 1, rowToCheck));
                if (passedPiece != null && passedPiece.GetType().Name.CompareTo(this.GetType().Name) == 0 && ((Pawn)passedPiece).allowEnPassantCapture)
                {
                    int attackPoint = rowToCheck;
                    if (this.side == Side.Black)
                    {
                        attackPoint--;
                    }
                    else
                    {
                        attackPoint++;
                    }
                    movesForCurrentPosition.FlipPosition(new Position(this.GetCurrentPosition().GetColumn() - 1, attackPoint));
                }
            }
        }
        if (this.GetCurrentPosition().GetColumn() < Position.max)
        {
            if (opponentLocations.ValueAtPosition(new Position(this.GetCurrentPosition().GetColumn() + 1, rowToCheck)) > 0)
            {
                AbstractPiece passedPiece = this.chessBoard.GetPieceAtPosition(new Position(this.GetCurrentPosition().GetColumn() + 1, rowToCheck));
                if (passedPiece != null && passedPiece.GetType().Name.CompareTo(this.GetType().Name) == 0 && ((Pawn)passedPiece).allowEnPassantCapture)
                {
                    int attackPoint = rowToCheck;
                    if (this.side == Side.Black)
                    {
                        attackPoint--;
                    }
                    else
                    {
                        attackPoint++;
                    }
                    movesForCurrentPosition.FlipPosition(new Position(this.GetCurrentPosition().GetColumn() + 1, attackPoint));
                }
            }
        }

        return(movesForCurrentPosition);
    }
Ejemplo n.º 39
0
        public static void Test1()
        {
            Piece p = Piece.GOLD;

            Console.WriteLine(p.Pretty());
            Console.WriteLine(p.ToUsi());
            Piece p2 = Shogi.Core.Util.MakePiecePromote(Color.WHITE, p);

            Console.WriteLine(p2.ToUsi());

#if false
            // Squareのテスト
            Square sq = Square.SQ_56;
            //Console.WriteLine(sq.ToFile().ToUSI() + sq.ToRank().ToUSI());
            Console.WriteLine(sq.ToUsi());
            Console.WriteLine(sq.Pretty());
#endif

            Move m = Shogi.Core.Util.MakeMove(Square.SQ_56, Square.SQ_45);
            Console.WriteLine(m.ToUsi());

            Move m2 = Shogi.Core.Util.MakeMoveDrop(Piece.SILVER, Square.SQ_45);
            Console.WriteLine(m2.ToUsi());

            Move m3 = Shogi.Core.Util.MakeMovePromote(Square.SQ_84, Square.SQ_83);
            Console.WriteLine(m3.ToUsi());

            Move m4 = Shogi.Core.Util.FromUsiMove("8h2b+");
            Console.WriteLine(m4.Pretty());

            Move m5 = Shogi.Core.Util.FromUsiMove("G*3b");
            Console.WriteLine(m5.Pretty());

            Move m6 = Shogi.Core.Util.FromUsiMove("7g7f");

            Hand h = Hand.ZERO;
            h.Add(Piece.PAWN, 5);
            h.Add(Piece.KNIGHT, 1);
            Console.WriteLine(h.Pretty());
            Console.WriteLine(h.ToUsi(Color.BLACK));
            Console.WriteLine(h.ToUsi(Color.WHITE));

            var pos = new Position();
            //pos.UsiPositionCmd("startpos moves 7g7f 3c3d 8h3c+");

            pos.InitBoard(BoardType.NoHandicap);
            MoveGen.GenTest(pos);

            pos.UsiPositionCmd("sfen lnsgkgsnl/9/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL w - 1 moves 5a6b 7g7f 3a3b");

            Console.WriteLine(pos.Pretty());

#if false
            // UndoMove()のテスト
            pos.UndoMove();
            Console.WriteLine(pos.Pretty());

            pos.UndoMove();
            Console.WriteLine(pos.Pretty());

            pos.UndoMove();
            Console.WriteLine(pos.Pretty());
            Console.WriteLine(pos.PrettyPieceNo());
#endif

            // 駒番号のテスト
            //Console.WriteLine(pos.PrettyPieceNo());

            //  Console.WriteLine(pos.Pieces().Pretty());
            //  Console.WriteLine(pos.Pieces(Color.BLACK).Pretty());


#if false
            // Bitboard(Square)のテスト
            for (Square sq = Square.ZERO; sq < Square.NB; ++sq)
            {
                Console.WriteLine("sq = " + sq.Pretty());
                Bitboard b = new Bitboard(sq);
                Console.WriteLine(b.Pretty());
            }
#endif

#if false
            // 角・馬の利きのテスト
            Bitboard occupied = new Bitboard(Square.SQ_33);
            Console.WriteLine(occupied.Pretty());
            Bitboard bb = Bitboard.BishopEffect(Square.SQ_55, occupied);
            Console.WriteLine(bb.Pretty());

            Bitboard bb2 = Bitboard.BishopStepEffect(Square.SQ_56);
            Console.WriteLine(bb2.Pretty());

            Bitboard bb3 = Bitboard.BishopEffect(Square.SQ_56, Bitboard.AllBB());
            Console.WriteLine(bb3.Pretty());

            Bitboard bb4 = Bitboard.HorseEffect(Square.SQ_55, occupied);
            Console.WriteLine(bb4.Pretty());
#endif

#if false
            // 飛車・龍の利きのテスト
            Bitboard occupied = new Bitboard(Square.SQ_53);
            Console.WriteLine(occupied.Pretty());
            Bitboard bb = Bitboard.RookEffect(Square.SQ_55, occupied);
            Console.WriteLine(bb.Pretty());

            Bitboard bb2 = Bitboard.RookStepEffect(Square.SQ_56);
            Console.WriteLine(bb2.Pretty());

            Bitboard bb3 = Bitboard.RookEffect(Square.SQ_56, Bitboard.AllBB());
            Console.WriteLine(bb3.Pretty());

            Bitboard bb4 = Bitboard.DragonEffect(Square.SQ_55, occupied);
            Console.WriteLine(bb4.Pretty());
#endif

#if false
            // 香りの利きのテスト
            Bitboard occupied = new Bitboard(Square.SQ_53);
            Bitboard bb       = Bitboard.LanceEffect(Color.BLACK, Square.SQ_55, occupied);
            Console.WriteLine(bb.Pretty());

            Bitboard bb3 = Bitboard.LanceStepEffect(Color.BLACK, Square.SQ_56);
            Console.WriteLine(bb3.Pretty());
#endif

#if false
            // 歩、桂、銀、金、玉の利きのテスト
            Bitboard bb = Bitboard.PawnEffect(Color.BLACK, Square.SQ_55);
            Console.WriteLine(bb.Pretty());

            Bitboard bb2 = Bitboard.KnightEffect(Color.BLACK, Square.SQ_55);
            Console.WriteLine(bb2.Pretty());

            Bitboard bb3 = Bitboard.SilverEffect(Color.BLACK, Square.SQ_55);
            Console.WriteLine(bb3.Pretty());

            Bitboard bb4 = Bitboard.GoldEffect(Color.BLACK, Square.SQ_55);
            Console.WriteLine(bb4.Pretty());

            Bitboard bb5 = Bitboard.KingEffect(Square.SQ_55);
            Console.WriteLine(bb5.Pretty());
#endif

#if false
            // EffectsFrom()のテスト
            var bb = Bitboard.EffectsFrom(Piece.W_DRAGON, Square.SQ_54, pos.Pieces());
            Console.WriteLine(bb.Pretty());

            var bb2 = Bitboard.EffectsFrom(Piece.W_GOLD, Square.SQ_54, pos.Pieces());
            Console.WriteLine(bb2.Pretty());
#endif

#if false
            // BitboardのPop()のテスト
            for (Square sq = Square.ZERO; sq < Square.NB; ++sq)
            {
                Console.Write("sq = " + sq.Pretty() + " ");
                Bitboard b = new Bitboard(sq);
                Square   r = b.Pop();
                Console.WriteLine(r.Pretty());
            }
#endif

#if false
            // 駒落ちの局面のテスト
            pos.InitBoard(BoardType.Handicap2); // 2枚落ち
            Console.WriteLine(pos.Pretty());

            pos.InitBoard(BoardType.Handicap10); // 10枚落ち
            Console.WriteLine(pos.Pretty());
#endif

#if false
            pos.SetSfen(Position.SFEN_HIRATE);
            Console.WriteLine(pos.ToSfen());
            Console.WriteLine(pos.Pretty());
            pos.DoMove(m6);
            Console.WriteLine(pos.Pretty());
#endif

#if false
            // sfen化して、setしてhash keyが変わらないかのテスト
            //pos.SetSfen(pos.ToSfen());
            //Console.WriteLine(pos.Pretty());
#endif

#if false
            // 指し手生成祭りの局面
            pos.SetSfen("l6nl/5+P1gk/2np1S3/p1p4Pp/3P2Sp1/1PPb2P1P/P5GS1/R8/LN4bKL w RGgsn5p 1");
            Console.WriteLine(pos.ToSfen());
            Console.WriteLine(pos.Pretty());
#endif

#if false
            // 駒番号のデバッグ
            Console.WriteLine(pos.PrettyPieceNo());

            //            Console.WriteLine(pos.Pieces().Pretty());
            //           Console.WriteLine(pos.Pieces(Color.BLACK).Pretty());
#endif

#if false
            // BitweenBB()のテスト
            var bb = Bitboard.BetweenBB(Square.SQ_77, Square.SQ_33);
            Console.WriteLine(bb.Pretty());

            var bb2 = Bitboard.BetweenBB(Square.SQ_58, Square.SQ_52);
            Console.WriteLine(bb2.Pretty());
#endif

#if false
            // 乱数テスト
            var rand = new PRNG(1234);
            Console.WriteLine(rand.Rand());
            Console.WriteLine(rand.Rand());
            Console.WriteLine(rand.Rand());

            var key_side = Zobrist.Side;
            Console.WriteLine(key_side.ToString());
#endif

#if false
            // serialization test

            var csa        = new Model.CsaConnectData();
            var serializer = new DataContractJsonSerializer(typeof(Model.CsaConnectData));
            var ms         = new MemoryStream();
            serializer.WriteObject(ms, csa);
            var json = Encoding.UTF8.GetString(ms.ToArray());
            MessageBox.Show(json);
#endif

#if false
            // UsiPositionCmdのテスト。非合法手が混じっているパターン

            var pos2 = new Position();
            try
            {
                pos2.UsiPositionCmd("startpos moves 7g7f 3c4d 2g2f "); // 2手目が非合法手
            } catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
#endif

#if false
            {
                // 千日手の引き分けのテスト
                var pos2 = new Position();
                pos.UsiPositionCmd("startpos moves");

                var moves = new[] {
                    Util.MakeMove(Square.SQ_59, Square.SQ_58),
                    Util.MakeMove(Square.SQ_51, Square.SQ_52),
                    Util.MakeMove(Square.SQ_58, Square.SQ_59),
                    Util.MakeMove(Square.SQ_52, Square.SQ_51),
                };

                int ply = 0;
                for (int j = 0; j < 5; ++j)
                {
                    for (int i = 0; i < moves.Length; ++i)
                    {
                        pos.DoMove(moves[i]);
                        var rep = pos.IsRepetition();

                        ply++;
                        Console.WriteLine(string.Format("ply = {0} , rep = {1} ", ply, rep.ToString()));

                        // 16手目を指した局面(17手目)が先手番で千日手引き分けの局面になるはず
                    }
                }
            }
#endif

#if false
            {
                // 連続王手の千日手の負けのテスト
                var pos2 = new Position();
                pos.UsiPositionCmd("startpos moves 7g7f 5c5d 8h3c 5a6b");

                var moves = new[] {
                    Util.MakeMove(Square.SQ_33, Square.SQ_44),
                    Util.MakeMove(Square.SQ_62, Square.SQ_51),
                    Util.MakeMove(Square.SQ_44, Square.SQ_33),
                    Util.MakeMove(Square.SQ_51, Square.SQ_62),
                };

                int ply = 4;
                for (int j = 0; j < 5; ++j)
                {
                    for (int i = 0; i < moves.Length; ++i)
                    {
                        pos.DoMove(moves[i]);
                        //Console.WriteLine(pos.Pretty());
                        //Console.WriteLine(pos.State().checkersBB.Pretty());

                        var rep = pos.IsRepetition();

                        ply++;
                        Console.WriteLine(string.Format("ply = {0} , rep = {1} ", ply, rep.ToString()));

                        // 19手目の局面(を指した直後の局面=20手目,後手番)で、ここで後手勝ちになるはず。
                    }
                }
            }
#endif

#if false
            //  UndoMove()でcapture,promoteが戻るかのテスト
            var pos2 = new Position();
            pos2.UsiPositionCmd("startpos moves 7g7f 3c3d 8h2b+");
            Console.WriteLine(pos2.Pretty());
            pos2.UndoMove();
            Console.WriteLine(pos2.Pretty());
            pos2.UndoMove();
            Console.WriteLine(pos2.Pretty());
            pos2.UndoMove();
            Console.WriteLine(pos2.Pretty());
            Console.WriteLine(pos2.PrettyPieceNo());
#endif

#if true
            {
                // -- 局面の合法性のチェック

                // 平手
                pos.SetSfen("lnsgkgsnl/9/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL b - 1");
                Console.WriteLine(pos.IsValid());

                // 先手2歩
                pos.SetSfen("lnsgkgsnl/9/9/P8/9/9/P8/1B5R1/LNSGKGSNL b - 1");
                Console.WriteLine(pos.IsValid());

                // 後手2歩
                pos.SetSfen("lnsgkgsnl/9/8p/8p/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL b - 1");
                Console.WriteLine(pos.IsValid());

                // 玉なし
                pos.SetSfen("lnsg1gsnl/9/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSG1GSNL b - 1");
                Console.WriteLine(pos.IsValid());

                // 片玉
                pos.SetSfen("lnsg1gsnl/9/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL b - 1");
                Console.WriteLine(pos.IsValid());

                // 片玉(詰将棋時) これは合法
                pos.SetSfen("lnsg1gsnl/9/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL b - 1");
                Console.WriteLine("詰将棋片玉 : " + pos.IsValid(true));

                // 先手玉が2枚
                pos.SetSfen("lnsgKgsnl/9/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL b - 1");
                Console.WriteLine(pos.IsValid());

                // 玉3枚
                pos.SetSfen("lnsgkksnl/9/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL b - 1");
                Console.WriteLine(pos.IsValid());

                // 非手番側に王手
                pos.SetSfen("lnsgkgsnl/9/ppppppBpp/9/9/9/PPPPPPPPP/25R1/LNSGKGSNL b - 1");
                Console.WriteLine(pos.IsValid());

                // 行き場の無い駒
                pos.SetSfen("Lnsgkgsnl/9/pppppp1pp/9/9/9/PPPPPPPPP/25R1/LNSGKGSNL b - 1");
                Console.WriteLine(pos.IsValid());
                pos.SetSfen("l1sgkgsnl/N8/pppppp1pp/9/9/9/PPPPPPPPP/25R1/LNSGKGSNL b - 1");
                Console.WriteLine(pos.IsValid());
                pos.SetSfen("P1sgkgsnl/9/pppppp1pp/9/9/9/9/25R1/LNSGKGSNL b - 1");
                Console.WriteLine(pos.IsValid());
                pos.SetSfen("2sgkgsnl/9/9/9/9/9/9/25R1/LNSGKGSNp b - 1");
                Console.WriteLine(pos.IsValid());
            }
#endif
        }
Ejemplo n.º 40
0
 public IEnumerable<Move> GetMovesOneSquareForward(Bitboard notblockers)
 {
     Bitboard b = (this.Locations << 8 & notblockers);
     return GetMoves(b, 8);
 }
Ejemplo n.º 41
0
 public static void PopLsb(ref Bitboard bitboard)
 {
     bitboard &= (bitboard - 1);
 }
Ejemplo n.º 42
0
 public IEnumerable<Move> GetMovesOneSquareForward(Bitboard notblockers, Bitboard filterFrom, Bitboard filterTo)
 {
     Bitboard l = this.Locations & filterFrom;
     Bitboard b = (l << 8 & notblockers);
     b &= filterTo;
     return GetMoves(b, 8);
 }
Ejemplo n.º 43
0
 public static int BitScanForward(this Bitboard bitboard)
 {
     Debug.Assert(bitboard != 0);
     return(MultiplyDeBruijnBitPosition[((ulong)((long)bitboard & -(long)bitboard) * DeBruijnSequence) >> 58]);
 }
Ejemplo n.º 44
0
        public IEnumerable<Move> GetMovesTwoSquaresForward(Bitboard notblockers, Bitboard filterFrom, Bitboard filterTo)
        {
            var b = Locations.Intersect(new Rank(1)).Intersect(filterFrom);
            b = b.Shift(1, 0).Intersect(notblockers);
            b = b.Shift(1, 0).Intersect(notblockers);
            b = b.Intersect(filterTo);

            foreach(var to in b.Squares)
            {
                Square from = to - 16;
                b = b.Except(to);
                yield return new Move(from, to);
            }
        }
Ejemplo n.º 45
0
        public static void TestPawnMoves(bool captureFunc, string fen, Move[] expectedMoves, int color, Bitboard destinationBitboard = 0)
        {
            Position board       = Position.FromFen(fen);
            MoveList actualMoves = new MoveList();

            if (destinationBitboard == 0)
            {
                destinationBitboard = ~board.GetPieceBitboard(color, Position.ALL_PIECES);
            }
            if (captureFunc)
            {
                board.GetAllPawnCaptureMoves(actualMoves, color, destinationBitboard);
            }
            else
            {
                board.GetAllPawnPushMoves(actualMoves, color, destinationBitboard);
            }
            TestArrayEquality(expectedMoves, actualMoves.ToArray());
        }
Ejemplo n.º 46
0
 public IEnumerable<Move> GetCaptures(Bitboard enemies, Square? enpassant = null)
 {
     return GetCaptures(enemies, Bitboard.Full, Bitboard.Full, enpassant);
 }
Ejemplo n.º 47
0
 public Bitboard GetMoveBoard(Square from, Bitboard friends, Bitboard enemies)
 {
     return
         rook.GetMoveBoard(from, friends, enemies).And(
         bishop.GetMoveBoard(from, friends, enemies));
 }
Ejemplo n.º 48
0
        public Bitboard GetMoveBoard(Bitboard notblockers, Bitboard enemies, Square? enpassant)
        {
            var onesquarforward = (this.Locations << 8 & notblockers);

            var twosquaresforward = Locations
                .Intersect(new Rank(1))
                .Shift(1, 0).Intersect(notblockers)
                .Shift(1, 0).Intersect(notblockers);

            return onesquarforward | twosquaresforward |
                GetCapturesMoveBoard(notblockers, enemies, enpassant);
        }
Ejemplo n.º 49
0
 static Util_TryRule()
 {
     m_trySakiBB_ = new Bitboard();
 }
Ejemplo n.º 50
0
        /// <summary>
        /// トライできる先。
        /// </summary>
        /// <param name="ky">局面</param>
        /// <param name="kikiBB">手番らいおんの利きビットボード</param>
        /// <param name="tb">手番</param>
        /// <param name="ms1">手番らいおんがいる升</param>
        /// <returns></returns>
        public static Bitboard GetTrySaki(Bitboard kikiBB, Masu ms1)
        {
#if DEBUG
            Util_Test.AppendLine("テスト: トライルール", Pure.Sc.dbgMojiretu);
#endif
            m_trySakiBB_.Clear();

            // 自分はN段目にいる☆
            int  dan     = Conv_Masu.ToDanO1_JibunSiten(PureMemory.kifu_teban, ms1);
            bool nidanme = 2 == dan;
#if DEBUG
            Util_Test.AppendLine($"2段目にいるか☆?[{nidanme}] わたしは[{dan}]段目にいるぜ☆", Pure.Sc.dbgMojiretu);
#endif
            if (!nidanme)
            {
#if DEBUG
                Util_Test.AppendLine("むりだぜ☆", Pure.Sc.dbgMojiretu);
                //Util_Test.Flush(reigai1);
#endif
                return(m_trySakiBB_);
            }

            // 1段目に移動できる升☆

            m_trySakiBB_.Set(kikiBB);
            m_trySakiBB_.Siborikomi(BitboardsOmatome.bb_try[PureMemory.kifu_nTeban]);

#if DEBUG
            Interproject.project.Dbg_TryRule1(kikiBB, m_trySakiBB_);
#endif

            // 味方の駒がないところ☆
            Bitboard spaceBB = new Bitboard();
            spaceBB.Set(BitboardsOmatome.bb_boardArea);
            PureMemory.gky_ky.shogiban.ibashoBan_yk00.yomiIbashoBan.ToSitdown_KomaZenbu(PureMemory.kifu_teban, spaceBB);
            m_trySakiBB_.Siborikomi(spaceBB);

#if DEBUG
            Interproject.project.Dbg_TryRule2(spaceBB, m_trySakiBB_);
#endif
            if (m_trySakiBB_.IsEmpty())
            {
#if DEBUG
                Util_Test.AppendLine("むりだぜ☆", Pure.Sc.dbgMojiretu);
                //Util_Test.Flush(reigai1);
#endif
                return(m_trySakiBB_);
            }

            // 相手の利きが届いていないところ☆
            Bitboard safeBB = new Bitboard();
            safeBB.Set(BitboardsOmatome.bb_boardArea);
            PureMemory.gky_ky.yomiKy.yomiShogiban.yomiKikiBan.ToSitdown_BBKikiZenbu(PureMemory.kifu_aiteban, safeBB);
            m_trySakiBB_.Siborikomi(safeBB);

#if DEBUG
            Interproject.project.Dbg_TryRule3(safeBB, m_trySakiBB_);
#endif
            if (m_trySakiBB_.IsEmpty())
            {
#if DEBUG
                Util_Test.AppendLine("むりだぜ☆", Pure.Sc.dbgMojiretu);
                //Util_Test.Flush(reigai1);
#endif
                return(m_trySakiBB_);
            }

#if DEBUG
            Util_Test.AppendLine("トライできるぜ☆", Pure.Sc.dbgMojiretu);
            //Util_Test.Flush(reigai1);
#endif

            return(m_trySakiBB_);
        }
Ejemplo n.º 51
0
 internal static Bitboard ExcludeSquares(ref Bitboard bb, Bitboard exclude)
 {
     return(bb &= ~exclude);
 }