Skip to content

Commit

Permalink
Merge branch 'master' into feature/allow-to-requeue-agent
Browse files Browse the repository at this point in the history
  • Loading branch information
crashkonijn authored Oct 4, 2023
2 parents 5cbea8e + 38cca16 commit b053d6a
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 0 deletions.
26 changes: 26 additions & 0 deletions Package/Runtime/CrashKonijn.Goap.Resolver/GraphResolverJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ public void Execute()
closedSet.TryAdd(currentNode.Index, currentNode);
openSet.Remove(currentNode.Index);

// If this node has a condition that is false and has no connections, it is unresolvable
if (this.HasUnresolvableCondition(currentNode.Index))
{
continue;
}

foreach (var conditionIndex in this.NodeConditions.GetValuesForKey(currentNode.Index))
{
if (runData.ConditionsMet[conditionIndex])
Expand All @@ -114,6 +120,7 @@ public void Execute()
var newG = currentNode.G + this.RunData.Costs[neighborIndex];
NodeData neighbor;

// Current neighbour is not in the open set
if (!openSet.TryGetValue(neighborIndex, out neighbor))
{
neighbor = new NodeData
Expand All @@ -127,6 +134,7 @@ public void Execute()
continue;
}

// This neighbour has a lower cost
if (newG < neighbor.G)
{
neighbor.G = newG;
Expand Down Expand Up @@ -167,5 +175,23 @@ private void RetracePath(NodeData startNode, NativeHashMap<int, NodeData> closed
currentNode = closedSet[currentNode.ParentIndex];
}
}

private bool HasUnresolvableCondition(int currentIndex)
{
foreach (var conditionIndex in this.NodeConditions.GetValuesForKey(currentIndex))
{
if (this.RunData.ConditionsMet[conditionIndex])
{
continue;
}

if (!this.ConditionConnections.GetValuesForKey(conditionIndex).MoveNext())
{
return true;
}
}

return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -485,5 +485,69 @@ public void Resolve_ShouldNotResolve_CompletedCondition()
result.Should().HaveCount(2);
result.Should().Equal(incompleteAction, rootAction);
}

[Test]
public void Resolve_ShouldNotResolve_ActionWithFalseConditionWithoutConnections()
{
var rootConnection = new TestConnection("Root");
var availableConnection = new TestConnection("Available");
var unavailableConnection = new TestConnection("Unavailable");

var goal = new TestAction("goal")
{
Conditions = new ICondition[] { rootConnection }
};

var expensiveAction = new TestAction("expensiveAction")
{
Effects = new IEffect[] { rootConnection },
};

var unavailableAction = new TestAction("subAction")
{
Effects = new IEffect[] { rootConnection },
Conditions = new ICondition[] { unavailableConnection, availableConnection }
};

var shouldNotResolveAction = new TestAction("shouldNotResolveAction")
{
Effects = new IEffect[] { availableConnection },
};

var actions = new IAction[] { goal, expensiveAction, unavailableAction, shouldNotResolveAction };
var resolver = new GraphResolver(actions, new TestKeyResolver());

var executableBuilder = resolver.GetExecutableBuilder();
executableBuilder
.SetExecutable(expensiveAction, true)
.SetExecutable(unavailableAction, false)
.SetExecutable(shouldNotResolveAction, true);

var positionBuilder = resolver.GetPositionBuilder();
var costBuilder = resolver.GetCostBuilder();
costBuilder.SetCost(expensiveAction, 100f);

var conditionBuilder = resolver.GetConditionBuilder();

// Act
var handle = resolver.StartResolve(new RunData
{
StartIndex = 0,
IsExecutable = new NativeArray<bool>(executableBuilder.Build(), Allocator.TempJob),
Positions = new NativeArray<float3>(positionBuilder.Build(), Allocator.TempJob),
Costs = new NativeArray<float>(costBuilder.Build(), Allocator.TempJob),
ConditionsMet = new NativeArray<bool>(conditionBuilder.Build(), Allocator.TempJob),
DistanceMultiplier = 1f
});

var result = handle.Complete();

// Cleanup
resolver.Dispose();

// Assert
result.Should().HaveCount(1);
result.Should().Equal(expensiveAction);
}
}
}

0 comments on commit b053d6a

Please sign in to comment.