我创建了一个小决策树,你认为它是什么,我能纠正什么?我想为树创建一个代码,它看起来是这样的:

我的实施:
using System;
using System.Collections.Generic;
using System.Text;
public interface TreeNode
{
bool nodeState { get; }
bool Evaluate();
}
/// <summary>
/// Returns true when one of childs returns true
/// </summary>
public class Selector : TreeNode
{
private List<TreeNode> childNodes;
public bool nodeState { get; private set; } = false;
public Selector(List<TreeNode> childNodes) { this.childNodes = childNodes; }
public bool Evaluate()
{
foreach (TreeNode node in childNodes)
if (node.Evaluate())
{
nodeState = true;
return true;
}
nodeState = false;
return false;
}
}
/// <summary>
/// Returns true when all childs return true
/// </summary>
public class Sequence : TreeNode
{
private List<TreeNode> childNodes;
public bool nodeState { get; private set; } = false;
public Sequence(List<TreeNode> childNodes) { this.childNodes = childNodes; }
public bool Evaluate()
{
foreach (TreeNode node in childNodes)
if (!node.Evaluate())
{
nodeState = false;
return false;
}
nodeState = true;
return true;
}
}
/// <summary>
/// Has only one child, negate it
/// </summary>
public class Inverter : TreeNode
{
private TreeNode nodeToInvert;
public bool nodeState { get; private set; } = false;
public Inverter(TreeNode nodeToInvert) { this.nodeToInvert = nodeToInvert; }
public bool Evaluate()
{
nodeState = !nodeToInvert.Evaluate();
return !nodeToInvert.Evaluate();
}
}
/// <summary>
/// Leaf of tree, returns delegate of bool function that is setted in it's constuctor
/// </summary>
public class ActionNode : TreeNode
{
public delegate bool ActionNodeDelegate();
private ActionNodeDelegate action;
public bool nodeState { get; private set; } = false;
public ActionNode(ActionNodeDelegate action)
{
this.action = action;
}
public bool Evaluate()
{
nodeState = action();
return action();
}
}
public static class DecisionTree
{
public static void Test()
{
while (true)
{
AITree tree = new AITree();
Console.ReadKey();
Console.Clear();
}
}
}
public class AITree
{
private float playerDistanceFromEnemy;
private int playerPower;
private ActionNode IsInAttackRange;
private ActionNode IsVisible;
private ActionNode EstimatePlayerPower;
private Sequence Attack;
private Inverter Patrol;
private Sequence Escape;
private Selector Root;
bool PlayerIsInAttackRange() => playerDistanceFromEnemy < 5;
bool PlayerIsVisible() => playerDistanceFromEnemy < 8;
bool PlayerIsTooPowerful() => playerPower > 3;
public AITree()
{
Random rnd = new Random();
playerDistanceFromEnemy = (float)rnd.Next(10, 100) / 10;
playerPower = rnd.Next(1, 6);
IsInAttackRange = new ActionNode(PlayerIsInAttackRange);
IsVisible = new ActionNode(PlayerIsVisible);
EstimatePlayerPower = new ActionNode(PlayerIsTooPowerful);
Attack = new Sequence(new List<TreeNode> { IsInAttackRange, IsVisible }); // Attack only when player is visible and is in attack range
Patrol = new Inverter(Attack); // Patrol only when not attacking
Escape = new Sequence(new List<TreeNode> { IsVisible, EstimatePlayerPower }); // Escape when player is visible and player is too powerful
Root = new Selector(new List<TreeNode> { Escape, Patrol, Attack }); // Escape has the biggest priority
Root.Evaluate();
ShowCommunicats();
}
private void ShowCommunicats()
{
StringBuilder sb = new StringBuilder();
Console.WriteLine($"Player distance: {playerDistanceFromEnemy}, Player power: {playerPower}");
sb.AppendLine();
Console.WriteLine(Patrol.nodeState ? "enemy will patrol" : "enemy will not patrol");
Console.WriteLine(Escape.nodeState ? "enemy escapes" : "enemy will not escape");
Console.WriteLine(IsVisible.nodeState ? "enemy see player" : "enemy dont see player");
Console.WriteLine(IsInAttackRange.nodeState ? "player is in the enemy attack distance" : "player is too far to hit");
Console.WriteLine(Attack.nodeState ? "enemy attacks" : "enemy will not attack");
}
}发布于 2017-01-27 16:25:08
Evaluate()方法Selector/Sequence不会在所有子节点上调用Evaluate()。因此,您不能确定noteState对所有节点都是正确的。但是您的示例代码在运行Root.Evaluate()后使用所有节点的节点状态。Evaluate中获得NRE )IEnumerable<TreeNode>作为参数类型,以便更灵活。您可以使用LINQ:
public bool Evaluate() => nodeState = childNodes.Any(n => n.Evaluate());
public bool Evaluate() => nodeState = childNodes.All(n => n.Evaluate());但是,如上所述,您应该为所有子节点调用Evaluate()。
public bool Evaluate()
{
childNodes.ForEach(n => nodeState |= n.Evaluate());
return nodeState;
}
public bool Evaluate()
{
nodeState = true;
childNodes.ForEach(n => nodeState &= n.Evaluate());
return nodeState;
}在命名约定中有C#
您的需求让我想起了框架来自@Dmitry的可数和不可数集。
https://codereview.stackexchange.com/questions/153773
复制相似问题