/// <summary> /// マージするための下請け。 /// /// currentNodeのsfen == tree.currentNodeのsfen /// であることは保証されている。 /// /// ここにマージしていく。 /// </summary> /// <param name="tree"></param> private void MergeSub(KifuTree tree) { //Debug.Assert(position.ToSfen() == tree.position.ToSfen()); // → このAssert書きたいが、重くなるので省略。 // それぞれの指し手で進めて再帰的に自分自身を呼び出す。 var moves = tree.currentNode.moves; foreach (var move in moves) { // すでに同じ指し手の分岐を持っているか? var move2 = currentNode.moves.Find(kifuMove => kifuMove.nextMove == move.nextMove); if (move2 != null) { // 見つかったのでこの枝を辿って再帰的に子nodeを追加。 DoMove(move2); tree.DoMove(move); MergeSub(tree); tree.UndoMove(); UndoMove(); } else { // ただしprevNodeは異なるので、この指し手で進めたときのprevNodeを書き換えてやる必要はある。 move.nextNode.prevNode = currentNode; // 見つからなかったのでこの枝をまるごと追加。 currentNode.moves.Add(move); } } }
/// <summary> /// 別のKifuTreeをマージする。 /// /// マージされた棋譜の本譜の末尾の局面を指していて欲しい気もするが…。 /// せめて、マージされた開始局面を指すようにするか。 /// /// エラーがあればその内容を文字列として返す。 /// </summary> /// <param name="tree"></param> public string Merge(KifuTree tree) { // このsfenの局面にマージする。 var sfen = tree.rootSfen; // このnodeを探す var node = SearchNode(sfen); if (node == null) { return("メイン棋譜にマージするための開始局面がありませんでした。"); } // このnodeにマージしていく。 tree.RewindToRoot(); MergeSub(tree); return(null); }