/// <summary> /// DoMove()のときに棋譜に追加する /// </summary> /// <param name="m"></param> private void AddKifu(Move m, TimeSpan t) { if (EnableKifuList) { // 棋譜をappendする var move_text = move_to_kif_string(position, m); var move_text_game_ply = position.gamePly; move_text = string.Format("{0,-4}", move_text); move_text = move_text.Replace(' ', ' '); // 半角スペースから全角スペースへの置換 var text = string.Format("{0,3}.{1} {2}", move_text_game_ply, move_text, $"{t.Hours:D2}:{t.Minutes:D2}:{t.Seconds:D2}"); KifuList.Add(text); RaisePropertyChanged("KifuList", KifuList, KifuList.Count - 1 /*末尾が変更になった*/); } if (EnableUsiMoveList) { // special moveは、USIとしては規定されていない指し手になるのでここでは出力しない。 // ("position"コマンドで送信してしまいかねないので) if (!m.IsSpecial()) { UsiMoveList.Add(m.ToUsi()); } } }
/// <summary> /// 現在のnode以降のKifuList,kifuWindowMovesを削除 /// </summary> public void ClearKifuForward() { if (KifuList.Count - 1 > pliesFromRoot) { KifuList.RemoveRange(pliesFromRoot + 1, KifuList.Count - (pliesFromRoot + 1)); kifuWindowMoves.RemoveRange(pliesFromRoot, kifuWindowMoves.Count - pliesFromRoot); } }
/// <summary> /// UndoMove()のときに棋譜を1行取り除く。 /// </summary> private void RemoveKifu(bool isSpecialMove = false) { if (EnableKifuList) { KifuList.RemoveAt(KifuList.Count - 1); // RemoveLast() RaisePropertyChanged("KifuList", KifuList, KifuList.Count /*末尾が削除になった*/); } // UsiMoveListにはspecial moveは含まれていないので、取り除くことは出来ない。 if (EnableUsiMoveList && !isSpecialMove) { UsiMoveList.RemoveAt(UsiMoveList.Count - 1); // RemoveLast() } }
/// <summary> /// UndoMove()のときに棋譜を1行取り除く。 /// </summary> private void RemoveKifu() { if (EnableKifuList) { // rootNodeからの指し手。これは棋譜リストと同期させている。 kifuWindowMoves.RemoveAt(kifuWindowMoves.Count - 1); // 棋譜ウィンドウに表示する用の文字列 KifuList.RemoveAt(KifuList.Count - 1); RaisePropertyChanged("KifuListRemoved", null /*末尾が削除になった*/); } if (EnableUsiMoveList) { UsiMoveList.RemoveAt(UsiMoveList.Count - 1); // RemoveLast() } }
/// <summary> /// DoMove()のときに棋譜に追加する /// </summary> /// <param name="m"></param> private void AddKifu(KifuMove move, TimeSpan t) { var m = move.nextMove; if (EnableKifuList) { // rootNodeからの指し手。これは棋譜リストと同期させている。 kifuWindowMoves.Add(move); // -- 棋譜をappendする // 分岐棋譜であれば、先頭に"+"を付与。 // ただし、本譜の手順でなければ"*"を付与。 char plus; if (currentNode.moves.Count != 1) { // 本譜の手順なら'+',本譜以外の手順であれば'*' // ちなみに「本譜」ボタンを押した時、 // 棋譜の先頭から最初の'*'のあるところまで戻って、そこを'+'にする。 plus = currentNode.moves[0].nextMove == m ? '+' : '*'; if (plus == '*') // 本譜ではないところを選んでいる { // 最初の分岐であるか。 if (KifuBranch == -1 || (KifuList.Count < KifuBranch)) { KifuBranch = KifuList.Count; } } else if (plus == '+') { // 本譜の手順に変わったので分岐ではない。 if (KifuBranch == KifuList.Count) { KifuBranch = -1; } } } else { plus = ' '; } // 分岐棋譜の場合、分岐以降はインデントを入れる。 var indent = ""; if (KifuBranch != -1 && KifuBranch <= KifuList.Count) { indent = ">"; } var move_text = move_to_kif_string(position, m); var move_text_game_ply = position.gamePly; // 消費時間の文字列「1秒」のように短めの文字列で表現。 // 一番上の桁は、そのあとのPadMidUnicode()でpaddingされるので、PadLeft的なpaddingはしないでおく。 string time_string; if (t.TotalSeconds < 60) { time_string = $"{t.Seconds}秒"; } else if (t.TotalMinutes < 60) { time_string = $"{t.Minutes}分{t.Seconds,2}秒"; } else if (t.TotalHours < 24) { time_string = $"{t.Hours}時間{t.Minutes,2}分{t.Seconds,2}秒"; } else { time_string = $"{t.Days}日{t.Hours,2}時間{t.Minutes,2}分{t.Seconds,2}秒"; } var move_time = move_text.PadMidUnicode(time_string, 12 /*指し手=最大全角6文字=半角12文字*/ + 1 /* space */ + 7 /*時間文字列、1分00秒で半角7文字*/); var text = $"{indent}{plus}{move_text_game_ply, 3}.{move_time}"; KifuList.Add(text); RaisePropertyChanged("KifuListAdded", text /*末尾が変更になった。変更になった行を送る。*/); } if (EnableUsiMoveList) { // special moveは、USIとしては規定されていない指し手になるのでここでは出力しない。 // ("position"コマンドで送信してしまいかねないので) // ただし削除処理がややこしくなるのは嫌なので要素は一つ増やしておく。 UsiMoveList.Add(!m.IsSpecial() ? m.ToUsi() : string.Empty); } }
/// <summary> /// DoMove()のときに棋譜に追加する /// </summary> /// <param name="m"></param> private void AddKifu(KifuMove move, TimeSpan t) { var m = move.nextMove; if (EnableKifuList) { // rootNodeからの指し手。これは棋譜リストと同期させている。 kifuWindowMoves.Add(move); // -- 棋譜をappendする // 分岐棋譜であれば、先頭に"+"を付与。 // ただし、本譜の手順でなければ"*"を付与。 char plus; if (currentNode.moves.Count != 1) { // 本譜の手順なら'+',本譜以外の手順であれば'*' // ちなみに「本譜」ボタンを押した時、 // 棋譜の先頭から最初の'*'のあるところまで戻って、そこを'+'にする。 plus = currentNode.moves[0].nextMove == m ? '+' : '*'; if (plus == '*') // 本譜ではないところを選んでいる { // 最初の分岐であるか。 if (KifuBranch == -1 || (KifuList.Count < KifuBranch)) { KifuBranch = KifuList.Count; } } else if (plus == '+') { // 本譜の手順に変わったので分岐ではない。 if (KifuBranch == KifuList.Count) { KifuBranch = -1; } } } else { plus = ' '; } // 分岐棋譜の場合、分岐以降はインデントを入れる。 var indent = ""; if (KifuBranch != -1 && KifuBranch <= KifuList.Count) { indent = ">"; } var move_text = move_to_kif_string(position, m); var move_text_game_ply = position.gamePly; // 消費時間の文字列「1秒」のように短めの文字列で表現。 // 一番上の桁は、そのあとのPadMidUnicode()でpaddingされるので、PadLeft的なpaddingはしないでおく。 string time_string; if (t.TotalSeconds < 60) { time_string = $"{t.Seconds}秒"; } else if (t.TotalMinutes < 60) { time_string = $"{t.Minutes}分{t.Seconds,2}秒"; } else if (t.TotalHours < 24) { time_string = $"{t.Hours}時間{t.Minutes,2}分{t.Seconds,2}秒"; } else { time_string = $"{t.Days}日{t.Hours,2}時間{t.Minutes,2}分{t.Seconds,2}秒"; } var ply_text = $"{indent}{plus}{move_text_game_ply,3}"; string total_consumption_time_string = null; var kifuMoveTime = currentNode.moves.Find(x => x.nextMove == m).kifuMoveTimes; // この指し手の手番側。最後、SpecialMoveに関しては、手番側とは限らないのであとで考える。 // (先手が指す→千日手成立[ここで先手の総消費時間が出て欲しい] みたいなのもあるので) // TODO : 現状、Special Moveに対してTotalTime積んでないな。これ、時間切れのときに総消費時間わからんな…。 // あとでよく考える。 var turn = position.sideToMove; var total = kifuMoveTime.Player(turn).TotalTime; // D2だと99時間までなのでそれを超える場合は、桁のある限り。 total_consumption_time_string = total.TotalHours >= 100 ? $"{(int)total.TotalHours}:{total.Minutes,2:D2}:{total.Seconds,2:D2}" : $"{(int)total.TotalHours,2:D2}:{total.Minutes,2:D2}:{total.Seconds,2:D2}"; var row = new KifuListRow(ply_text, move_text, time_string, total_consumption_time_string); KifuList.Add(row); RaisePropertyChanged("KifuListAdded", row /*末尾が変更になった。変更になった行を送る。*/); // -- この内容をLastKifuStringに反映させる。 // special moveは除外 if (m.IsOk()) { var kifu_version = TheApp.app.Config.KifuWindowKifuVersion; switch (kifu_version) { // 同じ形式なので棋譜ウィンドウに表示しているものをそのまま代入しておけば良い。 case 0: LastKifuString = move_text; break; case 1: case 2: case 3: LastKifuString = KifFormatter.Ki2C.format(position, m); break; default: Debug.Assert(false); break; } } } if (EnableUsiMoveList) { // special moveは、USIとしては規定されていない指し手になるのでここでは出力しない。 // ("position"コマンドで送信してしまいかねないので) // ただし削除処理がややこしくなるのは嫌なので要素は一つ増やしておく。 UsiMoveList.Add(!m.IsSpecial() ? m.ToUsi() : string.Empty); } }