diff --git a/Examples/ConsumerDemo.cs b/Examples/ConsumerDemo.cs index f871e3f..d80b8a9 100644 --- a/Examples/ConsumerDemo.cs +++ b/Examples/ConsumerDemo.cs @@ -19,7 +19,7 @@ internal static void Run() { var agent = new Agent( name: "Consumer Agent", state: new() { - { "food", 4 }, + { "food", 0 }, { "energy", 100 }, { "money", 0 }, { "inCar", false }, @@ -35,7 +35,17 @@ internal static void Run() { Value = 5 } } - }) + }), + //new ComparativeGoal( + // name: "Get at least 5 money", + // desiredState: new() { + // { + // "money", new() { + // Operator = ComparisonOperator.GreaterThanOrEquals, + // Value = 5 + // } + // } + // }) //new Goal( // name: "Get 5 food", // desiredState: new() { diff --git a/MountainGoap/Internals/ActionAStar.cs b/MountainGoap/Internals/ActionAStar.cs index 5de84e6..6b3c886 100644 --- a/MountainGoap/Internals/ActionAStar.cs +++ b/MountainGoap/Internals/ActionAStar.cs @@ -130,38 +130,7 @@ private static bool IsHigherThanOrEquals(object a, object b) { } private bool MeetsGoal(ActionNode actionNode, ActionNode current) { - if (goal is Goal normalGoal) { -#pragma warning disable S3267 // Loops should be simplified with "LINQ" expressions - foreach (var kvp in normalGoal.DesiredState) { - if (!actionNode.State.ContainsKey(kvp.Key)) return false; - else if (actionNode.State[kvp.Key] == null && actionNode.State[kvp.Key] != normalGoal.DesiredState[kvp.Key]) return false; - else if (actionNode.State[kvp.Key] is object obj && obj != null && !obj.Equals(normalGoal.DesiredState[kvp.Key])) return false; - } -#pragma warning restore S3267 // Loops should be simplified with "LINQ" expressions - } - else if (goal is ExtremeGoal extremeGoal) { - if (actionNode.Action == null) return false; - foreach (var kvp in extremeGoal.DesiredState) { - if (!actionNode.State.ContainsKey(kvp.Key)) return false; - else if (!current.State.ContainsKey(kvp.Key)) return false; - else if (kvp.Value && actionNode.State[kvp.Key] is object a && current.State[kvp.Key] is object b && IsLowerThan(a, b)) return false; - else if (!kvp.Value && actionNode.State[kvp.Key] is object a2 && current.State[kvp.Key] is object b2 && IsHigherThan(a2, b2)) return false; - } - } - else if (goal is ComparativeGoal comparativeGoal) { - if (actionNode.Action == null) return false; - foreach (var kvp in comparativeGoal.DesiredState) { - if (!actionNode.State.ContainsKey(kvp.Key)) return false; - else if (!current.State.ContainsKey(kvp.Key)) return false; - else if (kvp.Value.Operator == ComparisonOperator.Undefined) return false; - else if (kvp.Value.Operator == ComparisonOperator.Equals && actionNode.State[kvp.Key] is object obj && !obj.Equals(comparativeGoal.DesiredState[kvp.Key].Value)) return false; - else if (kvp.Value.Operator == ComparisonOperator.LessThan && actionNode.State[kvp.Key] is object a && comparativeGoal.DesiredState[kvp.Key].Value is object b && !IsLowerThan(a, b)) return false; - else if (kvp.Value.Operator == ComparisonOperator.GreaterThan && actionNode.State[kvp.Key] is object a2 && comparativeGoal.DesiredState[kvp.Key].Value is object b2 && !IsHigherThan(a2, b2)) return false; - else if (kvp.Value.Operator == ComparisonOperator.LessThanOrEquals && actionNode.State[kvp.Key] is object a3 && comparativeGoal.DesiredState[kvp.Key].Value is object b3 && !IsLowerThanOrEquals(a3, b3)) return false; - else if (kvp.Value.Operator == ComparisonOperator.GreaterThanOrEquals && actionNode.State[kvp.Key] is object a4 && comparativeGoal.DesiredState[kvp.Key].Value is object b4 && !IsHigherThanOrEquals(a4, b4)) return false; - } - } - return true; + return Utils.MeetsGoal(goal, actionNode, current); } } } diff --git a/MountainGoap/Internals/Utils.cs b/MountainGoap/Internals/Utils.cs index 85d3eb7..784653b 100644 --- a/MountainGoap/Internals/Utils.cs +++ b/MountainGoap/Internals/Utils.cs @@ -74,5 +74,40 @@ internal static bool IsHigherThanOrEquals(object a, object b) { if (a is DateTime dateTimeA && b is DateTime dateTimeB) return dateTimeA >= dateTimeB; return false; } + + internal static bool MeetsGoal(BaseGoal goal, ActionNode actionNode, ActionNode current) { + if (goal is Goal normalGoal) { +#pragma warning disable S3267 // Loops should be simplified with "LINQ" expressions + foreach (var kvp in normalGoal.DesiredState) { + if (!actionNode.State.ContainsKey(kvp.Key)) return false; + else if (actionNode.State[kvp.Key] == null && actionNode.State[kvp.Key] != normalGoal.DesiredState[kvp.Key]) return false; + else if (actionNode.State[kvp.Key] is object obj && obj != null && !obj.Equals(normalGoal.DesiredState[kvp.Key])) return false; + } +#pragma warning restore S3267 // Loops should be simplified with "LINQ" expressions + } + else if (goal is ExtremeGoal extremeGoal) { + if (actionNode.Action == null) return false; + foreach (var kvp in extremeGoal.DesiredState) { + if (!actionNode.State.ContainsKey(kvp.Key)) return false; + else if (!current.State.ContainsKey(kvp.Key)) return false; + else if (kvp.Value && actionNode.State[kvp.Key] is object a && current.State[kvp.Key] is object b && IsLowerThan(a, b)) return false; + else if (!kvp.Value && actionNode.State[kvp.Key] is object a2 && current.State[kvp.Key] is object b2 && IsHigherThan(a2, b2)) return false; + } + } + else if (goal is ComparativeGoal comparativeGoal) { + if (actionNode.Action == null) return false; + foreach (var kvp in comparativeGoal.DesiredState) { + if (!actionNode.State.ContainsKey(kvp.Key)) return false; + else if (!current.State.ContainsKey(kvp.Key)) return false; + else if (kvp.Value.Operator == ComparisonOperator.Undefined) return false; + else if (kvp.Value.Operator == ComparisonOperator.Equals && actionNode.State[kvp.Key] is object obj && !obj.Equals(comparativeGoal.DesiredState[kvp.Key].Value)) return false; + else if (kvp.Value.Operator == ComparisonOperator.LessThan && actionNode.State[kvp.Key] is object a && comparativeGoal.DesiredState[kvp.Key].Value is object b && !IsLowerThan(a, b)) return false; + else if (kvp.Value.Operator == ComparisonOperator.GreaterThan && actionNode.State[kvp.Key] is object a2 && comparativeGoal.DesiredState[kvp.Key].Value is object b2 && !IsHigherThan(a2, b2)) return false; + else if (kvp.Value.Operator == ComparisonOperator.LessThanOrEquals && actionNode.State[kvp.Key] is object a3 && comparativeGoal.DesiredState[kvp.Key].Value is object b3 && !IsLowerThanOrEquals(a3, b3)) return false; + else if (kvp.Value.Operator == ComparisonOperator.GreaterThanOrEquals && actionNode.State[kvp.Key] is object a4 && comparativeGoal.DesiredState[kvp.Key].Value is object b4 && !IsHigherThanOrEquals(a4, b4)) return false; + } + } + return true; + } } } \ No newline at end of file