Skip to content

Commit

Permalink
Fix: Prevent connecting actions with conflicting effects #314
Browse files Browse the repository at this point in the history
  • Loading branch information
crashkonijn committed Nov 29, 2024
1 parent fb9566d commit b0c6ac0
Show file tree
Hide file tree
Showing 7 changed files with 360 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
{
public interface IKeyResolver
{
string GetKey(IConnectable action, ICondition condition);
string GetKey(IConnectable action, IEffect effect);
string GetKey(ICondition condition);
string GetKey(IEffect effect);
bool AreConflicting(IEffect effect, ICondition condition);
void SetWorldData(IWorldData globalWorldData);
}
}
36 changes: 27 additions & 9 deletions Package/Runtime/CrashKonijn.Goap.Resolver/GraphBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@ public Graph Build(IEnumerable<IConnectable> actions)
return graph;
}

private void ConnectNodes(INode node, Dictionary<string, List<INode>> effectMap,
Dictionary<string, List<INode>> conditionMap, IGraph graph)
private void ConnectNodes(
INode node, Dictionary<string, List<INode>> effectMap,
Dictionary<string, List<INode>> conditionMap, IGraph graph
)
{
if (!graph.ChildNodes.Contains(node) && !node.IsRootNode)
graph.ChildNodes.Add(node);
Expand All @@ -49,17 +51,19 @@ private void ConnectNodes(INode node, Dictionary<string, List<INode>> effectMap,
if (actionNodeCondition.Connections.Any())
continue;

var key = this.keyResolver.GetKey(node.Action, actionNodeCondition.Condition);
var key = this.keyResolver.GetKey(actionNodeCondition.Condition);

if (!effectMap.ContainsKey(key))
continue;

actionNodeCondition.Connections = effectMap[key].ToArray();
var connections = effectMap[key].Where(x => !this.HasConflictingConditions(node, x)).ToArray();

actionNodeCondition.Connections = connections;

foreach (var connection in actionNodeCondition.Connections)
{
connection.Effects.First(x => this.keyResolver.GetKey(connection.Action, x.Effect) == key)
.Connections = conditionMap[key].ToArray();
connection.Effects.First(x => this.keyResolver.GetKey(x.Effect) == key)
.Connections = conditionMap[key].Where(x => !this.HasConflictingConditions(node, x)).ToArray();
}

foreach (var subNode in actionNodeCondition.Connections)
Expand All @@ -69,6 +73,20 @@ private void ConnectNodes(INode node, Dictionary<string, List<INode>> effectMap,
}
}

private bool HasConflictingConditions(INode node, INode otherNode)
{
foreach (var condition in node.Conditions)
{
foreach (var otherEffects in otherNode.Effects)
{
if (this.keyResolver.AreConflicting(otherEffects.Effect, condition.Condition))
return true;
}
}

return false;
}

private Dictionary<string, List<INode>> GetEffectMap(INode[] actionNodes)
{
var map = new Dictionary<string, List<INode>>();
Expand All @@ -77,7 +95,7 @@ private Dictionary<string, List<INode>> GetEffectMap(INode[] actionNodes)
{
foreach (var actionNodeEffect in actionNode.Effects)
{
var key = this.keyResolver.GetKey(actionNode.Action, actionNodeEffect.Effect);
var key = this.keyResolver.GetKey(actionNodeEffect.Effect);

if (!map.ContainsKey(key))
map[key] = new List<INode>();
Expand All @@ -97,7 +115,7 @@ private Dictionary<string, List<INode>> GetConditionMap(INode[] actionNodes)
{
foreach (var actionNodeConditions in actionNode.Conditions)
{
var key = this.keyResolver.GetKey(actionNode.Action, actionNodeConditions.Condition);
var key = this.keyResolver.GetKey(actionNodeConditions.Condition);

if (!map.ContainsKey(key))
map[key] = new List<INode>();
Expand All @@ -109,4 +127,4 @@ private Dictionary<string, List<INode>> GetConditionMap(INode[] actionNodes)
return map;
}
}
}
}
17 changes: 11 additions & 6 deletions Package/Runtime/CrashKonijn.Goap.Runtime/Resolvers/KeyResolver.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
using System;
using CrashKonijn.Agent.Core;
using CrashKonijn.Goap.Core;

namespace CrashKonijn.Goap.Runtime
{
public class KeyResolver : KeyResolverBase
{
protected override string GetKey(IAction action, ICondition condition)
public override string GetKey(ICondition condition)
{
return condition.WorldKey.Name + this.GetText(condition.Comparison);
}

protected override string GetKey(IAction action, IEffect effect)
public override string GetKey(IEffect effect)
{
return effect.WorldKey.Name + this.GetText(effect.Increase);
}

protected override string GetKey(IGoal action, ICondition condition)
public override bool AreConflicting(IEffect effect, ICondition condition)
{
return condition.WorldKey.Name + this.GetText(condition.Comparison);
if (effect.WorldKey != condition.WorldKey)
return false;

if (this.GetText(effect.Increase) == this.GetText(condition.Comparison))
return false;

return true;
}

private string GetText(bool value)
Expand All @@ -44,4 +49,4 @@ private string GetText(Comparison comparison)
throw new Exception($"Comparison type {comparison} not supported");
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System;
using CrashKonijn.Agent.Core;
using CrashKonijn.Goap.Core;
using CrashKonijn.Goap.Core;

namespace CrashKonijn.Goap.Runtime
{
Expand All @@ -13,23 +11,8 @@ public void SetWorldData(IWorldData globalWorldData)
this.WorldData = globalWorldData;
}

public string GetKey(IConnectable action, ICondition condition)
{
if (action is IAction tAction)
return this.GetKey(tAction, (ICondition) condition);
if (action is IGoal tGoal)
return this.GetKey(tGoal, (ICondition) condition);

throw new Exception($"Unsupported type {action.GetType()}");
}

public string GetKey(IConnectable action, IEffect effect)
{
return this.GetKey((IAction) action, (IEffect) effect);
}

protected abstract string GetKey(IAction action, ICondition key);
protected abstract string GetKey(IAction action, IEffect key);
protected abstract string GetKey(IGoal goal, ICondition key);
public abstract string GetKey(IEffect key);
public abstract string GetKey(ICondition key);
public abstract bool AreConflicting(IEffect effect, ICondition condition);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace CrashKonijn.Goap.UnitTests.Data
{
public class TestKeyResolver : IKeyResolver
{
public string GetKey(IConnectable action, ICondition condition)
public string GetKey(ICondition condition)
{
if (condition is StringCondition stringCondition)
return stringCondition.GetKey();
Expand All @@ -16,7 +16,7 @@ public string GetKey(IConnectable action, ICondition condition)
throw new Exception("Should not happen");
}

public string GetKey(IConnectable action, IEffect effect)
public string GetKey(IEffect effect)
{
if (effect is StringEffect stringEffect)
return stringEffect.GetKey();
Expand All @@ -27,6 +27,11 @@ public string GetKey(IConnectable action, IEffect effect)
throw new Exception("Should not happen");
}

public bool AreConflicting(IEffect effect, ICondition condition)
{
return false;
}

public void SetWorldData(IWorldData globalWorldData) { }
}
}
Loading

0 comments on commit b0c6ac0

Please sign in to comment.