/// <summary> /// セーブファイルを読み込み、局面を復元します。 /// </summary> /// <param name="taikyoku"></param> /// <param name="boardSize">19路盤なら19、9路盤なら9と入れてください。</param> public static void Load(out Taikyoku taikyoku, int boardSize) { BoardPrinterB boardPrinterB; switch (boardSize) { case 9: boardPrinterB = new N9zibanPrinterImpl(); break; default: boardPrinterB = new N19zibanPrinterImpl(); break; } taikyoku = new TaikyokuImpl( boardSize, new ComputerPlayerBImpl(), new BoardImpl(boardSize), new MarkingBoardImpl(boardSize), new CountedBoardImpl(boardSize), boardPrinterB ); string gnugoDatText = File.ReadAllText(taikyoku.SaveFileName); // 盤設定を読み込みます。 for (int i = 0; i < taikyoku.GobanBounds.BoardSize; i++) { for (int j = 0; j < taikyoku.GobanBounds.BoardSize; j++) { taikyoku.Goban.Put(new GobanPointImpl(i, j), Conv_StoneColor.FromNumber(int.Parse(gnugoDatText.Substring(0, 1)))); gnugoDatText = gnugoDatText.Substring(1); //fscanf(fp, "%c", ref ; } } // コンピューターの色、取ったピースズを読み込みます。 int ix; ix = gnugoDatText.IndexOf(" "); taikyoku.MyColor = Conv_StoneColor.FromNumber(int.Parse(gnugoDatText.Substring(0, ix))); gnugoDatText = gnugoDatText.Substring(ix + 1//空白の次へ ); ix = gnugoDatText.IndexOf(" "); taikyoku.Count_MyCaptured = int.Parse(gnugoDatText.Substring(0, ix)); gnugoDatText = gnugoDatText.Substring(ix + 1); ix = gnugoDatText.IndexOf(" "); taikyoku.Count_YourCaptured = int.Parse(gnugoDatText.Substring(0, ix)); gnugoDatText = gnugoDatText.Substring(ix + 1); //fscanf(fp, "%d %d %d ", ref Util_GlobalVar.Mymove, // ref Util_GlobalVar.Mk, ref Util_GlobalVar.Uk); // 序盤定跡フラグを読み込みます。 for (int index = 0; index < 9; index++) { ix = gnugoDatText.IndexOf(" "); taikyoku.OpeningZyosekiFlag[index] = int.Parse(gnugoDatText.Substring(0, ix)) != 0; gnugoDatText = gnugoDatText.Substring(ix + 1); //fscanf(fp, "%d ", ref Util_GlobalVar.Opn[i]); } //fclose(fp); taikyoku.YourColor = Conv_StoneColor.FromNumber(3 - (int)taikyoku.MyColor); }
/// <summary> /// C#あれんじ GNUの碁1.2 のメイン・プログラム /// /// Gnugo1.2 では、main.c の main関数。 /// </summary> /// <param name="args"></param> /// <returns></returns> static int Main(string[] args) { bool isContinueGame = false;// Gnugo1.2 では、cont という変数名。continueの略か。 // タイトル画面 new Scene_01_TitleImpl().DoScene(); // 操作説明画面 new Scene_02_InstructionImpl().DoScene(); Taikyoku taikyoku; if (File.Exists(TaikyokuImpl.SAVE_FILE_NAME_19ZIBAN)) { // セーブファイルが作られていれば、古いゲームを続けます。 //---------------------------------------- // 19路盤のゲームを再開 //---------------------------------------- isContinueGame = true; // 古い対局データの読み込み Util_Load.Load(out taikyoku, 19); // ファイルを削除します。 File.Delete(TaikyokuImpl.SAVE_FILE_NAME_19ZIBAN); } else if (File.Exists(TaikyokuImpl.SAVE_FILE_NAME_9ZIBAN)) { // セーブファイルが作られていれば、古いゲームを続けます。 //---------------------------------------- // 9路盤のゲームを再開 //---------------------------------------- isContinueGame = true; // 古い対局データの読み込み Util_Load.Load(out taikyoku, 9); // ファイルを削除します。 File.Delete(TaikyokuImpl.SAVE_FILE_NAME_9ZIBAN); } else { //---------------------------------------- // 9路盤 or 19路盤の選択 //---------------------------------------- { // 盤のサイズが決まっていないうちは、対局データを初期設定できません。 Scene_03_BoardSizeImpl scene_03 = new Scene_03_BoardSizeImpl(); scene_03.DoScene(); // TODO: 盤サイズ(仮)。 盤サイズを指定してから決めたい。暫定で、19路盤サイズとします。 int boardSize_temp = scene_03.BoardSize; BoardPrinterB boardPrinterB; switch (boardSize_temp) { case 9: boardPrinterB = new N9zibanPrinterImpl(); break; default: boardPrinterB = new N19zibanPrinterImpl(); break; } // C#化にあたって、グローバル変数はこちらに移動しました。 taikyoku = new TaikyokuImpl( boardSize_temp, new ComputerPlayerBImpl(), new BoardImpl(boardSize_temp), new MarkingBoardImpl(boardSize_temp), new CountedBoardImpl(boardSize_temp), boardPrinterB ); taikyoku.GobanBounds.BoardSize = scene_03.BoardSize; switch (taikyoku.GobanBounds.BoardSize) { case 9: { taikyoku.BoardPrinter = new N9zibanPrinterImpl(); } break; default: { taikyoku.BoardPrinter = new N19zibanPrinterImpl(); } break; } } // ハンディーキャップを選択したところで、ゲーム盤を表示します。 ((BoardPrinterB)taikyoku.BoardPrinter).ShowBoard(taikyoku); // 序盤定跡フラグを ON にします。 for (int index = 0; index < 9; index++) { taikyoku.OpeningZyosekiFlag[index] = true; } taikyoku.OpeningZyosekiFlag[4] = false;// [4]のフラグだけ OFF にします。 if (taikyoku.GobanBounds.BoardSize == 9) { // 序盤定石のほとんどは、19路盤専用です。 taikyoku.OpeningZyosekiFlag[1] = false; taikyoku.OpeningZyosekiFlag[2] = false; taikyoku.OpeningZyosekiFlag[3] = false; taikyoku.OpeningZyosekiFlag[5] = false; taikyoku.OpeningZyosekiFlag[6] = false; taikyoku.OpeningZyosekiFlag[7] = false; taikyoku.OpeningZyosekiFlag[8] = false; } // 盤上の石を全て取り払います。 for (int i = 0; i < taikyoku.GobanBounds.BoardSize; i++) { for (int j = 0; j < taikyoku.GobanBounds.BoardSize; j++) { taikyoku.Goban.Put(new GobanPointImpl(i, j), StoneColor.Empty); } } // お互いの取られた石数もクリアーします。 taikyoku.Count_MyCaptured = 0; taikyoku.Count_YourCaptured = 0; } taikyoku.PlayState = GameState.Playing; //ゲーム開始 taikyoku.Pass = 0; //パス0回 taikyoku.MyKo.MoveToVanish(); // お互いの取った石(コウになるかもしれない)の位置をクリアー taikyoku.YourKo.MoveToVanish(); taikyoku.Random = new Random( //0 // 毎回同じランダム値を出すには、種を固定します。 DateTime.Now.Millisecond // 毎回ランダムにするには、種を時刻などによって変更します。 ); if (!isContinueGame) // 新ゲーム { //---------------------------------------- // ハンディーキャップの選択 //---------------------------------------- Scene_04_HandicapImpl scene_04 = new Scene_04_HandicapImpl(); scene_04.DoScene(taikyoku); //---------------------------------------- // 色の選択 //---------------------------------------- for (; ;) //無限ループ { // 色を尋ねます。 Console.Write("\nChoose side(b or w)? "); string command_str = Console.ReadLine(); //scanf("%c",ans); if (command_str.StartsWith("b")) { //---------------------------------------- // 人間が黒手番(先手)を選んだとき //---------------------------------------- taikyoku.MyColor = StoneColor.White; // コンピューターが白 taikyoku.YourColor = StoneColor.Black; // 人間が黒 if (scene_04.Handicap != 0) { // 人間がハンディキャップを取ったときは、 // 初手として、コンピューターが石を置きます。 GobanPoint bestMove; Util_BestMove.Generate_BestMove(out bestMove, taikyoku); taikyoku.Goban.Put(bestMove, taikyoku.MyColor); } break; } else if (command_str.StartsWith("w")) { //---------------------------------------- // 人間が白手番(後手)を選んだとき //---------------------------------------- taikyoku.MyColor = StoneColor.Black; // コンピューターが黒 taikyoku.YourColor = StoneColor.White; // コンピューターが白 if (scene_04.Handicap == 0) { // 人間がハンディキャップを取らないときは、 // 初手として、コンピューターが石を置きます。 GobanPoint bestMove; Util_BestMove.Generate_BestMove(out bestMove, taikyoku); taikyoku.Goban.Put(bestMove, taikyoku.MyColor); } // 人間がハンディキャップを取っているときは、コンピューターは初手の石を置かず、 // 人間の手番から始まります。 break; } // それ以外の入力は、無限ループ } } // 人間の先後番を選んだところで、碁番を再表示します。 ((BoardPrinterB)taikyoku.BoardPrinter).ShowBoard(taikyoku); // メインループ while (0 < taikyoku.PlayState) { // 人間側の指し手を入力してください。 // 列を示すアルファベットに続いて、行を示す番号を入力してください。 Console.Write("your move? "); // Gnugo1.2 では、move配列。コマンドラインから サイズ10のchar型配列に入れていたが、C#化にあたり、やり方を変えた。 string command_str = Console.ReadLine(); //scanf("%s", move); GobanPoint yourLocation; // 人間の指し手 Util_CommandDriven.DoCommand(command_str, out yourLocation, taikyoku); // 人間の指し手を読込 if (GameState.Playing == taikyoku.PlayState) { if (!yourLocation.IsPass()) // パスでないなら { // 碁番に石を置きます。 taikyoku.Goban.Put(yourLocation, taikyoku.YourColor); // コンピューター側の囲われた石を削除します。コウにならないか、注意します。 Util_RemoveStones_Surrounded.RemoveStones_Surrounded(taikyoku.MyColor, taikyoku); } if (taikyoku.Pass != 2) { GobanPoint myLocation; // コンピューターの指し手 Util_BestMove.Generate_BestMove(out myLocation, taikyoku); if (!myLocation.IsPass()) // パスでなければ { // 碁番に石を置きます。 taikyoku.Goban.Put(myLocation, taikyoku.MyColor); // 人間側の囲われた石を削除します。コウにならないか、注意します。 Util_RemoveStones_Surrounded.RemoveStones_Surrounded(taikyoku.YourColor, taikyoku); } } ((BoardPrinterB)taikyoku.BoardPrinter).ShowBoard(taikyoku); } if (taikyoku.Pass == 2) { taikyoku.PlayState = GameState.Stop; // お互いがパスをしたら、ゲーム終了です。 } } if (taikyoku.PlayState == GameState.Stop) { // ゲームを終了します。 // 負けがわかっている人向けにか、結果画面は飛ばすことができます。 //getchar(); Console.Write("Do you want to count score (y or n)? "); string command_str = Console.ReadLine(); //scanf("%c",ans); if (command_str.StartsWith("y")) { new Scene_99_EndOfGameImpl().DoScene(taikyoku); } } // アプリケーションを正常終了します。 return(0); }