diff --git a/Directory.Packages.props b/Directory.Packages.props index 779bd54e..44a47e8f 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,99 +1,87 @@ - - - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PdkFriendServer/Logic/NeuralBot.cs b/PdkFriendServer/Logic/NeuralBot.cs new file mode 100644 index 00000000..d14647f5 --- /dev/null +++ b/PdkFriendServer/Logic/NeuralBot.cs @@ -0,0 +1,259 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using GameFix.PaoDeKuaiF; +using GameFix.Poker; +using GameMessage; +using GameMessage.PaoDeKuaiF; +using Microsoft.ML.OnnxRuntime; +using Microsoft.ML.OnnxRuntime.Tensors; + +namespace PdkFriendServer.Logic +{ + /// + /// NeuralBot v1 — 加载 ONNX 模型做决策的 Bot。 + /// 状态编码与 Python trainer 完全一致:15 rank × 4 suit × 7 channel → 420 float。 + /// + /// 用法:PdkGameMain.InitBots() 中替换部分 bot 为 NeuralBot。 + /// 训练:Python trainer → 导出 ONNX → 放 model.onnx → C# 加载。 + /// + public class NeuralBot : IPdkBot + { + private readonly InferenceSession _session; + private readonly Random _rng; + private readonly CardTracker _tracker = new CardTracker(); + private readonly float _epsilon; // 探索率 + + // 状态编码常量 + private static readonly int[] Ranks = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16 }; + private const int NumRanks = 13; + private const int NumSuits = 4; + private const int NumChannels = 7; + private const int InputDim = NumChannels * NumRanks * NumSuits; // 364 + private const int OutputDim = 14; // 13 ranks + pass + + public NeuralBot(string modelPath = "model.onnx", float epsilon = 0.05f) + { + var options = new SessionOptions(); + options.LogSeverityLevel = OrtLoggingLevel.ORT_LOGGING_LEVEL_ERROR; + _session = new InferenceSession(modelPath, options); + _rng = new Random(); + _epsilon = epsilon; + } + + public bool DecideBaoZhuang(PdkBotView view) + { + // Neural model 暂不参与包庄决策,沿用 ISMCTS 逻辑 + _tracker.Update(view); + int minPlays = HandOptimizer.MinPlays(view.MyHand); + if (minPlays >= 7) return false; + return minPlays <= 3; // 极简:手牌极好才包 + } + + public PlayOutCardPdkF DecidePlay(PdkBotView view) + { + _tracker.Update(view); + var hand = view.MyHand; + if (hand.Length == 0) return Pass(view); + + // 1. 获取合法出牌 + bool isFirstPlay = view.MaxPlayCard.GameNum <= 0; + var tips = PdkCardAlgorithm.GetTipCard(view.MaxPlayCard, hand, null, view.Rule.AAAIsZhaDan); + var candidates = new List<(PlayOutCardPdkF play, int actionIdx)>(); + + if (tips != null) + { + foreach (var tip in tips) + { + int rank = tip[0].GameNum; + int idx = RankToIdx(rank); + candidates.Add((MakePlay(tip, view.MyPos), idx)); + } + } + + // 新轮次补多牌方案 + if (isFirstPlay) + AddMultiCardCandidates(hand, view.MyPos, candidates); + + if (!isFirstPlay) + candidates.Add((Pass(view), OutputDim - 1)); // pass = last index + + if (candidates.Count == 0) return Pass(view); + if (candidates.Count == 1) return candidates[0].play; + + // 2. ε-greedy 探索 + if (_rng.NextDouble() < _epsilon) + return candidates[_rng.Next(candidates.Count)].play; + + // 3. 状态编码 + ONNX 推理 + var stateVec = EncodeState(view); + var qValues = RunInference(stateVec); + + // 4. 选合法动作中 Q 值最高的 + int bestIdx = 0; + float bestQ = float.MinValue; + for (int i = 0; i < candidates.Count; i++) + { + int ai = candidates[i].actionIdx; + if (ai >= 0 && ai < qValues.Length && qValues[ai] > bestQ) + { + bestQ = qValues[ai]; + bestIdx = i; + } + } + + var chosen = candidates[bestIdx]; + bool isPass = chosen.play.Type == CardType1.None; + Console.WriteLine($"[NeuralBot pos{view.MyPos}] {candidates.Count}c → " + + $"{(isPass ? "pass" : $"{chosen.play.Ids?.Length ?? 1}c rank={chosen.play.GameNum}")} Q={bestQ:F3}"); + return chosen.play; + } + + // ---- 状态编码(与 Python encode_game_state 一致)---- + + private float[] EncodeState(PdkBotView view) + { + var state = new float[InputDim]; // 7 × 13 × 4 = 364 + + // ch0: 我的手牌 + foreach (var c in view.MyHand) + { + if (c.GameState != 1) continue; + int ri = RankToIdx(c.GameNum); + int si = SuitToIdx(c.ID); + if (ri >= 0 && si >= 0) + state[ChOffset(0) + ri * NumSuits + si] = 1.0f; + } + + // ch1: 已出牌 — 通过 card tracker 的 seen cards + var seenIds = GetSeenCardIds(view); + foreach (var id in seenIds) + { + int ri = RankToIdx(IdToGameNum(id)); + int si = SuitToIdx(id); + if (ri >= 0 && si >= 0) + state[ChOffset(1) + ri * NumSuits + si] = 1.0f; + } + + // ch2: 我的手牌数量 + int myCount = view.MyHand.Count(c => c.GameState == 1); + int c2Slot = myCount % NumRanks; + state[ChOffset(2) + c2Slot * NumSuits + 0] = (float)myCount / 16.0f; + + // ch3: 下家剩余 + int opp1 = view.MyPos % 3; + int c1 = view.ShenYuCard[opp1]; + state[ChOffset(3) + (c1 % NumRanks) * NumSuits + 0] = (float)c1 / 16.0f; + + // ch4: 上家剩余 + int opp2 = (view.MyPos + 1) % 3; + int c2 = view.ShenYuCard[opp2]; + state[ChOffset(4) + (c2 % NumRanks) * NumSuits + 0] = (float)c2 / 16.0f; + + // ch5: 当前位置 + state[ChOffset(5) + (view.MyPos % NumRanks) * NumSuits + 0] = 1.0f; + + // ch6: last_play rank + if (view.MaxPlayCard.GameNum > 0 && view.MaxPlayCard.Pos != view.MyPos) + { + int lr = RankToIdx(view.MaxPlayCard.GameNum); + if (lr >= 0) + state[ChOffset(6) + lr * NumSuits + 0] = 1.0f; + } + + return state; + } + + private float[] RunInference(float[] input) + { + var tensor = new DenseTensor(input, new[] { 1, InputDim }); + var inputs = new List { NamedOnnxValue.CreateFromTensor("state", tensor) }; + using var results = _session.Run(inputs); + var output = results.First().AsTensor(); + return output.ToArray(); + } + + // ---- 辅助 ---- + + private static int RankToIdx(int gameNum) => gameNum switch + { + 3 => 0, 4 => 1, 5 => 2, 6 => 3, 7 => 4, 8 => 5, 9 => 6, + 10 => 7, 11 => 8, 12 => 9, 13 => 10, 14 => 11, 16 => 12, + _ => -1 + }; + + private static int SuitToIdx(int id) + { + // ID = (suit-1)*13 + n, suit 1-4 + int suit = (id - 1) / 13; // 0-3 + return suit >= 0 && suit < 4 ? suit : -1; + } + + private static int IdToGameNum(int id) + { + int n = (id - 1) % 13 + 1; // 1-13 + return n == 1 ? 14 : n == 2 ? 16 : n; + } + + private HashSet GetSeenCardIds(PdkBotView view) + { + var seen = new HashSet(); + // Track played cards through view: all hands that have appeared on table + if (view.MaxPlayCard.Ids != null) + foreach (var id in view.MaxPlayCard.Ids) seen.Add(id); + // Also track from our own played cards (cards not in my hand anymore) + return seen; + } + + private static int ChOffset(int ch) => ch * NumRanks * NumSuits; + + // ---- 多牌候选(精简版,复用 IsmctsBot 逻辑)---- + + private void AddMultiCardCandidates(TCardInfoPdkF[] hand, int pos, + List<(PlayOutCardPdkF play, int actionIdx)> candidates) + { + // 对子 + foreach (var g in hand.Where(c => c.GameState == 1).GroupBy(c => c.GameNum).Where(g => g.Count() >= 2)) + { + var pair = g.Take(2).ToList(); + candidates.Add((MakePlay(pair, pos), RankToIdx(pair[0].GameNum))); + } + // 三张 + foreach (var g in hand.Where(c => c.GameState == 1).GroupBy(c => c.GameNum).Where(g => g.Count() >= 3)) + { + var trip = g.Take(3).ToList(); + var rem = hand.Where(c => c.GameState == 1 && c.GameNum != g.Key).ToList(); + if (rem.Count >= 2) + { + // 优先带对子 + var pair = rem.GroupBy(c => c.GameNum).Where(x => x.Count() >= 2).OrderBy(x => x.Key).FirstOrDefault(); + var attach = pair != null ? pair.Take(2).ToList() : rem.OrderBy(c => c.GameNum).Take(2).ToList(); + candidates.Add((MakePlay(trip.Concat(attach).ToList(), pos), RankToIdx(trip[0].GameNum))); + } + } + // 顺子 + var straights = PokerLogic.GetShunZi(hand); + if (straights != null) + foreach (var s in straights) + { + var cards = s.ToList(); + candidates.Add((MakePlay(cards, pos), RankToIdx(cards[0].GameNum))); + } + // 炸弹 + if (PokerLogic.GetPlayZhaDans(hand, out var bombs) && bombs != null) + foreach (var b in bombs) + { + var cards = b.ToList(); + candidates.Add((MakePlay(cards, pos), RankToIdx(cards[0].GameNum))); + } + } + + private static PlayOutCardPdkF MakePlay(List cards, int pos) + => new PlayOutCardPdkF { Pos = (byte)pos, GameNum = cards[0].GameNum, Ids = cards.Select(c => c.ID).ToArray(), Type = CardType1.None }; + + private static PlayOutCardPdkF Pass(PdkBotView v) + => new PlayOutCardPdkF { Pos = (byte)v.MyPos, Type = CardType1.None }; + + public void Dispose() => _session?.Dispose(); + } +} \ No newline at end of file diff --git a/PdkFriendServer/Logic/PdkGameMain.cs b/PdkFriendServer/Logic/PdkGameMain.cs index da513ebb..3d6bbb32 100644 --- a/PdkFriendServer/Logic/PdkGameMain.cs +++ b/PdkFriendServer/Logic/PdkGameMain.cs @@ -56,12 +56,22 @@ namespace PdkFriendServer.Logic this.GamePack = new PdkGamePack(); } - /// 懒初始化3个bot(BotMode==true时首次WaitWanJiaShuRu调用) - private void InitBots() + /// 懒初始化3个bot(BotMode==true时首次WaitWanJiaShuRu调用) + /// BotTypes: "ISMCTS" / "NEURAL" / null=默认ISMCTS + /// 训练模式: ["NEURAL","NEURAL","ISMCTS"] = 2个模型bot + 1个ISMCTS + public static string[] BotTypes = null; + + private void InitBots() { _bots = new IPdkBot[3]; for (int i = 0; i < 3; i++) - _bots[i] = new IsmctsBot(); + { + string type = BotTypes != null && BotTypes.Length > i ? BotTypes[i] : null; + if (type == "NEURAL") + _bots[i] = new NeuralBot("model.onnx", 0.1f); + else + _bots[i] = new IsmctsBot(); + } } /// 构建当前玩家的可见视图——只看自己手牌+公开信息 diff --git a/PdkFriendServer/PdkFriendServer.csproj b/PdkFriendServer/PdkFriendServer.csproj index e33c38fc..d6c85fdd 100644 --- a/PdkFriendServer/PdkFriendServer.csproj +++ b/PdkFriendServer/PdkFriendServer.csproj @@ -43,6 +43,8 @@ + + diff --git a/exe/PdkFriendServer/PdkFriendServer.deps.json b/exe/PdkFriendServer/PdkFriendServer.deps.json index f5fea0c2..cf487b48 100644 --- a/exe/PdkFriendServer/PdkFriendServer.deps.json +++ b/exe/PdkFriendServer/PdkFriendServer.deps.json @@ -13,6 +13,8 @@ "GlobalSever": "1.0.0", "MessagePack.Annotations": "3.1.4", "Microsoft.Bcl.AsyncInterfaces": "9.0.0", + "Microsoft.ML.OnnxRuntime": "1.27.1", + "Microsoft.ML.OnnxRuntime.Managed": "1.27.1", "Microsoft.NET.StringTools": "17.11.4", "MrWu": "1.0.0", "NetWorkMessage": "1.0.0", @@ -195,6 +197,99 @@ } } }, + "Microsoft.ML.OnnxRuntime/1.27.1": { + "dependencies": { + "Microsoft.ML.OnnxRuntime.Managed": "1.27.1" + }, + "runtimeTargets": { + "runtimes/android/native/onnxruntime.aar": { + "rid": "android", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/ios/native/onnxruntime.xcframework.zip": { + "rid": "ios", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/linux-arm64/native/libonnxruntime.so": { + "rid": "linux-arm64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/linux-arm64/native/libonnxruntime_providers_shared.so": { + "rid": "linux-arm64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/linux-x64/native/libonnxruntime.so": { + "rid": "linux-x64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/linux-x64/native/libonnxruntime_providers_shared.so": { + "rid": "linux-x64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/osx-arm64/native/libonnxruntime.dylib": { + "rid": "osx-arm64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/win-arm64/native/onnxruntime.dll": { + "rid": "win-arm64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/win-arm64/native/onnxruntime.lib": { + "rid": "win-arm64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/win-arm64/native/onnxruntime_providers_shared.dll": { + "rid": "win-arm64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/win-arm64/native/onnxruntime_providers_shared.lib": { + "rid": "win-arm64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/win-x64/native/onnxruntime.dll": { + "rid": "win-x64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/win-x64/native/onnxruntime.lib": { + "rid": "win-x64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/win-x64/native/onnxruntime_providers_shared.dll": { + "rid": "win-x64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/win-x64/native/onnxruntime_providers_shared.lib": { + "rid": "win-x64", + "assetType": "native", + "fileVersion": "0.0.0.0" + } + } + }, + "Microsoft.ML.OnnxRuntime.Managed/1.27.1": { + "dependencies": { + "System.Numerics.Tensors": "9.0.0" + }, + "runtime": { + "lib/net8.0/Microsoft.ML.OnnxRuntime.dll": { + "assemblyVersion": "1.27.1.0", + "fileVersion": "1.27.1.0" + } + } + }, "Microsoft.NET.StringTools/17.11.4": { "runtime": { "lib/net8.0/Microsoft.NET.StringTools.dll": { @@ -222,6 +317,14 @@ } } }, + "System.Numerics.Tensors/9.0.0": { + "runtime": { + "lib/net9.0/System.Numerics.Tensors.dll": { + "assemblyVersion": "9.0.0.0", + "fileVersion": "9.0.24.52809" + } + } + }, "Tea/1.1.3": { "dependencies": { "Newtonsoft.Json": "13.0.4" @@ -571,6 +674,20 @@ "path": "microsoft.bcl.asyncinterfaces/9.0.0", "hashPath": "microsoft.bcl.asyncinterfaces.9.0.0.nupkg.sha512" }, + "Microsoft.ML.OnnxRuntime/1.27.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-lVD57zo77erw9oLC2obkKkMOM+CqbtwZuztfXQxEy3oJBOWmDKweto+c+N/Mh/FUoVRRFfsR9KaMX+aM+XLh+Q==", + "path": "microsoft.ml.onnxruntime/1.27.1", + "hashPath": "microsoft.ml.onnxruntime.1.27.1.nupkg.sha512" + }, + "Microsoft.ML.OnnxRuntime.Managed/1.27.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-7vZTjZzuSP6XC47lbRN0xI9+6YDOChxKjmUmb80q7YC8Nb7zQUVrETFGLXlFfYWjvlb8/4J+w+L33gBTCpLMKA==", + "path": "microsoft.ml.onnxruntime.managed/1.27.1", + "hashPath": "microsoft.ml.onnxruntime.managed.1.27.1.nupkg.sha512" + }, "Microsoft.NET.StringTools/17.11.4": { "type": "package", "serviceable": true, @@ -592,6 +709,13 @@ "path": "newtonsoft.json.bson/1.0.1", "hashPath": "newtonsoft.json.bson.1.0.1.nupkg.sha512" }, + "System.Numerics.Tensors/9.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-hyJB4UlpAi19Xr9AXzu2NuagKC4lPfHObNMEAA0HmqFz2rX7wKgzeYzO/jM/eBHDhnUGFFEjk5cOoJaxqg5J4A==", + "path": "system.numerics.tensors/9.0.0", + "hashPath": "system.numerics.tensors.9.0.0.nupkg.sha512" + }, "Tea/1.1.3": { "type": "package", "serviceable": true, diff --git a/exe/PdkFriendServer/PdkFriendServer.dll b/exe/PdkFriendServer/PdkFriendServer.dll index 91062576..d4d057a0 100644 Binary files a/exe/PdkFriendServer/PdkFriendServer.dll and b/exe/PdkFriendServer/PdkFriendServer.dll differ diff --git a/exe/PdkFriendServer/PdkFriendServer.dll.config b/exe/PdkFriendServer/PdkFriendServer.dll.config index 898d21a0..64acc8d3 100644 --- a/exe/PdkFriendServer/PdkFriendServer.dll.config +++ b/exe/PdkFriendServer/PdkFriendServer.dll.config @@ -409,6 +409,12 @@ + + + + + + diff --git a/exe/PdkFriendServer/PdkFriendServer.pdb b/exe/PdkFriendServer/PdkFriendServer.pdb index e3c1015a..f2ed6097 100644 Binary files a/exe/PdkFriendServer/PdkFriendServer.pdb and b/exe/PdkFriendServer/PdkFriendServer.pdb differ diff --git a/exe/hjha-console/PdkFriendServer.dll b/exe/hjha-console/PdkFriendServer.dll index 91062576..d4d057a0 100644 Binary files a/exe/hjha-console/PdkFriendServer.dll and b/exe/hjha-console/PdkFriendServer.dll differ diff --git a/exe/hjha-console/PdkFriendServer.dll.config b/exe/hjha-console/PdkFriendServer.dll.config index 898d21a0..64acc8d3 100644 --- a/exe/hjha-console/PdkFriendServer.dll.config +++ b/exe/hjha-console/PdkFriendServer.dll.config @@ -409,6 +409,12 @@ + + + + + + diff --git a/exe/hjha-console/PdkFriendServer.pdb b/exe/hjha-console/PdkFriendServer.pdb index e3c1015a..f2ed6097 100644 Binary files a/exe/hjha-console/PdkFriendServer.pdb and b/exe/hjha-console/PdkFriendServer.pdb differ diff --git a/exe/hjha-console/hjha-console.deps.json b/exe/hjha-console/hjha-console.deps.json index 378a9fea..d876d377 100644 --- a/exe/hjha-console/hjha-console.deps.json +++ b/exe/hjha-console/hjha-console.deps.json @@ -191,6 +191,99 @@ } } }, + "Microsoft.ML.OnnxRuntime/1.27.1": { + "dependencies": { + "Microsoft.ML.OnnxRuntime.Managed": "1.27.1" + }, + "runtimeTargets": { + "runtimes/android/native/onnxruntime.aar": { + "rid": "android", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/ios/native/onnxruntime.xcframework.zip": { + "rid": "ios", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/linux-arm64/native/libonnxruntime.so": { + "rid": "linux-arm64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/linux-arm64/native/libonnxruntime_providers_shared.so": { + "rid": "linux-arm64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/linux-x64/native/libonnxruntime.so": { + "rid": "linux-x64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/linux-x64/native/libonnxruntime_providers_shared.so": { + "rid": "linux-x64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/osx-arm64/native/libonnxruntime.dylib": { + "rid": "osx-arm64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/win-arm64/native/onnxruntime.dll": { + "rid": "win-arm64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/win-arm64/native/onnxruntime.lib": { + "rid": "win-arm64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/win-arm64/native/onnxruntime_providers_shared.dll": { + "rid": "win-arm64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/win-arm64/native/onnxruntime_providers_shared.lib": { + "rid": "win-arm64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/win-x64/native/onnxruntime.dll": { + "rid": "win-x64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/win-x64/native/onnxruntime.lib": { + "rid": "win-x64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/win-x64/native/onnxruntime_providers_shared.dll": { + "rid": "win-x64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/win-x64/native/onnxruntime_providers_shared.lib": { + "rid": "win-x64", + "assetType": "native", + "fileVersion": "0.0.0.0" + } + } + }, + "Microsoft.ML.OnnxRuntime.Managed/1.27.1": { + "dependencies": { + "System.Numerics.Tensors": "9.0.0" + }, + "runtime": { + "lib/net8.0/Microsoft.ML.OnnxRuntime.dll": { + "assemblyVersion": "1.27.1.0", + "fileVersion": "1.27.1.0" + } + } + }, "Microsoft.NET.StringTools/17.11.4": { "runtime": { "lib/net8.0/Microsoft.NET.StringTools.dll": { @@ -218,6 +311,14 @@ } } }, + "System.Numerics.Tensors/9.0.0": { + "runtime": { + "lib/net9.0/System.Numerics.Tensors.dll": { + "assemblyVersion": "9.0.0.0", + "fileVersion": "9.0.24.52809" + } + } + }, "Tea/1.1.3": { "dependencies": { "Newtonsoft.Json": "13.0.4" @@ -380,6 +481,8 @@ "GlobalSever": "1.0.0", "MessagePack.Annotations": "3.1.4", "Microsoft.Bcl.AsyncInterfaces": "9.0.0", + "Microsoft.ML.OnnxRuntime": "1.27.1", + "Microsoft.ML.OnnxRuntime.Managed": "1.27.1", "Microsoft.NET.StringTools": "17.11.4", "MrWu": "1.0.0", "NetWorkMessage": "1.0.0", @@ -588,6 +691,20 @@ "path": "microsoft.bcl.asyncinterfaces/9.0.0", "hashPath": "microsoft.bcl.asyncinterfaces.9.0.0.nupkg.sha512" }, + "Microsoft.ML.OnnxRuntime/1.27.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-lVD57zo77erw9oLC2obkKkMOM+CqbtwZuztfXQxEy3oJBOWmDKweto+c+N/Mh/FUoVRRFfsR9KaMX+aM+XLh+Q==", + "path": "microsoft.ml.onnxruntime/1.27.1", + "hashPath": "microsoft.ml.onnxruntime.1.27.1.nupkg.sha512" + }, + "Microsoft.ML.OnnxRuntime.Managed/1.27.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-7vZTjZzuSP6XC47lbRN0xI9+6YDOChxKjmUmb80q7YC8Nb7zQUVrETFGLXlFfYWjvlb8/4J+w+L33gBTCpLMKA==", + "path": "microsoft.ml.onnxruntime.managed/1.27.1", + "hashPath": "microsoft.ml.onnxruntime.managed.1.27.1.nupkg.sha512" + }, "Microsoft.NET.StringTools/17.11.4": { "type": "package", "serviceable": true, @@ -609,6 +726,13 @@ "path": "newtonsoft.json.bson/1.0.1", "hashPath": "newtonsoft.json.bson.1.0.1.nupkg.sha512" }, + "System.Numerics.Tensors/9.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-hyJB4UlpAi19Xr9AXzu2NuagKC4lPfHObNMEAA0HmqFz2rX7wKgzeYzO/jM/eBHDhnUGFFEjk5cOoJaxqg5J4A==", + "path": "system.numerics.tensors/9.0.0", + "hashPath": "system.numerics.tensors.9.0.0.nupkg.sha512" + }, "Tea/1.1.3": { "type": "package", "serviceable": true, diff --git a/exe/hjha-console/hjha-console.dll b/exe/hjha-console/hjha-console.dll index 3d2f4153..b985ee47 100644 Binary files a/exe/hjha-console/hjha-console.dll and b/exe/hjha-console/hjha-console.dll differ diff --git a/exe/hjha-console/hjha-console.pdb b/exe/hjha-console/hjha-console.pdb index c348b073..da890a2a 100644 Binary files a/exe/hjha-console/hjha-console.pdb and b/exe/hjha-console/hjha-console.pdb differ diff --git a/hjha-console/Program.cs b/hjha-console/Program.cs index cf183a85..d2bda6bf 100644 --- a/hjha-console/Program.cs +++ b/hjha-console/Program.cs @@ -9,6 +9,7 @@ namespace hjha_console { static void Main(string[] args) { + if (args.Length > 0 && args[0] == "--mix") { PdkGameMain.BotTypes = new[] { "NEURAL", "NEURAL", "ISMCTS" }; args = new[] { "--stress", args.Length > 1 ? args[1] : "10" }; } if (args.Length > 0 && args[0] == "--stress") { int rounds = args.Length > 1 ? int.Parse(args[1]) : 100; diff --git a/model.onnx b/model.onnx new file mode 100644 index 00000000..505d299e Binary files /dev/null and b/model.onnx differ