public Kyokumen(Kyokumen kyokumen, string usimove) { bammen = new Koma[9, 9]; s_mochi = new int[7]; g_mochi = new int[7]; teban = kyokumen.teban; Array.Copy(kyokumen.bammen, bammen, kyokumen.bammen.Length); Array.Copy(kyokumen.s_mochi, s_mochi, kyokumen.s_mochi.Length); Array.Copy(kyokumen.g_mochi, g_mochi, kyokumen.g_mochi.Length); proceed(usimove); }
static bool CheckRepetition(Kyokumen kyokumen, List <Kyokumen> history) { int count = 0; foreach (Kyokumen his in history) { if (kyokumen == his) { count++; } } return(count >= 3); }
public static Result match(string matchname, uint byoyomi, Player b, Player w, string startusi = "startpos", string kifupath = @"./kifu.txt") //開始局面のusiはsfen部分から { while (true) { using (Process sente = new Process()) using (Process gote = new Process()) { try { Console.Write($"waiting setup {b.name}..."); b.Start(sente); Console.WriteLine(" readyok."); Console.Write($"waiting setup {w.name}..."); w.Start(gote); Console.WriteLine(" readyok."); List <string> kifu = new List <string>(); List <int> evals = new List <int>(); int startmove = 1; List <Kyokumen> history = new List <Kyokumen>(); string go = $"go btime 0 wtime 0 byoyomi {byoyomi}"; var starttime = DateTime.Now; string startsfen = "startpos"; if (startusi != "startpos") { string[] tokens = startusi.Split(' ', StringSplitOptions.RemoveEmptyEntries); if (tokens[0] != "startpos") { throw new NotImplementedException(); } else { history.Add(new Kyokumen()); for (int i = 2; i < tokens.Length; i++) { kifu.Add(tokens[i]); history.Add(new Kyokumen(history[history.Count - 1], tokens[i])); } startmove = history.Count; } } else { history.Add(new Kyokumen()); } Console.WriteLine($"start at {startusi}"); Console.Write($"{starttime.ToString(Kifu.TimeFormat)} {matchname}:"); while (true) { if (kifu.Count % 2 == 0) //先手 { var(move, eval) = GetMove(sente, position(startsfen, kifu), go); kifu.Add(move); evals.Add(eval); Console.Write($" b:{move}({eval})"); if (move == "resign") { Result result = Result.GoteWin; Kifu.FoutKifu(starttime, matchname, b, w, byoyomi, kifu, startmove, evals, result, kifupath); sendGameOver(sente, gote, result); return(result); } else if (move == "win") { Result result = Result.SenteWin; Kifu.FoutKifu(starttime, matchname, b, w, byoyomi, kifu, startmove, evals, result, kifupath); sendGameOver(sente, gote, result); return(result); } var nextKyokumen = new Kyokumen(history[history.Count - 1], move); if (CheckRepetition(nextKyokumen, history)) { Result result = Result.Repetition; Kifu.FoutKifu(starttime, matchname, b, w, byoyomi, kifu, startmove, evals, result, kifupath); sendGameOver(sente, gote, result); return(result); } if (CheckEndless(history.Count)) { Result result = Result.Draw; Kifu.FoutKifu(starttime, matchname, b, w, byoyomi, kifu, startmove, evals, result, kifupath); sendGameOver(sente, gote, result); return(result); } history.Add(nextKyokumen); } else //後手 { var(move, eval) = GetMove(gote, position(startsfen, kifu), go); kifu.Add(move); evals.Add(-eval); Console.Write($" w:{move}({-eval})"); if (move == "resign") { Result result = Result.SenteWin; Kifu.FoutKifu(starttime, matchname, b, w, byoyomi, kifu, startmove, evals, result, kifupath); sendGameOver(sente, gote, result); return(result); } else if (move == "win") { Result result = Result.GoteWin; Kifu.FoutKifu(starttime, matchname, b, w, byoyomi, kifu, startmove, evals, result, kifupath); sendGameOver(sente, gote, result); return(result); } var nextKyokumen = new Kyokumen(history[history.Count - 1], move); if (CheckRepetition(nextKyokumen, history)) { Result result = Result.Repetition; Kifu.FoutKifu(starttime, matchname, b, w, byoyomi, kifu, startmove, evals, result, kifupath); sendGameOver(sente, gote, result); return(result); } if (CheckEndless(history.Count)) { Result result = Result.Draw; Kifu.FoutKifu(starttime, matchname, b, w, byoyomi, kifu, startmove, evals, result, kifupath); sendGameOver(sente, gote, result); return(result); } history.Add(nextKyokumen); } } } catch (Exception e) { Console.WriteLine(e); if (!sente.HasExited) { sente.StandardInput.WriteLine("quit"); } if (!gote.HasExited) { gote.StandardInput.WriteLine("quit"); } } finally { if (!sente.WaitForExit(100)) { try { sente.Kill(); } catch (Exception) { //プロセスは既に終了しているので何もしない(waitが終わってkillを呼ぶまでの一瞬の間にプロセスが終了した場合に例外が発生する) } } if (!gote.WaitForExit(100)) { try { gote.Kill(); } catch (Exception) { //プロセスは既に終了しているので何もしない } } } } } }
public static void KifulineToCSA() { Console.WriteLine("input kifu line by kifu.txt"); Console.Write(">"); string[] kifuline = Console.ReadLine().Split(':'); if (kifuline.Length != 3) { Console.WriteLine("kifu line syntax error."); return; } Console.Write("csa output filename? > "); string filename = Console.ReadLine().Split(new char[] { ' ', '.' }, StringSplitOptions.RemoveEmptyEntries)[0] + ".csa"; using (var fs = new StreamWriter(filename, false)) { fs.WriteLine("V2.2"); //対局情報 string[] info = kifuline[1].Split(' '); // <日:時> <title> (<sente> vs <gote>) <byoyomi>ms: <kifu> //対局者情報 fs.WriteLine($"N+{info[2].Trim('(')}"); fs.WriteLine($"N-{info[4].Trim(')')}"); //棋戦名 fs.WriteLine($@"$EVENT:{info[1]}"); //持ち時間 int byoyomi = int.Parse(Regex.Replace(info[5], @"[^0-9]", "")) / 1000; fs.WriteLine(@"$TIME_LIMIT:00:00+" + byoyomi.ToString()); //初期局面 fs.WriteLine("PI"); //指し手 string[] moves = kifuline[2].Split(' ', StringSplitOptions.RemoveEmptyEntries); Kyokumen kyokumen = new Kyokumen(); bool kecchaku = false; for (int i = 0; i < moves.Length; i++) { string usimove = moves[i]; if (usimove == "resign") { fs.WriteLine(@"%TORYO"); kecchaku = true; } else if (usimove == "win") { fs.WriteLine(@"%KACHI"); kecchaku = true; } else { kyokumen.proceed(usimove); fs.WriteLine(Kyokumen.usimove_to_csamove(usimove, kyokumen)); } fs.WriteLine("T" + byoyomi.ToString()); } if (!kecchaku) { if (moves.Length > Program.drawMoves) { fs.WriteLine(@"%HIKIWAKE"); } else { fs.WriteLine(@"SENNICHITE"); } } Console.WriteLine("kifu has been converted."); } }