diff --git a/TTTConsole/Plugin.cs b/TTTConsole/Plugin.cs
new file mode 100644
index 0000000..ba01a07
--- /dev/null
+++ b/TTTConsole/Plugin.cs
@@ -0,0 +1,74 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Runtime.InteropServices;
+
+namespace TTT {
+
+ class Plugin {
+
+ // DLLの動的読み込みに必要なWin32API関数
+ [DllImport("kernel32.dll", SetLastError = true)]
+ public static extern IntPtr LoadLibrary(string lib);
+ [DllImport("kernel32.dll", SetLastError = true)]
+ public static extern void FreeLibrary(IntPtr module);
+ [DllImport("kernel32.dll", SetLastError = true)]
+ public static extern IntPtr GetProcAddress(IntPtr module, string proc);
+
+ private delegate void GetNameDelegate(StringBuilder s, Int32 bufsize);
+ private delegate bool IsHumanDelegate();
+ public delegate int MyTurnDelegate(IntPtr board);
+ public string Name { get; private set; }
+ public bool IsHuman { get; private set; }
+ public MyTurnDelegate MyTurn { get; private set; }
+
+ private IntPtr _module;
+
+ ///
+ /// コンストラクタ
+ ///
+ public Plugin() {
+ _module = IntPtr.Zero;
+ }
+
+ ///
+ /// デストラクタ
+ ///
+ ~Plugin() {
+ if (_module != IntPtr.Zero) FreeLibrary(_module);
+ }
+
+ ///
+ /// プラグインの読み込み
+ ///
+ /// プラグインDLLファイル名
+ /// 読み込みの成否
+ public bool Load(string filename) {
+ var module = LoadLibrary(filename);
+ if (module == IntPtr.Zero) return false;
+
+ // 名前の取得
+ IntPtr method = GetProcAddress(module, "GetName");
+ if (method == IntPtr.Zero) return false;
+ var GetName = (GetNameDelegate)Marshal.GetDelegateForFunctionPointer(method, typeof(GetNameDelegate));
+ System.Text.StringBuilder sb = new System.Text.StringBuilder(256);
+ GetName(sb, sb.Capacity);
+ Name = sb.ToString();
+
+ // 人間かどうかの取得
+ method = GetProcAddress(module, "IsHuman");
+ if (method == IntPtr.Zero) return false;
+ var isHumanFunc = (IsHumanDelegate)Marshal.GetDelegateForFunctionPointer(method, typeof(IsHumanDelegate));
+ IsHuman = isHumanFunc();
+
+ // 思考関数ポインタの取得
+ method = GetProcAddress(module, "MyTurn");
+ if (method == IntPtr.Zero) return false;
+ MyTurn = (MyTurnDelegate)Marshal.GetDelegateForFunctionPointer(method, typeof(MyTurnDelegate));
+
+ return true;
+ }
+ }
+}
diff --git a/TTTConsole/Program.cs b/TTTConsole/Program.cs
index 597acd0..f4e5264 100644
--- a/TTTConsole/Program.cs
+++ b/TTTConsole/Program.cs
@@ -3,28 +3,16 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
-using System.Runtime.InteropServices;
using TTT;
namespace TTTConsole {
class Program {
- [DllImport("kernel32.dll", SetLastError = true)]
- public static extern IntPtr LoadLibrary(string lib);
- [DllImport("kernel32.dll", SetLastError = true)]
- public static extern void FreeLibrary(IntPtr module);
- [DllImport("kernel32.dll", SetLastError = true)]
- public static extern IntPtr GetProcAddress(IntPtr module, string proc);
-
- private delegate void GetNameDelegate(StringBuilder s, Int32 bufsize);
- private delegate bool IsHumanDelegate();
- private delegate int MyTurnDelegate(IntPtr board);
-
static string[] PLAYER_STR = new string[] { "", "先手", "後手" };
static string[] PLAYER_MARK = new string[] { " ", "○", "×" };
- static List names = new List();
static int[] thinkers;
+ static List plugins;
static bool showNumber = false;
///
@@ -41,68 +29,25 @@
// プラグインDLLを開く
var pluginFiles = new List() { "TPIHuman.dll", "TPIRandom.dll" };
- var modules = new List();
- var GetName = new List();
- var IsHuman = new List();
- var MyTurn = new List();
-
+ plugins = new List();
foreach (var file in pluginFiles) {
- var module = LoadLibrary(file);
- if (module == IntPtr.Zero) // error handling
- {
- Console.WriteLine($"Could not load library: {Marshal.GetLastWin32Error()}");
- continue;
- }
-
- IntPtr method = GetProcAddress(module, "GetName");
- if (method == IntPtr.Zero) // error handling
- {
- Console.WriteLine($"Could not load 'GetName' method: {Marshal.GetLastWin32Error()}");
- FreeLibrary(module); // unload library
- continue;
- }
- GetName.Add((GetNameDelegate)Marshal.GetDelegateForFunctionPointer(method, typeof(GetNameDelegate)));
-
- method = GetProcAddress(module, "IsHuman");
- if (method == IntPtr.Zero) // error handling
- {
- Console.WriteLine($"Could not load 'IsHuman' method: {Marshal.GetLastWin32Error()}");
- FreeLibrary(module); // unload library
- continue;
- }
- IsHuman.Add((IsHumanDelegate)Marshal.GetDelegateForFunctionPointer(method, typeof(IsHumanDelegate)));
-
- method = GetProcAddress(module, "MyTurn");
- if (method == IntPtr.Zero) // error handling
- {
- Console.WriteLine($"Could not load 'MyTurn' method: {Marshal.GetLastWin32Error()}");
- FreeLibrary(module); // unload library
- continue;
- }
- MyTurn.Add((MyTurnDelegate)Marshal.GetDelegateForFunctionPointer(method, typeof(MyTurnDelegate)));
-
- modules.Add(module);
- }
-
- // プラグイン名の取得
- System.Text.StringBuilder sb = new System.Text.StringBuilder(256);
- foreach (var gn in GetName) {
- gn(sb, sb.Capacity);
- names.Add(sb.ToString());
+ 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 < names.Count; i++) {
- Console.WriteLine($"({i + 1}) {names[i]}");
+ 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] > names.Count) return;
+ if (thinkers[pl] < 1 || thinkers[pl] > plugins.Count) return;
--thinkers[pl];
}
@@ -117,9 +62,9 @@
ShowBoard(ttt);
Console.Write($"{PlayerStr(ttt.Player)} の番");
- if (IsHuman[thinkers[(int)ttt.Player - 1]]()) Console.WriteLine("");
- ttt.Set(MyTurn[thinkers[(int)ttt.Player - 1]](ttt.GetBoard()));
- if (IsHuman[thinkers[(int)ttt.Player - 1]]()) Console.WriteLine($" --> {ttt.LastSet + 1}");
+ 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);
@@ -147,7 +92,6 @@
// 終了
Console.Write("Press [Enter] to exit.");
Console.ReadLine();
- foreach (var module in modules) FreeLibrary(module);
}
///
@@ -183,7 +127,7 @@
/// プレイヤー
/// 表示文字列
static string PlayerStr(PLAYER p) {
- return $"{PLAYER_STR[(int)p]}({names[thinkers[(int)p - 1]]})";
+ return $"{PLAYER_STR[(int)p]}({plugins[thinkers[(int)p - 1]].Name})";
}
}
}
diff --git a/TTTConsole/TTTConsole.csproj b/TTTConsole/TTTConsole.csproj
index fd608e5..4b4bf99 100644
--- a/TTTConsole/TTTConsole.csproj
+++ b/TTTConsole/TTTConsole.csproj
@@ -63,6 +63,7 @@
+