diff --git a/TTTConsole/ConsolePlay.cs b/TTTConsole/ConsolePlay.cs new file mode 100644 index 0000000..130c68e --- /dev/null +++ b/TTTConsole/ConsolePlay.cs @@ -0,0 +1,162 @@ +using System; +using System.Collections.Generic; +using TTT; + +namespace TTTConsole { + + class ConsolePlay { + + private readonly string[] PLAYER_STR = new string[] { "", "先手", "後手" }; + private readonly string[] PLAYER_MARK = new string[] { " ", "○", "×" }; + + private TicTacToe _ttt = new TicTacToe(); + private List _plugins = new List(); + private List _player = new List(); + static bool _showNumber = false; + + /// + /// 実行 + /// + /// + public void Run(string[] pluginFiles) { + ShowTitle(); + if (!LoadPlugin(pluginFiles)) { + Console.WriteLine("プラグインがありません."); + return; + } + if (!SelectPlayer()) { + Console.WriteLine("中断します."); + return; + } + Battle(); + ShowResult(); + } + + /// + /// タイトルを表示 + /// + private void ShowTitle() { + Console.WriteLine(new string('*', 30)); + Console.WriteLine("拡張○×ゲーム"); + Console.WriteLine(new string('*', 30)); + Console.WriteLine(""); + } + + /// + /// プラグインを読み込む + /// + /// + private bool LoadPlugin(string[] files) { + foreach (var file in files) { + var plugin = new Plugin(); + if (!plugin.Load(file)) continue; + _plugins.Add(plugin); + } + return _plugins.Count > 0; + } + + /// + /// プレイヤーの選択 + /// + private bool SelectPlayer() { + Console.WriteLine("プレイヤーの選択"); + for (var pl = 0; pl < _ttt.PLAYERS; pl++) { + for (var i = 0; i < _plugins.Count; i++) { + Console.WriteLine($"({i + 1}) {_plugins[i].Name}"); + } + Console.Write($"{PLAYER_STR[pl + 1]} を選んでください: "); + var input = Console.ReadLine(); + + int selID; + if (!int.TryParse(input, out selID)) return false; + if (selID < 1 || selID > _plugins.Count) return false; + _player.Add(_plugins[selID - 1]); + } + + // 数字表示の選択 + Console.Write("○×の順番を表示しますか? 1:しない 2:する "); + _showNumber = int.Parse(Console.ReadLine()) == 2 ? true : false; + + return true; + } + + /// + /// 対戦 + /// + private void Battle() { + _ttt.Init(); + do { + Console.WriteLine(""); + ShowBoard(); + Console.Write($"{PlayerStr()} の番"); + + if (_player[(int)_ttt.Player - 1].IsHuman) Console.WriteLine(""); + _ttt.Set(_player[(int)_ttt.Player - 1].MyTurn(_ttt.GetBoard())); + if (!_player[(int)_ttt.Player - 1].IsHuman) Console.WriteLine($" --> {_ttt.LastSet + 1}"); + + } while (_ttt.Judge == JUDGE.None); + } + + /// + /// 結果表示 + /// + private void ShowResult() { + string msg = ""; + switch (_ttt.Judge) { + case JUDGE.WIN: + msg = $"{PlayerStr()} の勝利"; + break; + case JUDGE.DRAW: + msg = $"引き分け"; + break; + case JUDGE.OUT_OF_RANGE: + msg = $"{PlayerStr()} の反則負け(範囲外)"; + break; + case JUDGE.OVERLAP: + msg = $"{PlayerStr()} の反則負け(重ね置き)"; + break; + } + + Console.WriteLine(""); + Console.WriteLine(new string('*', 30)); + ShowBoard(); + Console.WriteLine(""); + Console.WriteLine(msg); + Console.WriteLine(new string('*', 30)); + } + + /// + /// 盤の表示 + /// + private void ShowBoard() { + Console.WriteLine(new string('~', 6) + $" ターン{_ttt.Turn} " + new string('~', 6)); + + var flip = _ttt.Player == PLAYER.Second ? -1 : 1; + for (var row = 0; row < _ttt.BOARD_ROWS; row++) { + Console.Write(" "); + for (var col = 0; col < _ttt.BOARD_COLS; col++) { + var pos = row * _ttt.BOARD_COLS + col; + var pIdx = _ttt.Board[pos] * flip > 0 ? PLAYER.First : + _ttt.Board[pos] * flip < 0 ? PLAYER.Second : PLAYER.None; + Console.Write(PLAYER_MARK[(int)pIdx]); + if (_showNumber) Console.Write(_ttt.Board[pos] == 0 ? " " : + string.Format("{0,2}", Math.Abs(_ttt.Board[pos]))); + if (col < _ttt.BOARD_COLS - 1) Console.Write(" | "); + } + Console.WriteLine(""); + if (row < _ttt.BOARD_ROWS - 1) { + if (_showNumber) Console.WriteLine(" -----+------+-----"); + else Console.WriteLine(" ---+----+---"); + } + } + } + + /// + /// プレイヤーの表示文字列を生成 + /// + /// 表示文字列 + private string PlayerStr() { + return $"{PLAYER_STR[(int)_ttt.Player]}({_player[(int)_ttt.Player - 1].Name})"; + } + } +} diff --git a/TTTConsole/Plugin.cs b/TTTConsole/Plugin.cs index ba01a07..9767f20 100644 --- a/TTTConsole/Plugin.cs +++ b/TTTConsole/Plugin.cs @@ -1,9 +1,6 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Runtime.InteropServices; +using System.Text; namespace TTT { diff --git a/TTTConsole/Program.cs b/TTTConsole/Program.cs index f4e5264..3f7ec66 100644 --- a/TTTConsole/Program.cs +++ b/TTTConsole/Program.cs @@ -1,133 +1,26 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using TTT; +using System.IO; namespace TTTConsole { class Program { - static string[] PLAYER_STR = new string[] { "", "先手", "後手" }; - static string[] PLAYER_MARK = new string[] { " ", "○", "×" }; - static int[] thinkers; - static List plugins; - static bool showNumber = false; - /// /// プログラム開始点 /// /// static void Main(string[] args) { - Console.WriteLine(new string('*', 30)); - Console.WriteLine("拡張○×ゲーム"); - Console.WriteLine(new string('*', 30)); - Console.WriteLine(""); - var ttt = new TicTacToe(); + // プラグインDLL取得 + var pluginFiles = Directory.GetFiles(".", "*.dll"); - // プラグインDLLを開く - var pluginFiles = new List() { "TPIHuman.dll", "TPIRandom.dll" }; - plugins = new List(); - foreach (var file in pluginFiles) { - var plugin = new Plugin(); - if (!plugin.Load(file)) continue; - plugins.Add(plugin); - } - - // プレイヤーの選択 - Console.WriteLine("プレイヤーの選択"); - thinkers = new int[ttt.PLAYERS]; - for (var pl=0; pl< ttt.PLAYERS; pl++) { - for (var i = 0; i < plugins.Count; i++) { - Console.WriteLine($"({i + 1}) {plugins[i].Name}"); - } - Console.Write($"{PLAYER_STR[pl + 1]} を選んでください: "); - var input = Console.ReadLine(); - - if (!int.TryParse(input, out thinkers[pl])) return; - if (thinkers[pl] < 1 || thinkers[pl] > plugins.Count) return; - --thinkers[pl]; - } - - // 数字表示の選択 - Console.Write("○×の順番を表示しますか? 1:しない 2:する "); - showNumber = int.Parse(Console.ReadLine()) == 2 ? true : false; - - // 対戦開始 - ttt.Init(); - do { - Console.WriteLine(""); - ShowBoard(ttt); - Console.Write($"{PlayerStr(ttt.Player)} の番"); - - if (plugins[thinkers[(int)ttt.Player - 1]].IsHuman) Console.WriteLine(""); - ttt.Set(plugins[thinkers[(int)ttt.Player - 1]].MyTurn(ttt.GetBoard())); - if (!plugins[thinkers[(int)ttt.Player - 1]].IsHuman) Console.WriteLine($" --> {ttt.LastSet + 1}"); - - } while (ttt.Judge == JUDGE.None); - - // 結果表示 - Console.WriteLine(""); - Console.WriteLine(new string('*', 30)); - ShowBoard(ttt); - Console.WriteLine(""); - switch (ttt.Judge) { - case JUDGE.WIN: - Console.WriteLine($"{PlayerStr(ttt.Winner)} の勝利"); - break; - case JUDGE.DRAW: - Console.WriteLine($"引き分け"); - break; - case JUDGE.OUT_OF_RANGE: - Console.WriteLine($"{PlayerStr(ttt.Player)} の反則負け(範囲外)"); - break; - case JUDGE.OVERLAP: - Console.WriteLine($"{PlayerStr(ttt.Player)} の反則負け(重ね置き)"); - break; - } - Console.WriteLine(new string('*', 30)); + // プレイ + var play = new ConsolePlay(); + play.Run(pluginFiles); // 終了 Console.Write("Press [Enter] to exit."); Console.ReadLine(); } - - /// - /// 盤の表示 - /// - /// - static void ShowBoard(TicTacToe ttt) { - Console.WriteLine(new string('~', 6) + $" ターン{ttt.Turn} " + new string('~', 6)); - - var flip = ttt.Player == PLAYER.Second ? -1 : 1; - for (var row = 0; row < ttt.BOARD_ROWS; row++) { - Console.Write(" "); - for (var col = 0; col < ttt.BOARD_COLS; col++) { - var pos = row * ttt.BOARD_COLS + col; - var pIdx = ttt.Board[pos] * flip > 0 ? PLAYER.First : - ttt.Board[pos] * flip < 0 ? PLAYER.Second : PLAYER.None; - Console.Write(PLAYER_MARK[(int)pIdx]); - if (showNumber) Console.Write(ttt.Board[pos] == 0 ? " " : - string.Format("{0,2}", Math.Abs(ttt.Board[pos]))); - if (col < ttt.BOARD_COLS - 1) Console.Write(" | "); - } - Console.WriteLine(""); - if (row < ttt.BOARD_ROWS - 1) { - if (showNumber) Console.WriteLine(" -----+------+-----"); - else Console.WriteLine(" ---+----+---"); - } - } - } - - /// - /// プレイヤーの表示文字列を生成 - /// - /// プレイヤー - /// 表示文字列 - static string PlayerStr(PLAYER p) { - return $"{PLAYER_STR[(int)p]}({plugins[thinkers[(int)p - 1]].Name})"; - } } } diff --git a/TTTConsole/TTTConsole.csproj b/TTTConsole/TTTConsole.csproj index 4b4bf99..bc4715f 100644 --- a/TTTConsole/TTTConsole.csproj +++ b/TTTConsole/TTTConsole.csproj @@ -63,6 +63,7 @@ + diff --git a/TTTConsole/TicTacToe.cs b/TTTConsole/TicTacToe.cs index c49d2bf..121af9b 100644 --- a/TTTConsole/TicTacToe.cs +++ b/TTTConsole/TicTacToe.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Runtime.InteropServices; namespace TTT { @@ -23,13 +19,11 @@ public readonly int PLAYERS = 2; // プレイヤー数 public readonly int TURN_LIMIT; // ターン数上限(このターン数に至ると引き分け) public readonly int NONE = 0; // 空のマス - //public readonly int[] SIGN; // プレイヤーの符号 public readonly int[,] LINES; // 並べる線の情報 public int[] Board { get; private set; } // 盤 0:空 正:先手駒 負:後手駒 public int Turn { get; private set; } // ターン数 public PLAYER Player { get; private set; } // 手を挿すプレイヤー 1:先手 2:後手 - public PLAYER Winner { get; set; } // 勝者 0:なし 1:先手 2:後手 public JUDGE Judge { get; private set; } // ゲーム終了の判定 public int LastSet { get; private set; } // 直前に置いた場所 private IntPtr _board; // アンマネージドメモリの盤データ @@ -41,7 +35,6 @@ public TicTacToe(int turnLimit = 100) { TURN_LIMIT = turnLimit; Board = new int[BOARD_SIZE]; - //SIGN = new int[] { 0, 1, -1 }; LINES = new int[8, 3]{ { 0, 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 }, { 0, 3, 6 }, { 1, 4, 7 }, { 2, 5, 8 }, { 0, 4, 8 }, { 2, 4, 6 } }; _board = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(int)) * BOARD_SIZE); @@ -61,7 +54,6 @@ for (var i = 0; i < BOARD_SIZE; i++) Board[i] = NONE; Turn = 1; Player = PLAYER.First; - Winner = PLAYER.None; Judge = JUDGE.None; } @@ -80,7 +72,6 @@ // 反則(重ね置き)チェック if (Board[pos] != 0) { - Winner = Player == PLAYER.First ? PLAYER.Second : PLAYER.First; Judge = JUDGE.OVERLAP; return; } @@ -96,7 +87,6 @@ // 勝利判定 for (var i = 0; i < LINES.GetLength(0); i++) { if (Board[LINES[i, 0]] > 0 && Board[LINES[i, 1]] > 0 && Board[LINES[i, 2]] > 0) { - Winner = Player; Judge = JUDGE.WIN; return; }