diff --git a/PkmnLib.Dynamic/AI/AIHelpers.cs b/PkmnLib.Dynamic/AI/AIHelpers.cs index 304c70a..2d76774 100644 --- a/PkmnLib.Dynamic/AI/AIHelpers.cs +++ b/PkmnLib.Dynamic/AI/AIHelpers.cs @@ -6,8 +6,14 @@ using PkmnLib.Static.Utils; namespace PkmnLib.Dynamic.AI; +/// +/// Helper functions for AI +/// public static class AIHelpers { + /// + /// Estimates the amount of damage that will be done by a move against a target. + /// public static uint CalculateDamageEstimation(IMoveData move, IPokemon user, IPokemon target, IDynamicLibrary library) { diff --git a/PkmnLib.Dynamic/AI/AILogging.cs b/PkmnLib.Dynamic/AI/AILogging.cs index bd70b80..0bb236b 100644 --- a/PkmnLib.Dynamic/AI/AILogging.cs +++ b/PkmnLib.Dynamic/AI/AILogging.cs @@ -1,8 +1,18 @@ namespace PkmnLib.Dynamic.AI; +/// +/// Logging implementation for AI +/// public static class AILogging { + /// + /// The actual function called by the logging. + /// public static Action LogHandler { get; set; } = _ => { }; + /// + /// Forwarding function. + /// + /// public static void LogInformation(string message) => LogHandler(message); } \ No newline at end of file diff --git a/PkmnLib.Dynamic/AI/Explicit/AIMoveState.cs b/PkmnLib.Dynamic/AI/Explicit/AIMoveState.cs index a7c3914..8d19a0f 100644 --- a/PkmnLib.Dynamic/AI/Explicit/AIMoveState.cs +++ b/PkmnLib.Dynamic/AI/Explicit/AIMoveState.cs @@ -3,14 +3,25 @@ using PkmnLib.Static.Moves; namespace PkmnLib.Dynamic.AI.Explicit; +/// +/// Container wrapper for a move and its user. +/// public class AIMoveState { + /// public AIMoveState(IPokemon user, IMoveData move) { User = user; Move = move; } + /// + /// The user that's being wrapper + /// public IPokemon User { get; } + + /// + /// The move that's being wrapper + /// public IMoveData Move { get; } } \ No newline at end of file diff --git a/PkmnLib.Dynamic/AI/Explicit/ExplicitAI.Switch.cs b/PkmnLib.Dynamic/AI/Explicit/ExplicitAI.Switch.cs index bea4ee8..1a0c59d 100644 --- a/PkmnLib.Dynamic/AI/Explicit/ExplicitAI.Switch.cs +++ b/PkmnLib.Dynamic/AI/Explicit/ExplicitAI.Switch.cs @@ -45,8 +45,7 @@ public partial class ExplicitAI return false; } var battleSide = pokemon.BattleData!.BattleSide; - var bestReplacement = - ChooseBestReplacementPokemon(pokemon.BattleData!.Position, terribleMoves, usablePokemon, battleSide); + var bestReplacement = ChooseBestReplacementPokemon(terribleMoves, usablePokemon, battleSide); if (bestReplacement is null) { AILogging.LogInformation( @@ -57,8 +56,8 @@ public partial class ExplicitAI return true; } - private IPokemon? ChooseBestReplacementPokemon(byte position, bool terribleMoves, - IReadOnlyList usablePokemon, IBattleSide battleSide) + private IPokemon? ChooseBestReplacementPokemon(bool terribleMoves, IReadOnlyList usablePokemon, + IBattleSide battleSide) { var options = usablePokemon.Where((_, index) => { diff --git a/PkmnLib.Dynamic/AI/Explicit/ExplicitAIHandlers.cs b/PkmnLib.Dynamic/AI/Explicit/ExplicitAIHandlers.cs index fe5ac56..0962465 100644 --- a/PkmnLib.Dynamic/AI/Explicit/ExplicitAIHandlers.cs +++ b/PkmnLib.Dynamic/AI/Explicit/ExplicitAIHandlers.cs @@ -3,17 +3,35 @@ using PkmnLib.Static.Utils; namespace PkmnLib.Dynamic.AI.Explicit; +/// +/// An option where a move is used against a target +/// public record struct MoveOption(AIMoveState Move, IBattle Battle, IPokemon? Target, uint EstimatedDamage = 0); +/// +/// A function that takes an explicit AI and a move option and returns a boolean value. +/// public delegate bool AIBoolHandler(IExplicitAI ai, MoveOption option); +/// +/// A function for returning whether a Pokemon should switch. +/// public delegate bool AISwitchBoolHandler(IExplicitAI ai, IPokemon pokemon, IBattle battle, IReadOnlyList reserves); +/// +/// A function for returning the base power of a move. +/// public delegate void AIMoveBasePowerHandler(IExplicitAI ai, MoveOption option, ref int score); +/// +/// A function for returning a score +/// public delegate void AIScoreMoveHandler(IExplicitAI ai, MoveOption option, ref int score); +/// +/// Explicit AI Handlers are a library that allow plugins to explicitly indicate AI preferences. +/// public interface IReadOnlyExplicitAIHandlers { /// @@ -86,28 +104,50 @@ public interface IReadOnlyExplicitAIHandlers /// void ApplyGenerateMoveAgainstTargetScoreModifiers(IExplicitAI ai, MoveOption option, ref int score); + /// + /// Functions that indicate whether a Pokemon should switch + /// IReadOnlyDictionary ShouldSwitchFunctions { get; } + /// + /// Indicates whether a Pokemon should switch into another Pokemon + /// bool ShouldSwitch(IExplicitAI ai, IPokemon pokemon, IBattle battle, IReadOnlyList reserves); + /// + /// Functions that indicate whether a Pokemon should NOT switch + /// IReadOnlyDictionary ShouldNotSwitchFunctions { get; } + /// + /// Indicates whether a Pokemon should NOT switch into another Pokemon + /// bool ShouldNotSwitch(IExplicitAI ai, IPokemon pokemon, IBattle battle, IReadOnlyList reserves); + /// + /// Scores abilities + /// IReadOnlyDictionary AbilityRanking { get; } } +/// public class ExplicitAIHandlers : IReadOnlyExplicitAIHandlers { /// IReadOnlyDictionary IReadOnlyExplicitAIHandlers.MoveFailureCheck => MoveFailureCheck; + /// + /// Checks whether a move will fail + /// public FunctionHandlerDictionary MoveFailureCheck { get; } = new(); /// public bool MoveWillFail(IExplicitAI ai, StringKey functionCode, MoveOption option) => MoveFailureCheck.TryGetValue(functionCode, out var handler) && handler(ai, option); + /// + /// Checks whether a move will fail against a target + /// public FunctionHandlerDictionary MoveFailureAgainstTargetCheck { get; } = new(); /// @@ -118,12 +158,18 @@ public class ExplicitAIHandlers : IReadOnlyExplicitAIHandlers public bool MoveWillFailAgainstTarget(IExplicitAI ai, StringKey functionCode, MoveOption option) => MoveFailureAgainstTargetCheck.TryGetValue(functionCode, out var handler) && handler(ai, option); + /// + /// Functions to score a move + /// public FunctionHandlerDictionary MoveEffectScore { get; } = []; /// IReadOnlyDictionary IReadOnlyExplicitAIHandlers.MoveEffectScore => MoveEffectScore; + /// + /// Functions to score a move against a target + /// public FunctionHandlerDictionary MoveEffectAgainstTargetScore = []; /// @@ -137,6 +183,9 @@ public class ExplicitAIHandlers : IReadOnlyExplicitAIHandlers IReadOnlyDictionary IReadOnlyExplicitAIHandlers.MoveEffectAgainstTargetScore => MoveEffectAgainstTargetScore; + /// + /// Functions that indicate a moves base power + /// public FunctionHandlerDictionary MoveBasePower = []; /// @@ -150,6 +199,9 @@ public class ExplicitAIHandlers : IReadOnlyExplicitAIHandlers IReadOnlyDictionary IReadOnlyExplicitAIHandlers.MoveBasePower => MoveBasePower; + /// + /// Functions that indicate a moves score + /// public FunctionHandlerDictionary GeneralMoveScore = []; /// @@ -193,6 +245,7 @@ public class ExplicitAIHandlers : IReadOnlyExplicitAIHandlers IReadOnlyDictionary IReadOnlyExplicitAIHandlers.ShouldSwitchFunctions => ShouldSwitchFunctions; + /// public bool ShouldSwitch(IExplicitAI ai, IPokemon pokemon, IBattle battle, IReadOnlyList reserves) { var shouldSwitch = false; @@ -203,6 +256,9 @@ public class ExplicitAIHandlers : IReadOnlyExplicitAIHandlers return shouldSwitch; } + /// + /// Functions that indicate whether we should not switch + /// public FunctionHandlerDictionary ShouldNotSwitchFunctions = []; /// @@ -210,6 +266,9 @@ public class ExplicitAIHandlers : IReadOnlyExplicitAIHandlers IReadOnlyDictionary IReadOnlyExplicitAIHandlers.ShouldNotSwitchFunctions => ShouldNotSwitchFunctions; + /// + /// Functions to rank an ability + /// public FunctionHandlerDictionary AbilityRanking = []; ///