diff --git a/Examples/ConsumerDemo.cs b/Examples/ConsumerDemo.cs index 1493945..bf38bf2 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 }, @@ -36,22 +36,25 @@ internal static void Run() { // } // } // }) - //new Goal( - // name: "Get 5 food", - // desiredState: new() { - // { "food", 5 } - // }) - new ExtremeGoal( - name: "Get food", + new Goal( + name: "Get 5 food", desiredState: new() { - { "food", true } + { "food", 1 } }) + //new ExtremeGoal( + // name: "Get food", + // desiredState: new() { + // { "food", true } + // }) }, actions: new() { new( name: "Walk", - cost: 10, + cost: 6f, executor: GenericExecutor, + preconditions: new() { + { "inCar", false } + }, permutationSelectors: new() { { "location", PermutationSelectorGenerators.SelectFromCollection(locations) } }, @@ -67,7 +70,7 @@ internal static void Run() { ), new( name: "Drive", - cost: 1, + cost: 1f, preconditions: new() { { "inCar", true } }, @@ -85,9 +88,43 @@ internal static void Run() { { "location", "location" } } ), + //new( + // name: "Drive to work", + // cost: 2f, + // preconditions: new() { + // { "inCar", true } + // }, + // comparativePreconditions: new() { + // { "energy", new() { Operator = ComparisonOperator.GreaterThan, Value = 0 } } + // }, + // executor: GenericExecutor, + // arithmeticPostconditions: new() { + // { "energy", -1 } + // }, + // postconditions: new() { + // { "location", "work" } + // } + //), + //new( + // name: "Drive to store", + // cost: 2f, + // preconditions: new() { + // { "inCar", true } + // }, + // comparativePreconditions: new() { + // { "energy", new() { Operator = ComparisonOperator.GreaterThan, Value = 0 } } + // }, + // executor: GenericExecutor, + // arithmeticPostconditions: new() { + // { "energy", -1 } + // }, + // postconditions: new() { + // { "location", "store" } + // } + //), new( - name: "Get in Car", - cost: 1f, + name: "Get in car", + cost: 0.1f, preconditions: new() { { "inCar", false } }, @@ -102,11 +139,29 @@ internal static void Run() { }, executor: GenericExecutor ), + new( + name: "Get out of car", + cost: 0.1f, + preconditions: new() { + { "inCar", true } + }, + comparativePreconditions: new() { + { "energy", new() { Operator = ComparisonOperator.GreaterThan, Value = 0 } } + }, + postconditions: new() { + { "inCar", false } + }, + arithmeticPostconditions: new() { + { "energy", -1 } + }, + executor: GenericExecutor + ), new( name: "Work", - cost: 1f, + cost: 6f, preconditions: new() { { "location", "work" }, + { "inCar", false } }, comparativePreconditions: new() { { "energy", new() { Operator = ComparisonOperator.GreaterThan, Value = 0 } } @@ -119,9 +174,10 @@ internal static void Run() { ), new( name: "Shop", - cost: 1f, + cost: 1.2f, preconditions: new() { - { "location", "store" } + { "location", "store" }, + { "inCar", false } }, comparativePreconditions: new() { { "energy", new() { Operator = ComparisonOperator.GreaterThan, Value = 0 } }, diff --git a/MountainGoap/Internals/ActionAStar.cs b/MountainGoap/Internals/ActionAStar.cs index 411203d..b16d9ac 100644 --- a/MountainGoap/Internals/ActionAStar.cs +++ b/MountainGoap/Internals/ActionAStar.cs @@ -65,9 +65,9 @@ private static float Heuristic(ActionNode actionNode, BaseGoal goal, ActionNode var cost = 0f; if (goal is Goal normalGoal) { normalGoal.DesiredState.Select(kvp => kvp.Key).ToList().ForEach(key => { - if (!actionNode.State.ContainsKey(key)) cost++; - else if (actionNode.State[key] == null && actionNode.State[key] != normalGoal.DesiredState[key]) cost++; - else if (actionNode.State[key] is object obj && !obj.Equals(normalGoal.DesiredState[key])) cost++; + if (!actionNode.State.ContainsKey(key)) cost += actionNode.Cost(actionNode.State); + else if (actionNode.State[key] == null && actionNode.State[key] != normalGoal.DesiredState[key] ) cost += actionNode.Cost(actionNode.State); + else if (actionNode.State[key] is object obj && !obj.Equals(normalGoal.DesiredState[key])) cost += actionNode.Cost(actionNode.State); }); } else if (goal is ExtremeGoal extremeGoal) { @@ -78,20 +78,19 @@ private static float Heuristic(ActionNode actionNode, BaseGoal goal, ActionNode } if (!actionNode.State.ContainsKey(kvp.Key)) cost += float.PositiveInfinity; else if (!current.State.ContainsKey(kvp.Key)) cost += float.PositiveInfinity; - else if (kvp.Value && actionNode.State[kvp.Key] is object a && current.State[kvp.Key] is object b && IsHigherThan(a, b)) cost++; - else if (!kvp.Value && actionNode.State[kvp.Key] is object a2 && current.State[kvp.Key] is object b2 && IsLowerThan(a2, b2)) cost++; + else if (kvp.Value && actionNode.State[kvp.Key] is object a && current.State[kvp.Key] is object b && IsHigherThan(a, b)) cost += actionNode.Cost(actionNode.State); + else if (!kvp.Value && actionNode.State[kvp.Key] is object a2 && current.State[kvp.Key] is object b2 && IsLowerThan(a2, b2)) cost += actionNode.Cost(actionNode.State); } } else if (goal is ComparativeGoal comparativeGoal) { foreach (var kvp in comparativeGoal.DesiredState) { if (!actionNode.State.ContainsKey(kvp.Key)) cost += float.PositiveInfinity; - else if (!current.State.ContainsKey(kvp.Key)) cost += float.PositiveInfinity; else if (kvp.Value.Operator == ComparisonOperator.Undefined) cost += float.PositiveInfinity; - else if (kvp.Value.Operator == ComparisonOperator.Equals && actionNode.State[kvp.Key] is object obj && obj.Equals(comparativeGoal.DesiredState[kvp.Key].Value)) cost++; - else if (kvp.Value.Operator == ComparisonOperator.LessThan && actionNode.State[kvp.Key] is object a && current.State[kvp.Key] is object b && IsLowerThan(a, b)) cost++; - else if (kvp.Value.Operator == ComparisonOperator.GreaterThan && actionNode.State[kvp.Key] is object a2 && current.State[kvp.Key] is object b2 && IsHigherThan(a2, b2)) cost++; - else if (kvp.Value.Operator == ComparisonOperator.LessThanOrEquals && actionNode.State[kvp.Key] is object a3 && current.State[kvp.Key] is object b3 && IsLowerThanOrEquals(a3, b3)) cost++; - else if (kvp.Value.Operator == ComparisonOperator.GreaterThanOrEquals && actionNode.State[kvp.Key] is object a4 && current.State[kvp.Key] is object b4 && IsHigherThanOrEquals(a4, b4)) cost++; + else if (kvp.Value.Operator == ComparisonOperator.Equals && actionNode.State[kvp.Key] is object obj && obj.Equals(comparativeGoal.DesiredState[kvp.Key].Value)) cost += actionNode.Cost(actionNode.State); + else if (kvp.Value.Operator == ComparisonOperator.LessThan && actionNode.State[kvp.Key] is object a && comparativeGoal.DesiredState[kvp.Key] is object b && IsLowerThan(a, b)) cost += actionNode.Cost(actionNode.State); + else if (kvp.Value.Operator == ComparisonOperator.GreaterThan && actionNode.State[kvp.Key] is object a2 && comparativeGoal.DesiredState[kvp.Key] is object b2 && IsHigherThan(a2, b2)) cost += actionNode.Cost(actionNode.State); + else if (kvp.Value.Operator == ComparisonOperator.LessThanOrEquals && actionNode.State[kvp.Key] is object a3 && comparativeGoal.DesiredState[kvp.Key] is object b3 && IsLowerThanOrEquals(a3, b3)) cost += actionNode.Cost(actionNode.State); + else if (kvp.Value.Operator == ComparisonOperator.GreaterThanOrEquals && actionNode.State[kvp.Key] is object a4 && comparativeGoal.DesiredState[kvp.Key] is object b4 && IsHigherThanOrEquals(a4, b4)) cost += actionNode.Cost(actionNode.State); } } return cost;