PkmnLib.NET/AI/AIRunner/Program.cs
2025-07-11 17:03:08 +02:00

93 lines
3.3 KiB
C#

using System.CommandLine;
using System.CommandLine.Parsing;
using System.Reflection;
using PkmnLib.Dynamic.AI;
using PkmnLib.Dynamic.Libraries;
using PkmnLib.Plugin.Gen7;
using Serilog;
namespace AIRunner;
internal static class Program
{
private static List<PokemonAI>? _availableAIs;
private static Task<int> Main(string[] args)
{
Log.Logger = new LoggerConfiguration().MinimumLevel.Information().WriteTo.Console().CreateLogger();
Log.Information("Starting AI Runner...");
AILogging.LogHandler = Log.Debug;
var library = DynamicLibraryImpl.Create([
new Gen7Plugin(),
]);
_availableAIs = PokemonAI.InstantiateAis(library);
var testCommand = new Command("test", "Run two AIs against each other")
{
new Option<string>("--ai1")
{
Description = "The name of the first AI script to run against the second AI.",
Required = true,
Validators = { ValidateAI },
},
new Option<string>("--ai2")
{
Description = "The name of the second AI script to run against the first AI.",
Required = true,
Validators = { ValidateAI },
},
new Option<int>("--battles")
{
Description = "The number of battles to run between the two AIs.",
Required = false,
DefaultValueFactory = _ => 100,
Validators =
{
result =>
{
if (result.GetValueOrDefault<int>() <= 0)
{
result.AddError("--battles must be a positive integer.");
}
},
},
},
};
testCommand.SetAction(result =>
{
var ai1Name = result.GetRequiredValue<string>("--ai1");
var ai2Name = result.GetRequiredValue<string>("--ai2");
var ai1 = _availableAIs!.First(a =>
string.Equals(a.Name, ai1Name, StringComparison.InvariantCultureIgnoreCase));
var ai2 = _availableAIs!.First(a =>
string.Equals(a.Name, ai2Name, StringComparison.InvariantCultureIgnoreCase));
return TestCommandRunner.RunTestCommand(library, ai1, ai2, result.GetRequiredValue<int>("--battles"));
});
var rootCommand = new RootCommand("PkmnLib.NET AI Runner")
{
testCommand,
};
rootCommand.Description = "A tool to run AI scripts against each other in Pokémon battles.";
var parseResult = rootCommand.Parse(args);
return parseResult.InvokeAsync();
static void ValidateAI(OptionResult result)
{
var aiName = result.GetValueOrDefault<string>();
if (string.IsNullOrWhiteSpace(aiName))
{
result.AddError("must be a non-empty string.");
return;
}
var ai = _availableAIs!.FirstOrDefault(a => a.Name == aiName);
if (ai == null)
{
result.AddError(
$"AI '{aiName}' not found. Available AIs: {string.Join(", ", _availableAIs!.Select(a => a.Name))}");
}
}
}
}