Skip to content

Commit

Permalink
Refactored the Graphiz debugger code to follow the same style of code…
Browse files Browse the repository at this point in the history
…, removed non-used code in comments, exposed Goal, precond and effects in the ReGoapNode, moved the DebugPlan boolean inside the PlannerSettings, Removed any local information from the pregenerated Debugger cs

Updated the unity FSM example with various minor changes, both to the code and the scene - also upgraded the .NET version to 4.6 in Unity (needed for the Graphiz debugger!)
Added a bat file to automatically generate PDFs out of Graphiz dot files
  • Loading branch information
luxkun committed Apr 22, 2018
1 parent 6163f58 commit 8922720
Show file tree
Hide file tree
Showing 15 changed files with 132 additions and 69 deletions.
22 changes: 22 additions & 0 deletions ParseRaws.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
REM Helper bat file to create ps files with Graphiz's dot
REM Graphiz must be installed and must be in Windows's PATH, alternatively just put your 'dot.exe' directory in the following var

SET "dotPath="
REM Change this to the working directory, in Unity, if you place "ReGoap" inside Assets/, it will be '../../PlanDebugger'
SET "workingPath=../../PlanDebugger/"
SET "rawPath=Raws"
SET "resultsPath=PDFs"
SET "outputType=pdf"
SET "rawSearch=%rawPath%/*"

SET "currentDir=%cd%"

CD %workingPath%
ECHO "Changing working path to %workingPath%. Parsing files in %rawPath%. Saving in %resultsPath% with file type '%outputType%'."

MKDIR %resultsPath%
FOR %%I IN (%rawSearch%) DO %dotPath%dot -T%outputType% %rawPath%/%%I -o %resultsPath%/%%I.pdf

explorer %cd%\%resultsPath%

CD %currentDir%
9 changes: 9 additions & 0 deletions ParseRaws.bat.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion ReGoap/Core/IReGoapAgent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ public interface IReGoapAgent<T, W>
W GetPlanValue(T key);
void SetPlanValue(T key, W value);
bool HasPlanValue(T target);
bool debugPlan { get; set; }
// THREAD SAFE
List<IReGoapGoal<T, W>> GetGoalsSet();
List<IReGoapAction<T, W>> GetActionsSet();
Expand Down
75 changes: 45 additions & 30 deletions ReGoap/Planner/AStar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ public class AStar<T>
private readonly Dictionary<T, INode<T>> stateToNode;
private readonly Dictionary<T, INode<T>> explored;
private readonly List<INode<T>> createdNodes;
// Debug
private bool debugPlan = false;
private PlanDebugger debugger;

public AStar(int maxNodesToExpand = 1000)
{
Expand All @@ -28,46 +31,59 @@ void ClearNodes()
createdNodes.Clear();
}

private bool _debugPlan = false;
private Assets.ReGoap.Planner.PlanDebugger _debugger;

private void _DebugPlan(INode<T> node, INode<T> parent)
private void DebugPlan(INode<T> node, INode<T> parent)
{
if (!_debugPlan) return;
if (null == _debugger)
_debugger = new Assets.ReGoap.Planner.PlanDebugger();

string nodeStr = string.Format("{0} [label=\"GOAL({4}): {5}:\n{1}\nEFFECT:\n{2}\nPRECOND:\n{3}\n\"]", node.GetHashCode(), node.GoalString, node.EffectString, node.PrecondString, node.GetCost(), node.Name);
_debugger.AddNode(nodeStr);
if (!debugPlan) return;
if (debugger == null)
debugger = new PlanDebugger();

string nodeStr = string.Format(@"{0} [label=<
<table border='0' color='black' fontcolor='#F5F5F5'>
<tr> <td colspan='2'><b>{4}</b></td> </tr>
<hr/>
<tr align='left'> <td border='1' sides='rt'><b>Costs</b></td> <td border='1' sides='t'><b>g</b>: {1} ; <b>h</b>: {2} ; <b>c</b>: {3}</td> </tr>
<tr align='left'> <td border='1' sides='rt'><b>Preconditions</b></td> <td border='1' sides='t'>{5}</td> </tr>
<tr align='left'> <td border='1' sides='rt'><b>Effects</b></td> <td border='1' sides='t'>{6}</td> </tr>
<tr align='left'> <td border='1' sides='rt'><b>Goal</b></td> <td border='1' sides='t'>{7}</td> </tr>
</table>
>]",
node.GetHashCode(),
node.GetPathCost(), node.GetHeuristicCost(), node.GetCost(),
node.Name, node.Preconditions != null ? node.Preconditions.ToString() : "",
node.Effects != null ? node.Effects.ToString() : "",
node.Goal != null ? node.Goal.ToString() : "");
debugger.AddNode(nodeStr);

if (parent != null)
{
string connStr = string.Format("{0} -> {1}", parent.GetHashCode(), node.GetHashCode());
_debugger.AddConn(connStr);
debugger.AddConn(connStr);
}
}

private void _EndDebugPlan(INode<T> node)
private void EndDebugPlan(INode<T> node)
{
if (null != _debugger)
if (debugger != null)
{
while (node != null)
{ //mark success path
string nodeStr = string.Format("{0} [style=filled, color=\"#00FF00\"]", node.GetHashCode());
_debugger.AddNode(nodeStr);
{
//mark success path
string nodeStr = string.Format("{0} [style=\"bold\" color=\"darkgreen\"]", node.GetHashCode());
debugger.AddNode(nodeStr);
node = node.GetParent();
}

var txt = _debugger.TransformText();
var txt = debugger.TransformText();
System.IO.Directory.CreateDirectory("PlanDebugger");
System.IO.File.WriteAllText(string.Format("PlanDebugger/DebugPlan_{0}.dot", System.DateTime.Now.ToString("HHmmss_ffff")), txt);
_debugger.Clear();
System.IO.Directory.CreateDirectory("PlanDebugger/Raws");
System.IO.File.WriteAllText(string.Format("PlanDebugger/Raws/DebugPlan_{0}.dot", System.DateTime.Now.ToString("HHmmss_ffff")), txt);
debugger.Clear();
}
}

public INode<T> Run(INode<T> start, T goal, int maxIterations = 100, bool earlyExit = true, bool clearNodes = true, bool debugPlan = false)
{
_debugPlan = debugPlan;
this.debugPlan = debugPlan;

frontier.Clear();
stateToNode.Clear();
Expand All @@ -80,17 +96,16 @@ public INode<T> Run(INode<T> start, T goal, int maxIterations = 100, bool earlyE

frontier.Enqueue(start, start.GetCost());

_DebugPlan(start, null);
DebugPlan(start, null);

var iterations = 0;
while ((frontier.Count > 0) && (iterations < maxIterations) && (frontier.Count + 1 < frontier.MaxSize))
{
var node = frontier.Dequeue();
//Utilities.ReGoapLogger.Log(string.Format("\n++++Explored action: {0}({3}), state ({1})\n goal ({2})\n effect: ({4})", node.Name, node.GetState(), node.GoalString, node.GetCost(), node.EffectString));
if (node.IsGoal(goal))
{
ReGoapLogger.Log("[Astar] Success iterations: " + iterations);
_EndDebugPlan(node);
EndDebugPlan(node);
return node;
}
explored[node.GetState()] = node;
Expand All @@ -106,7 +121,7 @@ public INode<T> Run(INode<T> start, T goal, int maxIterations = 100, bool earlyE
if (earlyExit && child.IsGoal(goal))
{
ReGoapLogger.Log("[Astar] (early exit) Success iterations: " + iterations);
_EndDebugPlan(child);
EndDebugPlan(child);
return child;
}
var childCost = child.GetCost();
Expand All @@ -123,15 +138,15 @@ public INode<T> Run(INode<T> start, T goal, int maxIterations = 100, bool earlyE
break;
}

_DebugPlan(child, node);
DebugPlan(child, node);

//Utilities.ReGoapLogger.Log(string.Format(" Enqueue frontier: {0}, cost: {1}", child.Name, childCost));
frontier.Enqueue(child, childCost);
stateToNode[state] = child;
}
}
ReGoapLogger.LogWarning("[Astar] failed.");
_EndDebugPlan(null);
EndDebugPlan(null);
return null;
}
}
Expand All @@ -146,11 +161,11 @@ public interface INode<T>
float GetPathCost();
INode<T> GetParent();
bool IsGoal(T goal);
//int AstarID { get; } //used for planDebug

string Name { get; }
string GoalString { get; }
string EffectString { get; }
string PrecondString { get; }
T Goal { get; }
T Effects { get; }
T Preconditions { get; }

int QueueIndex { get; set; }
float Priority { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// the code is regenerated.
// </auto-generated>
// ------------------------------------------------------------------------------
namespace Assets.ReGoap.Planner
namespace ReGoap.Planner
{
using System.Linq;
using System.Text;
Expand All @@ -18,7 +18,7 @@ namespace Assets.ReGoap.Planner
/// Class to produce the template output
/// </summary>

#line 1 "E:\works\programs\GameProjects\TestGround\TestReGOAP\Assets\ReGoap\Planner\PlanDebugger.tt"
#line 1 "PlanDebugger.tt"
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "14.0.0.0")]
public partial class PlanDebugger : PlanDebuggerBase
{
Expand All @@ -30,40 +30,40 @@ public virtual string TransformText()
{
this.Write("\r\ndigraph {\r\n\r\nnode [shape=box]\r\n\r\n");

#line 11 "E:\works\programs\GameProjects\TestGround\TestReGOAP\Assets\ReGoap\Planner\PlanDebugger.tt"
#line 11 "PlanDebugger.tt"
foreach(var n in nodeDeclarations) {

#line default
#line hidden

#line 12 "E:\works\programs\GameProjects\TestGround\TestReGOAP\Assets\ReGoap\Planner\PlanDebugger.tt"
#line 12 "PlanDebugger.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(n));

#line default
#line hidden
this.Write("\r\n");

#line 13 "E:\works\programs\GameProjects\TestGround\TestReGOAP\Assets\ReGoap\Planner\PlanDebugger.tt"
#line 13 "PlanDebugger.tt"
}

#line default
#line hidden
this.Write("\r\n");

#line 15 "E:\works\programs\GameProjects\TestGround\TestReGOAP\Assets\ReGoap\Planner\PlanDebugger.tt"
#line 15 "PlanDebugger.tt"
foreach(var c in nodeConnections) {

#line default
#line hidden

#line 16 "E:\works\programs\GameProjects\TestGround\TestReGOAP\Assets\ReGoap\Planner\PlanDebugger.tt"
#line 16 "PlanDebugger.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(c));

#line default
#line hidden
this.Write("\r\n");

#line 17 "E:\works\programs\GameProjects\TestGround\TestReGOAP\Assets\ReGoap\Planner\PlanDebugger.tt"
#line 17 "PlanDebugger.tt"
}

#line default
Expand All @@ -72,7 +72,7 @@ public virtual string TransformText()
return this.GenerationEnvironment.ToString();
}

#line 21 "E:\works\programs\GameProjects\TestGround\TestReGOAP\Assets\ReGoap\Planner\PlanDebugger.tt"
#line 21 "PlanDebugger.tt"


public List<string> nodeDeclarations = new List<string>();
Expand Down
13 changes: 13 additions & 0 deletions ReGoap/Planner/PlanDebugger.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions ReGoap/Planner/PlanDebugger.tt.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 8922720

Please sign in to comment.