105 lines
3.7 KiB
C#
105 lines
3.7 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;
|
|
using Serilog.Core;
|
|
using Serilog.Events;
|
|
|
|
namespace AIRunner;
|
|
|
|
internal static class Program
|
|
{
|
|
private static List<PokemonAI>? _availableAIs;
|
|
|
|
internal static LoggingLevelSwitch LogLevelSwitch { get; } = new(LogEventLevel.Information);
|
|
|
|
private static Task<int> Main(string[] args)
|
|
{
|
|
Log.Logger = new LoggerConfiguration().MinimumLevel.ControlledBy(LogLevelSwitch).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<bool>("--debug")
|
|
{
|
|
Description = "Enable debug logging.",
|
|
},
|
|
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 debug = result.GetValue<bool>("--debug");
|
|
LogLevelSwitch.MinimumLevel = debug ? LogEventLevel.Debug : LogEventLevel.Information;
|
|
|
|
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))}");
|
|
}
|
|
}
|
|
}
|
|
} |