Beispiel #1
0
        /// <summary>
        /// KifMoveNodeからMoveNodeへ構造を変換します。
        /// 結果は<paramref name="root"/>以下に設定されます。
        /// </summary>
        private void ConvertToMoveNode(MoveNode root, Board board,
                                       List <Exception> errors)
        {
            for (var node = this; node != null; node = node.VariationNode)
            {
                // 指し手を実際に指してみます。
                var move = node.MakeMove(board, errors);
                if (move == null)
                {
                    continue;
                }

                var moveNode = new MoveNode
                {
                    Move        = move,
                    MoveCount   = node.MoveCount,
                    Duration    = node.Duration,
                    PVInfoList  = node.PVInfoList,
                    CommentList = node.CommentList,
                };

                // 次の指し手とその変化を変換します。
                if (node.NextNode != null)
                {
                    // 次の手以降の手はこのノードを親として追加していきます。
                    node.NextNode.ConvertToMoveNode(moveNode, board, errors);
                }

                root.AddNextNode(moveNode);
                board.Undo();
            }
        }
Beispiel #2
0
        /// <summary>
        /// KifMoveNodeからMoveNodeへ構造を変換します。
        /// 結果は<paramref name="root"/>以下に設定されます。
        /// </summary>
        private void ConvertToMoveNode(Board board, MoveNode root,
                                       List <Exception> errors)
        {
            for (var node = this; node != null; node = node.Variation)
            {
                var cloned = board.Clone();

                // 指し手を実際に指してみます。
                var bmove = node.MakeMove(cloned, errors);
                if (bmove == null)
                {
                    continue;
                }

                var moveNode = new MoveNode
                {
                    Move      = bmove,
                    MoveCount = node.MoveCount,
                    Duration  = node.Duration,
                    Comment   = node.Comment,
                };

                // 次の指し手とその変化を変換します。
                if (node.Next != null)
                {
                    node.Next.ConvertToMoveNode(cloned, moveNode, errors);
                }

                root.AddNext(moveNode);
            }
        }
Beispiel #3
0
        /// <summary>
        /// 指し手リストをツリー形式に変換します。
        /// </summary>
        public static MoveNode Convert2Node(IEnumerable <BoardMove> moveList,
                                            int firstMoveCount)
        {
            if (moveList == null)
            {
                throw new ArgumentNullException("moveList");
            }

            var root = new MoveNode();
            var last = root;

            foreach (var move in moveList)
            {
                var node = new MoveNode()
                {
                    MoveCount = firstMoveCount++,
                    Move      = move,
                };

                last.AddNext(node);
                last = node;
            }

            return(root);
        }
Beispiel #4
0
        /// <summary>
        /// コンストラクタ
        /// </summary>
        public KifuObject(KifuHeader header,
                          Board startBoard,
                          MoveNode root, Exception error = null)
        {
            Error = error;

            SetHeader(header);
            SetBoard(startBoard, true);
            SetRootNode(root);
        }
Beispiel #5
0
        /// <summary>
        /// 変化ツリーのルートノードを設定します。
        /// </summary>
        public void SetRootNode(MoveNode root)
        {
            if (root == null)
            {
                throw new ArgumentNullException("root");
            }

            RootNode = root;
            MoveList = Convert2List(root).ToList();
        }
Beispiel #6
0
        /// <summary>
        /// コンストラクタ
        /// </summary>
        public KifuObject(KifuHeader header,
                          Board startBoard,
                          Exception error = null)
        {
            MoveList = new List <BoardMove>();
            RootNode = new MoveNode();
            Error    = error;

            SetHeader(header);
            SetBoard(startBoard, false);
        }
Beispiel #7
0
        /// <summary>
        /// 指し手ツリーをリスト形式に変換します。
        /// </summary>
        public static IEnumerable <BoardMove> Convert2List(MoveNode root)
        {
            if (root == null)
            {
                throw new ArgumentNullException("root");
            }

            // 先頭ノードの手はnullのため、次のノードから手を取得します。
            for (var node = root.NextNode; node != null; node = node.NextNode)
            {
                yield return(node.Move);
            }
        }
Beispiel #8
0
        /// <summary>
        /// ノード全体を正規化し、変化の重複などをなくします。
        /// </summary>
        private static void RegulalizeStatic(MoveNode node, int moveCount)
        {
            while (node != null)
            {
                // 変化の重複を削除します。
                for (var i = 0; i < node.NextNodes.Count(); ++i)
                {
                    for (var j = i + 1; j < node.NextNodes.Count();)
                    {
                        var baseNode = node.NextNodes[i];
                        var compNode = node.NextNodes[j];

                        if (baseNode.Move == compNode.Move)
                        {
                            // もし同じ指し手の変化があれば、子の指し手をマージします。
                            // 子の重複チェックはこの後行うので、
                            // ここで重複があっても構いません。
                            compNode.NextNodes.ForEach(_ => _.ParentNode = null);
                            compNode.NextNodes.ForEach(_ => baseNode.AddNextNode(_));

                            node.NextNodes.RemoveAt(j);
                        }
                        else
                        {
                            ++j;
                        }
                    }
                }

                // 手数の再設定
                node.MoveCount = moveCount;

                if (node.NextNodeCount == 1)
                {
                    // 手数が長くなったときスタックオーバーフローになるため、
                    // 子ノードが一つの場合はループ内で回します。
                    node       = node.NextNode;
                    moveCount += 1;
                }
                else
                {
                    // 子ノードに関してもチェックを行います。
                    foreach (var child in node.NextNodes)
                    {
                        RegulalizeStatic(child, moveCount + 1);
                    }

                    return;
                }
            }
        }
Beispiel #9
0
        /// <summary>
        /// 次の指し手ノードを追加します。
        /// </summary>
        public void AddNext(MoveNode node)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }

            if (node.ParentNode != null)
            {
                throw new InvalidOperationException(
                          "すでに親ノードが登録されています。");
            }

            NextNodes.Add(node);
            node.ParentNode = this;
        }
Beispiel #10
0
        /// <summary>
        /// ノード全体を比較します。
        /// </summary>
        public bool NodeEquals(MoveNode other, bool compareComment)
        {
            if (ReferenceEquals(other, null))
            {
                return(false);
            }

            if (MoveCount != other.MoveCount)
            {
                return(false);
            }

            if (Move != other.Move)
            {
                return(false);
            }

            if (Duration != other.Duration)
            {
                return(false);
            }

            if (NextNodeCount != other.NextNodeCount)
            {
                return(false);
            }

            if (compareComment && Comment != other.Comment)
            {
                return(false);
            }

            for (var i = 0; i < NextNodeCount; ++i)
            {
                if (!NextNodes[i].NodeEquals(other.NextNodes[i], compareComment))
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #11
0
        /// <summary>
        /// KifMoveNodeからMoveNodeへ構造を変換します。
        /// </summary>
        public MoveNode ConvertToMoveNode(Board board, KifMoveNode head,
                                          out Exception error)
        {
            var errors = new List <Exception>();
            var root   = new MoveNode
            {
                MoveCount = head.MoveCount,
                Duration  = head.Duration,
                Comment   = head.Comment,
            };

            // これでrootの子要素に指し手ツリーが設定されます。
            ConvertToMoveNode(board, root, errors);

            error = (
                !errors.Any() ? null :
                errors.Count() == 1 ? errors.FirstOrDefault() :
                new AggregateException(errors));

            return(root);
        }