/// <summary> /// 指し手の作成。 /// </summary> /// <returns>ハンドル。0~11。</returns> public static int MakeMove() { var rand = new Random(); // 0~11。 int handle; while (true) { handle = rand.Next(12); // 3手続けて同じ個所を回すのは、逆回りに1回回すのと同じなので、そのような手は除外する。 if (Record.Ply > 2 && handle == Record.GetMove(Record.Ply - 1) && handle == Record.GetMove(Record.Ply - 2)) { Trace.WriteLine(string.Format(CultureInfo.CurrentCulture, "Info: 3連続同じ手は除外。")); // リトライ。 continue; } // 1つ前の手を、すぐ元に戻してしまう手は除外する。 if (Record.Ply > 0 && handle == MoveHelper.GetReversedHandle(Record.GetMove(Record.Ply - 1))) { Trace.WriteLine(string.Format(CultureInfo.CurrentCulture, "Info: 戻す手は除外。")); // リトライ。 continue; } // 正常終了。 break; } return(handle); }
/// <summary> /// 検査フェーズ。 /// </summary> private void Inspector() { // 定跡を適当に選ぶ。 (var currentPositionText, var bookRow) = Book.RandomRow; while (true) { // ハンドルと、局面の前後 が有っているか確認する。 var position = Position.Parse(currentPositionText); // 1手戻す。 var reversedHandle = MoveHelper.GetReversedHandle(bookRow.Handle); position.RotateOnly(reversedHandle); if (bookRow.PreviousBoardText != position.BoardText) { // エラー。 var message = string.Format( CultureInfo.CurrentCulture, "検査: 行削除。ハンドルと、局面の前後が不一致。 Current: '{0}', Handle: '{1}', ReversedHandle: '{2}', Expected previous: '{3}', Actual previous: '{4}'.", currentPositionText, bookRow.Handle, reversedHandle, bookRow.PreviousBoardText, position.BoardText); Trace.WriteLine(message); // データを消す。 Book.Remove(currentPositionText); } // 初期局面に たどり着いたら 抜ける。 if (bookRow.PreviousBoardText == Position.StartPosition) { Trace.WriteLine("検査良好。"); break; } // 1つ前の局面。 if (!Book.ContainsKey(bookRow.PreviousBoardText)) { // 無い場合、間違ったデータだったので消されたか、間引きされたか。 // 別のルートでつながるなど、使い道はあるかもしれない。 // とりあえずループを抜ける。 var message = string.Format( CultureInfo.CurrentCulture, "検査: 無視。前局面に遡れない定跡。 Actual previous: '{0}'.", bookRow.PreviousBoardText); Trace.WriteLine(message); break; } // 巻き戻し。 currentPositionText = bookRow.PreviousBoardText; bookRow = Book.GetValue(currentPositionText); } this.phase = 0; }