Implement highest damage AI, further work on AI runner, random fixes
All checks were successful
Build / Build (push) Successful in 51s
All checks were successful
Build / Build (push) Successful in 51s
This commit is contained in:
@@ -12,7 +12,7 @@ internal static class Program
|
||||
|
||||
private static Task<int> Main(string[] args)
|
||||
{
|
||||
Log.Logger = new LoggerConfiguration().MinimumLevel.Debug().WriteTo.Console().CreateLogger();
|
||||
Log.Logger = new LoggerConfiguration().MinimumLevel.Information().WriteTo.Console().CreateLogger();
|
||||
Log.Information("Starting AI Runner...");
|
||||
_availableAIs = AppDomain.CurrentDomain.GetAssemblies().SelectMany(assembly => assembly.GetTypes())
|
||||
.Where(type => type.IsSubclassOf(typeof(PokemonAI)) && !type.IsAbstract).Select(Activator.CreateInstance)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Collections.Concurrent;
|
||||
using PkmnLib.Dynamic.AI;
|
||||
using PkmnLib.Dynamic.Libraries;
|
||||
using PkmnLib.Dynamic.Models;
|
||||
@@ -12,32 +13,58 @@ public static class TestCommandRunner
|
||||
{
|
||||
internal static async Task RunTestCommand(PokemonAI ai1, PokemonAI ai2, int battles)
|
||||
{
|
||||
var t1 = DateTime.UtcNow;
|
||||
var library = DynamicLibraryImpl.Create([
|
||||
new Gen7Plugin(),
|
||||
]);
|
||||
|
||||
Log.Information("Running {Battles} battles between {AI1} and {AI2}", battles, ai1.Name, ai2.Name);
|
||||
var averageTimePerTurnPerBattle = new List<double>(battles);
|
||||
var results = new List<BattleResult>(battles);
|
||||
var random = new RandomImpl();
|
||||
var results = new ConcurrentBag<BattleResult>();
|
||||
var rootRandom = new RandomImpl();
|
||||
|
||||
const int maxTasks = 10;
|
||||
var battleTasks = new Task[maxTasks];
|
||||
var randoms = new IRandom[maxTasks];
|
||||
for (var i = 0; i < maxTasks; i++)
|
||||
{
|
||||
randoms[i] = new RandomImpl(rootRandom.GetInt());
|
||||
battleTasks[i] = Task.CompletedTask; // Initialize tasks to avoid null references
|
||||
}
|
||||
// Here you would implement the logic to run the AI scripts against each other.
|
||||
// This is a placeholder for demonstration purposes.
|
||||
for (var i = 0; i < battles; i++)
|
||||
{
|
||||
Log.Information("Battle {BattleNumber}: {AI1} vs {AI2}", i + 1, ai1.Name, ai2.Name);
|
||||
var battle = GenerateBattle(library, 3, random);
|
||||
var timePerTurn = new List<double>(20);
|
||||
while (!battle.HasEnded)
|
||||
var taskIndex = i % maxTasks;
|
||||
var index = i;
|
||||
var battleTask = Task.Run(async () =>
|
||||
{
|
||||
var res = await GetAndSetChoices(battle, ai1, ai2);
|
||||
timePerTurn.Add(res.MsPerTurn);
|
||||
Log.Information("Battle {BattleNumber}: {AI1} vs {AI2}", index + 1, ai1.Name, ai2.Name);
|
||||
var random = randoms[taskIndex];
|
||||
var battle = GenerateBattle(library, 3, random);
|
||||
var timePerTurn = new List<double>(20);
|
||||
while (!battle.HasEnded)
|
||||
{
|
||||
var res = await GetAndSetChoices(battle, ai1, ai2);
|
||||
timePerTurn.Add(res.MsPerTurn);
|
||||
}
|
||||
var result = battle.Result;
|
||||
Log.Information("Battle {BattleNumber} ended with result: {Result}", index + 1, result);
|
||||
averageTimePerTurnPerBattle.Add(timePerTurn.Average());
|
||||
results.Add(result.Value);
|
||||
});
|
||||
battleTasks[taskIndex] = battleTask;
|
||||
if (i % maxTasks == maxTasks - 1 || i == battles - 1)
|
||||
{
|
||||
Log.Debug("Starting {TaskCount} tasks", maxTasks);
|
||||
await Task.WhenAll(battleTasks);
|
||||
Log.Debug("Batch of {TaskCount} tasks completed", maxTasks);
|
||||
battleTasks = new Task[maxTasks]; // Reset tasks for the next batch
|
||||
}
|
||||
var result = battle.Result;
|
||||
Log.Information("Battle {BattleNumber} ended with result: {Result}", i + 1, result);
|
||||
averageTimePerTurnPerBattle.Add(timePerTurn.Average());
|
||||
results.Add(result.Value);
|
||||
}
|
||||
Log.Information("All battles completed");
|
||||
|
||||
var t2 = DateTime.UtcNow;
|
||||
Log.Information("{Amount} battles completed in {Duration} ms", battles, (t2 - t1).TotalMilliseconds);
|
||||
var averageTimePerTurn = averageTimePerTurnPerBattle.Average();
|
||||
Log.Information("Average time per turn: {AverageTimePerTurn} ms", averageTimePerTurn);
|
||||
|
||||
@@ -45,8 +72,11 @@ public static class TestCommandRunner
|
||||
var winCount2 = results.Count(x => x.WinningSide == 1);
|
||||
var drawCount = results.Count(x => x.WinningSide == null);
|
||||
|
||||
Log.Information("Results: {AI1} wins: {WinCount1}, {AI2} wins: {WinCount2}, Draws: {DrawCount}", ai1.Name,
|
||||
winCount1, ai2.Name, winCount2, drawCount);
|
||||
var winRate1 = winCount1 / (double)battles * 100;
|
||||
var winRate2 = winCount2 / (double)battles * 100;
|
||||
Log.Information("AI {AI1} win rate: {WinRate1:F3}% ({WinCount1} wins)", ai1.Name, winRate1, winCount1);
|
||||
Log.Information("AI {AI2} win rate: {WinRate2:F3}% ({WinCount2} wins)", ai2.Name, winRate2, winCount2);
|
||||
Log.Information("Draw rate: {DrawRate:F3}% ({DrawCount} draws)", drawCount / (double)battles * 100, drawCount);
|
||||
}
|
||||
|
||||
private static PokemonPartyImpl GenerateParty(IDynamicLibrary library, int length, IRandom random)
|
||||
@@ -64,7 +94,7 @@ public static class TestCommandRunner
|
||||
IsHidden = false,
|
||||
Index = abilityIndex,
|
||||
}, level, 0, species.GetRandomGender(random), 0, nature.Name);
|
||||
var moves = defaultForm.Moves.GetDistinctLevelMoves().OrderBy(x => random.GetInt()).Take(4);
|
||||
var moves = defaultForm.Moves.GetDistinctLevelMoves().OrderBy(_ => random.GetInt()).Take(4);
|
||||
foreach (var move in moves)
|
||||
mon.LearnMove(move, MoveLearnMethod.LevelUp, 255);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user