diff --git a/Random/Random.vcxproj b/Random/Random.vcxproj new file mode 100644 index 0000000..5ff5378 --- /dev/null +++ b/Random/Random.vcxproj @@ -0,0 +1,157 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {e94d271e-a8ba-45af-9531-02ca7d6035b7} + Random + 10.0 + TPIRandom + + + + Application + true + v142 + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + copy $(TargetPath) $(SolutionDir)TTTConsole\bin\$(PlatformTarget)\$(Configuration)\ + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + copy $(TargetPath) $(SolutionDir)TTTConsole\bin\$(PlatformTarget)\$(Configuration)\ + + + + + + + + + + + + \ No newline at end of file diff --git a/Random/Random.vcxproj.filters b/Random/Random.vcxproj.filters new file mode 100644 index 0000000..d11374d --- /dev/null +++ b/Random/Random.vcxproj.filters @@ -0,0 +1,27 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + ヘッダー ファイル + + + + + ソース ファイル + + + \ No newline at end of file diff --git a/Random/TTTPlugin.h b/Random/TTTPlugin.h new file mode 100644 index 0000000..dcdc8af --- /dev/null +++ b/Random/TTTPlugin.h @@ -0,0 +1,11 @@ +#pragma once + +const int BOARD_SIZE = 9; + +extern "C" +{ + // 既定の関数 + __declspec(dllexport) bool IsHuman(); + __declspec(dllexport) void GetName(char* buf, size_t bufsize); + __declspec(dllexport) int MyTurn(int* board, int turn, int player); +} diff --git a/Random/random.cpp b/Random/random.cpp new file mode 100644 index 0000000..9916f4f --- /dev/null +++ b/Random/random.cpp @@ -0,0 +1,38 @@ +#include "TTTPlugin.h" +#include +#include + +/// +/// 人間操作かどうかを返す +/// +/// 人間ならtrue, 機械ならfalse +bool IsHuman() { + return false; +} + +/// +/// 名前を返す +/// +/// 名前を格納する文字列 +/// 文字列バッファのサイズ +void GetName(char* buf, size_t bufsize) { + sprintf_s(buf, bufsize, "Mr.Random"); +} + +/// +/// 手を打つ +/// +/// 盤の状態 +/// ターン数 +/// 1:先手, 2:後手 +/// 置く場所 +int MyTurn(int* board, int turn, int player) { + std::random_device rnd; + + int pos; + do { + pos = rnd() % BOARD_SIZE; + } while (board[pos] != 0); + + return pos; +} diff --git a/TPIHuman/Human.cpp b/TPIHuman/Human.cpp new file mode 100644 index 0000000..7eaf828 --- /dev/null +++ b/TPIHuman/Human.cpp @@ -0,0 +1,37 @@ +#include "TTTPlugin.h" +#include + +/// +/// 人間操作かどうかを返す +/// +/// 人間ならtrue, 機械ならfalse +bool IsHuman() { + return true; +} + +/// +/// 名前を返す +/// +/// 名前を格納する文字列 +/// 文字列バッファのサイズ +void GetName(char* buf, size_t bufsize) { + sprintf_s(buf, bufsize, "人間"); +} + +/// +/// 手を打つ +/// +/// 盤の状態 +/// ターン数 +/// 1:先手, 2:後手 +/// 置く場所 +int MyTurn(int* board, int turn, int player) { + + int pos = 0; + do { + std::cout << "どこに置きますか? (1:左上 - 9:右下): "; + std::cin >> pos; + } while (pos < 1 || pos > 9 || board[pos - 1] != 0); + + return pos - 1; +} diff --git a/TPIHuman/TPIHuman.vcxproj b/TPIHuman/TPIHuman.vcxproj new file mode 100644 index 0000000..4fbce7e --- /dev/null +++ b/TPIHuman/TPIHuman.vcxproj @@ -0,0 +1,156 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {74d69a51-b6d6-4f41-956c-0adbaa10e868} + TPIHuman + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + copy $(TargetPath) $(SolutionDir)TTTConsole\bin\$(PlatformTarget)\$(Configuration)\ + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + copy $(TargetPath) $(SolutionDir)TTTConsole\bin\$(PlatformTarget)\$(Configuration)\ + + + + + + + + + + + + \ No newline at end of file diff --git a/TPIHuman/TPIHuman.vcxproj.filters b/TPIHuman/TPIHuman.vcxproj.filters new file mode 100644 index 0000000..49aebfa --- /dev/null +++ b/TPIHuman/TPIHuman.vcxproj.filters @@ -0,0 +1,27 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + ヘッダー ファイル + + + + + ソース ファイル + + + \ No newline at end of file diff --git a/TPIHuman/TTTPlugin.h b/TPIHuman/TTTPlugin.h new file mode 100644 index 0000000..dcdc8af --- /dev/null +++ b/TPIHuman/TTTPlugin.h @@ -0,0 +1,11 @@ +#pragma once + +const int BOARD_SIZE = 9; + +extern "C" +{ + // 既定の関数 + __declspec(dllexport) bool IsHuman(); + __declspec(dllexport) void GetName(char* buf, size_t bufsize); + __declspec(dllexport) int MyTurn(int* board, int turn, int player); +} diff --git a/TTTConsole/App.config b/TTTConsole/App.config new file mode 100644 index 0000000..56efbc7 --- /dev/null +++ b/TTTConsole/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/TTTConsole/Program.cs b/TTTConsole/Program.cs new file mode 100644 index 0000000..52ebbac --- /dev/null +++ b/TTTConsole/Program.cs @@ -0,0 +1,146 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Runtime.InteropServices; +using TTT; + +namespace TTTConsole { + + class Program { + + [DllImport("TPIRandom.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint ="IsHuman")] + private extern static bool IsHumanR(); + + [DllImport("TPIRandom.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "GetName", CharSet = CharSet.Ansi)] + private extern static void GetNameR(StringBuilder s, Int32 bufsize); + + [DllImport("TPIRandom.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "MyTurn")] + private extern static int MyTurnR(IntPtr board, int turn, int player); + + [DllImport("TPIRandom.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "IsHuman")] + private extern static bool IsHumanH(); + + [DllImport("TPIHuman.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "GetName", CharSet = CharSet.Ansi)] + private extern static void GetNameH(StringBuilder s, Int32 bufsize); + + [DllImport("TPIHuman.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "MyTurn")] + private extern static int MyTurnH(IntPtr board, int turn, int player); + + + static string[] PLAYER_STR = new string[] { "", "先手", "後手" }; + static string[] PLAYER_MARK = new string[] { " ", "○", "×" }; + static string[] names; + + /// + /// プログラム開始点 + /// + /// + static void Main(string[] args) { + + Console.WriteLine(new string('*', 30)); + Console.WriteLine("拡張○×ゲーム"); + Console.WriteLine(new string('*', 30)); + Console.WriteLine(""); + var ttt = new TicTacToe(); + + // プラグイン名の取得 + System.Text.StringBuilder sb = new System.Text.StringBuilder(256); + names = new string[2]; + //var names = new List(); + GetNameH(sb, sb.Capacity); + names[0] = sb.ToString(); + GetNameR(sb, sb.Capacity); + names[1] = sb.ToString(); + + // プレイヤーの選択 + Console.WriteLine("プレイヤーの選択"); + var thinkers = new int[ttt.PLAYERS]; + for (var pl=0; pl< ttt.PLAYERS; pl++) { + for (var i = 0; i < names.Length; i++) { + Console.WriteLine($"({i + 1}) {names[i]}"); + } + 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.Length) return; + } + + // 対戦開始 + ttt.Init(); + do { + Console.WriteLine(""); + ShowBoard(ttt); + Console.Write($"{PlayerStr(ttt.Player)} の番"); + + switch (thinkers[(int)ttt.Player - 1]) { + case 1: + Console.WriteLine(""); + ttt.Set(MyTurnH(ttt.GetBoard(), ttt.Turn, (int)ttt.Player)); + break; + case 2: + ttt.Set(MyTurnR(ttt.GetBoard(), ttt.Turn, (int)ttt.Player)); + if (!IsHumanR()) Console.WriteLine($" --> {ttt.LastSet + 1}"); + break; + } + } 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)); + + // 終了 + Console.Write("Press [Enter] to exit."); + Console.ReadLine(); + } + + /// + /// 盤の表示 + /// + /// + static void ShowBoard(TicTacToe ttt) { + Console.WriteLine(new string('~', 6) + $" ターン{ttt.Turn} " + new string('~', 6)); + + 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] > 0 ? PLAYER.First : + ttt.Board[pos] < 0 ? PLAYER.Second : PLAYER.None; + Console.Write(PLAYER_MARK[(int)pIdx]); + if (col < ttt.BOARD_COLS - 1) Console.Write(" | "); + } + Console.WriteLine(""); + if (row < ttt.BOARD_ROWS - 1) Console.WriteLine(" ---+----+---"); + } + } + + /// + /// プレイヤーの表示文字列を生成 + /// + /// プレイヤー + /// 表示文字列 + static string PlayerStr(PLAYER p) { + return $"{PLAYER_STR[(int)p]}({names[(int)p - 1]})"; + } + } +} diff --git a/TTTConsole/Properties/AssemblyInfo.cs b/TTTConsole/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..170ade8 --- /dev/null +++ b/TTTConsole/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 +// 制御されます。アセンブリに関連付けられている情報を変更するには、 +// これらの属性値を変更します。 +[assembly: AssemblyTitle("TTTConsole")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("TTTConsole")] +[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// ComVisible を false に設定すると、このアセンブリ内の型は COM コンポーネントから +// 参照できなくなります。COM からこのアセンブリ内の型にアクセスする必要がある場合は、 +// その型の ComVisible 属性を true に設定します。 +[assembly: ComVisible(false)] + +// このプロジェクトが COM に公開される場合、次の GUID が typelib の ID になります +[assembly: Guid("1e89ef09-bd17-47e9-8213-727e586bd5e5")] + +// アセンブリのバージョン情報は次の 4 つの値で構成されています: +// +// メジャー バージョン +// マイナー バージョン +// ビルド番号 +// リビジョン +// +// すべての値を指定するか、次を使用してビルド番号とリビジョン番号を既定に設定できます +// 既定値にすることができます: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/TTTConsole/TTTConsole.csproj b/TTTConsole/TTTConsole.csproj new file mode 100644 index 0000000..fd608e5 --- /dev/null +++ b/TTTConsole/TTTConsole.csproj @@ -0,0 +1,74 @@ + + + + + Debug + AnyCPU + {1E89EF09-BD17-47E9-8213-727E586BD5E5} + Exe + TTTConsole + TTTConsole + v4.7.2 + 512 + true + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + true + bin\x64\Debug\ + DEBUG;TRACE + full + x64 + 7.3 + prompt + true + + + bin\x64\Release\ + TRACE + true + pdbonly + x64 + 7.3 + prompt + true + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TTTConsole/TicTacToe.cs b/TTTConsole/TicTacToe.cs new file mode 100644 index 0000000..9626bf3 --- /dev/null +++ b/TTTConsole/TicTacToe.cs @@ -0,0 +1,130 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Runtime.InteropServices; + +namespace TTT { + + public enum PLAYER { None = 0, First = 1, Second = 2 }; + public enum JUDGE { None, WIN, DRAW, OUT_OF_RANGE, OVERLAP } + + /// + /// TicTacToeクラス + /// ゲーム進行のみ管理.UIは関与しない. + /// + class TicTacToe { + + public readonly int BOARD_ROWS = 3; // マスの行数 + public readonly int BOARD_COLS = 3; // マスの列数 + public readonly int BOARD_SIZE = 9; // マスの総数 + public readonly int REMAIN_PIECES = 3; // 盤に残る駒の数 + 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; // アンマネージドメモリの盤データ + + /// + /// コンストラクタ + /// + /// ターン数上限 + 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); + } + + /// + /// デストラクタ + /// + ~TicTacToe() { + Marshal.FreeCoTaskMem(_board); + } + + /// + /// ゲームの初期化 + /// + public void Init() { + for (var i = 0; i < BOARD_SIZE; i++) Board[i] = NONE; + Turn = 1; + Player = PLAYER.First; + Winner = PLAYER.None; + Judge = JUDGE.None; + } + + /// + /// 駒を置き,結果を判定 + /// + /// 置く場所 + /// 判定結果 + public void Set(int pos) { + // 値チェック + LastSet = pos; + if (pos < 0 || pos >= BOARD_SIZE) { + Judge = JUDGE.OUT_OF_RANGE; + return; + } + + // 反則(重ね置き)チェック + if (Board[pos] != 0) { + Winner = Player == PLAYER.First ? PLAYER.Second : PLAYER.First; + Judge = JUDGE.OVERLAP; + return; + } + + // 盤の更新 + Board[pos] = Turn * SIGN[(int)Player]; + if (Turn > REMAIN_PIECES) { + var remove = (Turn - REMAIN_PIECES) * SIGN[(int)Player]; + for (var i = 0; i < BOARD_SIZE; i++) { + if (Board[i] == remove) Board[i] = NONE; + } + } + + // 勝利判定 + for (var i = 0; i < LINES.GetLength(0); i++) { + if (Board[LINES[i, 0]] * SIGN[(int)Player] > 0 && + Board[LINES[i, 1]] * SIGN[(int)Player] > 0 && + Board[LINES[i, 2]] * SIGN[(int)Player] > 0) { + Winner = Player; + Judge = JUDGE.WIN; + return; + } + } + + // 次へ + if (Player == PLAYER.First) { + Player = PLAYER.Second; + } else { + Player = PLAYER.First; + if (++Turn >= TURN_LIMIT) { + Judge = JUDGE.DRAW; + return; + } + } + return; + } + + /// + /// アンマネージドメモリの盤データを取得 + /// + /// + public IntPtr GetBoard() { + Marshal.Copy(Board, 0, _board, BOARD_SIZE); + return _board; + } + } +} diff --git a/TicTacToe.sln b/TicTacToe.sln new file mode 100644 index 0000000..7a7e9ab --- /dev/null +++ b/TicTacToe.sln @@ -0,0 +1,51 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TTTConsole", "TTTConsole\TTTConsole.csproj", "{1E89EF09-BD17-47E9-8213-727E586BD5E5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TPIRandom", "Random\Random.vcxproj", "{E94D271E-A8BA-45AF-9531-02CA7D6035B7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TPIHuman", "TPIHuman\TPIHuman.vcxproj", "{74D69A51-B6D6-4F41-956C-0ADBAA10E868}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1E89EF09-BD17-47E9-8213-727E586BD5E5}.Debug|x64.ActiveCfg = Debug|x64 + {1E89EF09-BD17-47E9-8213-727E586BD5E5}.Debug|x64.Build.0 = Debug|x64 + {1E89EF09-BD17-47E9-8213-727E586BD5E5}.Debug|x86.ActiveCfg = Debug|Any CPU + {1E89EF09-BD17-47E9-8213-727E586BD5E5}.Debug|x86.Build.0 = Debug|Any CPU + {1E89EF09-BD17-47E9-8213-727E586BD5E5}.Release|x64.ActiveCfg = Release|x64 + {1E89EF09-BD17-47E9-8213-727E586BD5E5}.Release|x64.Build.0 = Release|x64 + {1E89EF09-BD17-47E9-8213-727E586BD5E5}.Release|x86.ActiveCfg = Release|Any CPU + {1E89EF09-BD17-47E9-8213-727E586BD5E5}.Release|x86.Build.0 = Release|Any CPU + {E94D271E-A8BA-45AF-9531-02CA7D6035B7}.Debug|x64.ActiveCfg = Debug|x64 + {E94D271E-A8BA-45AF-9531-02CA7D6035B7}.Debug|x64.Build.0 = Debug|x64 + {E94D271E-A8BA-45AF-9531-02CA7D6035B7}.Debug|x86.ActiveCfg = Debug|Win32 + {E94D271E-A8BA-45AF-9531-02CA7D6035B7}.Debug|x86.Build.0 = Debug|Win32 + {E94D271E-A8BA-45AF-9531-02CA7D6035B7}.Release|x64.ActiveCfg = Release|x64 + {E94D271E-A8BA-45AF-9531-02CA7D6035B7}.Release|x64.Build.0 = Release|x64 + {E94D271E-A8BA-45AF-9531-02CA7D6035B7}.Release|x86.ActiveCfg = Release|Win32 + {E94D271E-A8BA-45AF-9531-02CA7D6035B7}.Release|x86.Build.0 = Release|Win32 + {74D69A51-B6D6-4F41-956C-0ADBAA10E868}.Debug|x64.ActiveCfg = Debug|x64 + {74D69A51-B6D6-4F41-956C-0ADBAA10E868}.Debug|x64.Build.0 = Debug|x64 + {74D69A51-B6D6-4F41-956C-0ADBAA10E868}.Debug|x86.ActiveCfg = Debug|Win32 + {74D69A51-B6D6-4F41-956C-0ADBAA10E868}.Debug|x86.Build.0 = Debug|Win32 + {74D69A51-B6D6-4F41-956C-0ADBAA10E868}.Release|x64.ActiveCfg = Release|x64 + {74D69A51-B6D6-4F41-956C-0ADBAA10E868}.Release|x64.Build.0 = Release|x64 + {74D69A51-B6D6-4F41-956C-0ADBAA10E868}.Release|x86.ActiveCfg = Release|Win32 + {74D69A51-B6D6-4F41-956C-0ADBAA10E868}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {9CD56B47-57EA-48E5-8705-163FF8E9202A} + EndGlobalSection +EndGlobal