Exemple #1
0
        public void MateTest2()
        {
            var bod =
                "# ----  棋譜ファイル  ----\n" +
                "先手:先手\n" +
                "後手:後手\n" +
                "後手の持駒:歩三 \n" +
                "  9 8 7 6 5 4 3 2 1\n" +
                "+---------------------------+\n" +
                "|v香v桂 ・ ・ ・ ・ ・ ・ ・|一\n" +
                "| ・ ・ ・ ・ ・ ・ ・ ・ ・|二\n" +
                "|v玉v桂v歩 金 ・ ・ ・ ・ ・|三\n" +
                "| ・ ・ ・ ・ ・ ・ ・ ・ ・|四\n" +
                "| ・ 銀 ・ 歩 ・ ・ ・ ・ ・|五\n" +
                "| 玉 ・ 歩 ・ 歩 香 ・ ・ ・|六\n" +
                "| ・v金 銀 金 ・ ・ ・ ・ ・|七\n" +
                "| ・ ・v馬 銀 ・ ・ ・ ・ ・|八\n" +
                "| 香 ・ ・ ・ ・ ・ ・ ・ ・|九\n" +
                "+---------------------------+\n" +
                "先手の持駒:飛二 角 金 銀 桂二 香 歩十一 \n" +
                "手数=0\n" +
                "後手番\n";
            var board = BodBoard.Parse(bod);

            var move = BoardMove.CreateDrop(
                BWType.White,
                new Square(9, 5),
                PieceType.Hu);

            Assert.False(board.CanMove(move));
            Assert.False(board.DoMove(move));
        }
Exemple #2
0
        public void MateTest1()
        {
            var bod =
                "後手の持駒:角二 桂二 歩五 \n" +
                "  9 8 7 6 5 4 3 2 1\n" +
                "+---------------------------+\n" +
                "|v香 ・ ・ ・ ・ ・ ・ ・v香|一\n" +
                "| ・ ・ ・ ・ 銀 ・v金 ・ ・|二\n" +
                "| ・ ・ とv歩v歩 ・ ・v歩 ・|三\n" +
                "| ・ ・ ・ ・ ・ ・v歩 ・v歩|四\n" +
                "| 歩 ・ 銀 金 ・ 飛 ・ ・ ・|五\n" +
                "| ・ ・ 銀 歩 ・ 金 ・v玉 歩|六\n" +
                "| 玉 歩 桂 ・ ・ ・ ・ ・ ・|七\n" +
                "| ・ ・ 歩 ・ ・ 歩 金 ・ ・|八\n" +
                "| 香v飛 ・ ・ ・ 銀 ・ ・ 香|九\n" +
                "+---------------------------+\n" +
                "先手の持駒:桂 歩 \n" +
                "手数=130";
            var board = BodBoard.Parse(bod);

            var move = BoardMove.CreateDrop(
                BWType.Black,
                new Square(2, 7),
                PieceType.Hu);

            Assert.False(board.CanMove(move));
            Assert.False(board.DoMove(move));
        }
Exemple #3
0
        /// <summary>
        /// 移動中の駒を新しい位置に移動します。
        /// </summary>
        /// <remarks>
        /// 指せない指し手の場合は、駒の移動を終了します。
        /// </remarks>
        private void DoMoveNormal(Square dstSquare)
        {
            var       srcSquare = this.movingPiece.Square;
            var       piece     = this.movingPiece.Piece;
            BoardMove move      = null;

            if (srcSquare != null)
            {
                // 駒の移動の場合
                move = BoardMove.CreateMove(
                    piece.BWType, srcSquare, dstSquare, piece.Piece, false);

                // 成/不成りのダイアログを出す前に着手可能か確認します。
                if (!CanMove(move))
                {
                    move.IsPromote = true;
                    if (!CanMove(move))
                    {
                        EndMove();
                        return;
                    }
                }

                // 成れる場合は選択用のダイアログを出します。
                if (!move.IsPromote && Board.CanPromote(move))
                {
                    var promote = CheckToPromote(piece.PieceType, move.BWType);

                    move.IsPromote = promote;
                }
            }
            else
            {
                // 駒打ちの場合
                move = BoardMove.CreateDrop(
                    piece.BWType, dstSquare, piece.PieceType);

                if (!CanMove(move))
                {
                    EndMove();
                    return;
                }
            }

            EndMove();
            DoMove(move);
        }
Exemple #4
0
        /// <summary>
        /// CSA形式の指し手を解析します。
        /// </summary>
        public static BoardMove CsaToMove(this Board board, string csa)
        {
            if (board == null)
            {
                throw new ArgumentNullException("board");
            }

            if (string.IsNullOrEmpty(csa))
            {
                throw new ArgumentNullException("csa");
            }

            // 特殊な指し手
            var smove = board.CsaToSpecialMove(csa);

            if (smove != null)
            {
                return(smove);
            }

            // 普通の指し手
            var m = MoveRegex.Match(csa);

            if (!m.Success)
            {
                return(null);
            }

            var c    = m.Groups[1].Value;
            var side = (
                c == "+" ? BWType.Black :
                c == "-" ? BWType.White :
                BWType.None);

            // 移動前の位置
            var srcFile   = int.Parse(m.Groups[2].Value);
            var srcRank   = int.Parse(m.Groups[3].Value);
            var srcSquare =
                (srcFile == 0 || srcRank == 0
                ? (Square)null
                : new Square(srcFile, srcRank));

            // 移動後の位置
            var dstFile   = int.Parse(m.Groups[4].Value);
            var dstRank   = int.Parse(m.Groups[5].Value);
            var dstSquare =
                (dstFile == 0 || dstRank == 0
                ? (Square)null
                : new Square(dstFile, dstRank));

            // 駒
            var piece = CsaUtil.StrToPiece(m.Groups[6].Value);

            if (piece == null || piece.PieceType == PieceType.None)
            {
                return(null);
            }

            if (srcSquare == null)
            {
                // 駒打ちの場合
                return(BoardMove.CreateDrop(side, dstSquare, piece.PieceType));
            }
            else
            {
                // 駒の移動の場合、成りの判定を行います。
                var srcPiece = board[srcSquare];
                if (srcPiece == null || !srcPiece.Validate())
                {
                    return(null);
                }

                // CSA形式の場合、駒が成ると駒の種類が変わります。
                var isPromote = (!srcPiece.IsPromoted && piece.IsPromoted);
                if (isPromote)
                {
                    piece = new Piece(piece.PieceType, false);
                }

                return(BoardMove.CreateMove(side, srcSquare, dstSquare, piece, isPromote));
            }
        }
Exemple #5
0
        public void SerializeTest()
        {
            // すべてのマスをテストすると時間がかかりすぎるため、
            // 移動元・移動先共にテストするマスを絞っています。
            var validMoveList =
                from turn in new BWType[] { BWType.Black, BWType.White }
            from dst in Board.AllSquares()
            from src in Board.AllSquares()
            from pc in EnumEx.GetValues <PieceType>()
            from promoted in new bool[] { false, true }
            from tookPc in EnumEx.GetValues <PieceType>()
            from tookPromoted in new bool[] { false, true }
            from promote in new bool[] { false, true }
            let  pcPiece = new Piece(pc, promoted)
                           let tookPiece = (tookPc != PieceType.None ?
                                            new Piece(tookPc, tookPromoted) : null)
                                           where pcPiece.Validate()
                                           where tookPiece == null || tookPiece.Validate()
                                           where (dst.Rank % 2) == 1 && (dst.File % 3) == 1
                                           where (src.Rank % 2) == 1 && (src.File % 3) == 1
                                           let bmove = BoardMove.CreateMove(
                turn, src, dst,
                pcPiece, promote,
                tookPiece)
                                                       where bmove.Validate()
                                                       select bmove;

            var validDropList =
                from turn in new BWType[] { BWType.Black, BWType.White }
            from dst in Board.AllSquares()
            from pc in EnumEx.GetValues <PieceType>()
            where pc != PieceType.None
            let bmove = BoardMove.CreateDrop(turn, dst, pc)
                        where bmove.Validate()
                        select bmove;

            var specialMoveList =
                from turn in new BWType[] { BWType.Black, BWType.White }
            from special in EnumEx.GetValues <SpecialMoveType>()
            where special != SpecialMoveType.None
            let bmove = BoardMove.CreateSpecialMove(turn, special)
                        where bmove.Validate()
                        select bmove;

            var count = 0;

            var moveList = validMoveList.Concat(validDropList).Concat(specialMoveList);

            foreach (var bmove in moveList)
            {
                var bytes = PbUtil.Serialize(bmove);
                Assert.NotNull(bytes);

                var newMove = PbUtil.Deserialize <BoardMove>(bytes);
                Assert.NotNull(newMove);
                Assert.True(newMove.Validate());

                Assert.AreEqual(bmove, newMove);

                // 多くのテストがあるため、一応
                if (count++ % 50000 == 0)
                {
                    Console.WriteLine("BoardMoveTest.SerializeTest testing...");
                }
            }
        }
Exemple #6
0
        /// <summary>
        /// SFEN形式の指し手を、指し手に変換します。
        /// </summary>
        public static BoardMove SfenToMove(this Board board, string sfen)
        {
            if (board == null)
            {
                throw new ArgumentNullException("board");
            }

            if (string.IsNullOrEmpty(sfen))
            {
                throw new ArgumentNullException("sfen");
            }

            if (sfen.Length < 4)
            {
                return(null);
            }

            var dropPieceType = SfenUtil.SfenToPieceType(sfen[0]);

            if (dropPieceType != PieceType.None)
            {
                // 駒打ちの場合
                if ((sfen[1] != '*') ||
                    (sfen[2] < '1' || '9' < sfen[2]) ||
                    (sfen[3] < 'a' || 'i' < sfen[3]))
                {
                    return(null);
                }

                var dstFile = (sfen[2] - '1') + 1;
                var dstRank = (sfen[3] - 'a') + 1;

                return(BoardMove.CreateDrop(
                           board.Turn, new Square(dstFile, dstRank), dropPieceType));
            }
            else
            {
                // 駒の移動の場合
                if ((sfen[0] < '1' || '9' < sfen[0]) ||
                    (sfen[2] < '1' || '9' < sfen[2]) ||
                    (sfen[1] < 'a' || 'i' < sfen[1]) ||
                    (sfen[3] < 'a' || 'i' < sfen[3]))
                {
                    return(null);
                }

                var srcFile = (sfen[0] - '1') + 1;
                var srcRank = (sfen[1] - 'a') + 1;
                var dstFile = (sfen[2] - '1') + 1;
                var dstRank = (sfen[3] - 'a') + 1;
                var piece   = board[srcFile, srcRank];
                if (piece == null)
                {
                    return(null);
                }

                var promote = (sfen.Length > 4 && sfen[4] == '+');
                return(BoardMove.CreateMove(
                           board.Turn,
                           new Square(srcFile, srcRank),
                           new Square(dstFile, dstRank),
                           piece.Piece,
                           promote,
                           BoardPiece.GetPiece(board[dstFile, dstRank])));
            }
        }