using System;
using System.Dynamic;
using System.Linq;
using WeEngine.Enum;
using WeEngine.Packages;
using WeEngine.Strategy.Eval;
namespace WeEngine.Module
{
public class EvolutionEval : IEvalStrategy
{
///
/// 匹配关键字
///
///
public virtual void MatchKeyWord(NodeBase node)
{
if (node.CurPackageInfo.NodeState != NodeState.Running)
{
return;
}
string role = node.ExtendData?.BehaviorRole ?? "";
string scenePath= node.ExtendData?.ScenePath ?? "";
bool checkRole= node.ExtendData?.CheckRole ?? false;
var keyWords = checkRole
? node.CurPackageInfo.NotMatchKeywords?.Where(a =>
a.Roles.Any(s => s.Equal(role)) &&
(string.IsNullOrEmpty(scenePath) || a.NodePath.StartsWith(scenePath))).ToList()
: node.CurPackageInfo.NotMatchKeywords
?.Where(a => (string.IsNullOrEmpty(scenePath) || a.NodePath.StartsWith(scenePath))).ToList();
string word = node.ExtendData?.BehaviorWord ?? "";
if (keyWords != null && keyWords.Any() && !string.IsNullOrEmpty(word))
{
foreach (var keyWord in keyWords)
{
if (keyWord.Words.Any())
{
foreach (var str in keyWord.Words)
{
if (word.Contains(str))
{
dynamic obj = new ExpandoObject();
obj.MatchWord = word;
keyWord.ExtendData = obj;
keyWord.CurPackageInfo.RunnerManager?.Instance?.Run(keyWord, OperationType.MatchSuccess);
break;
}
}
}
}
}
}
///
/// 获取当前节点评分
///
///
public virtual decimal GetActualScore(NodeBase node)
{
if (node.NodeState == NodeState.New)
{
return 0;
}
if (node.CorrectionScore > 0)
{
return node.CorrectionScore > node.NodeFullScore ? node.NodeFullScore : node.CorrectionScore;
}
decimal actualScore;
switch (node.NodeType)
{
case NodeType.ScenePackage:
actualScore = node.HasChild ? node.Children.Where(a => a.NodeState != NodeState.New).Sum(a => a.ActualScore) : 0;
break;
case NodeType.SceneRound:
actualScore = node.HasChild ? node.Children.Where(a => a.NodeState != NodeState.New).Sum(a => a.ActualScore) : 0;
break;
case NodeType.SceneFlowBlock:
actualScore = node.Weights == 0 ? 0 : node.NodeFullScore * (node.ActualWeights / node.Weights);
break;
case NodeType.SceneFlow:
actualScore = node.Weights == 0 ? 0 : node.NodeFullScore * (node.ActualWeights / node.Weights);
break;
case NodeType.FlowNode:
var flow = ((FlowNode)node).SelfFlow;
actualScore = flow.ChildFullWeights == 0 ? 0 : flow.NodeFullScore * (node.ActualWeights / flow.ChildFullWeights);
break;
case NodeType.SceneInfo:
actualScore = node.ChildFullWeights == 0 ? 0 : node.NodeFullScore * (node.ActualWeights / node.ChildFullWeights);
break;
case NodeType.Behavior:
actualScore = node.Weights == 0 ? 0 : node.NodeFullScore * (node.ActualWeights / node.Weights);
break;
case NodeType.KeyWord:
actualScore = ((KeywordNode)node).HasMatched ? node.NodeFullScore : 0;
break;
default:
actualScore = node.Weights == 0 ? 0 : node.NodeFullScore * (node.ActualWeights / node.Weights);
break;
}
actualScore = Math.Round(actualScore, 2);
return actualScore;
}
///
/// 获取当前节点评分
///
///
public virtual decimal GetActualWeights(NodeBase node)
{
if (node.NodeState == NodeState.New)
return 0;
decimal actualWeights;
switch (node.NodeType)
{
case NodeType.ScenePackage:
actualWeights = 0;
break;
//case NodeType.SceneRound:
//{
// actualWeights = 0;
// var children = node.Children?.Where(a => a.NodeState != NodeState.New).ToList();
// if (node.ChildFullWeights != 0 && children != null && children.Any())
// {
// foreach (var child in children)
// {
// actualWeights += child.ActualWeights * (child.Weights / node.ChildFullWeights);
// }
// }
// break;
//}
case NodeType.SceneFlow:
if (node.ChildFullWeights == 0)
return 0;
FlowNode flowNode = node.HasChild ? (FlowNode)node.Children.FirstOrDefault(a => a.NodeState != NodeState.New) : null;
var childActualWeights = GetAllFlowNodeWeights(flowNode);
actualWeights = (childActualWeights / node.ChildFullWeights) * node.Weights;
break;
case NodeType.FlowNode:
var sceneInfos = ((FlowNode)node).SceneInfos;
actualWeights = 0;
if (sceneInfos != null && sceneInfos.Count > 0)
{
foreach (var sceneInfo in sceneInfos)
{
var sceneFullWeights=((FlowNode) node).SceneFullWeights;
if (sceneInfo.NodeState != NodeState.New && sceneFullWeights != 0)
{
actualWeights += sceneInfo.ActualWeights * (sceneInfo.Weights / sceneFullWeights);
}
}
}
break;
case NodeType.SceneInfo:
actualWeights = 0;
if (node.NodeState == NodeState.New || ((SceneNode)node).IsImportantNegative)
return actualWeights;
actualWeights = node.HasChild ? node.Children.Sum(a => a.ActualWeights) : 0;
//var behaviorInfos = node.HasChild ? node.Children.Select(a => (BehaviorInfo)a).ToList() : null;
//if (behaviorInfos != null && behaviorInfos.Any())
//{
// actualWeights = behaviorInfos.Where(a => a.BehaviorScoreType == BehaviorScoreType.Normal).Sum(a => a.ActualWeights);
// actualWeights = actualWeights - behaviorInfos.Where(a => a.BehaviorScoreType == BehaviorScoreType.Negative)
// .Sum(a => a.ActualWeights);
//}
if (actualWeights < 0)
{
actualWeights = 0;
}
break;
case NodeType.Behavior:
actualWeights = 0;
var n = (BehaviorNode)node;
if (node.NodeState == NodeState.New || n.ImportantNegative)
return actualWeights;
else if (n.BehaviorScoreType == BehaviorScoreType.Negative)
{
actualWeights = node.HasChild ? 0 - node.Children.Sum(a => a.ActualWeights) : 0;
}
else
{
bool isAuto = false;
if (node.CurPackageInfo.AssessAuto)
{
isAuto = true;
foreach (var role in n.BehaviorRoles)
{
if (node.CurPackageInfo.AssessRoles.Any(a=>role.Equal(a)))
{
isAuto = false;
break;
}
}
}
actualWeights = isAuto ? node.Weights : node.HasChild ? node.Children.Sum(a => a.ActualWeights) : 0;
}
break;
case NodeType.KeyWord:
actualWeights = node.Parent.ChildFullWeights == 0 ? 0 :
((KeywordNode)node).HasMatched
? (node.Weights / node.Parent.ChildFullWeights) * node.Parent.Weights
: 0;
break;
default:
{
actualWeights = 0;
var children = node.Children?.Where(a => a.NodeState != NodeState.New).ToList();
if (node.ChildFullWeights != 0 && children != null && children.Any())
{
foreach (var child in children)
{
actualWeights += child.ActualWeights * (child.Weights / node.ChildFullWeights);
}
}
break;
}
}
actualWeights = Math.Round(actualWeights, 2);
return actualWeights;
}
///
/// 获取当前节点满分
///
///
public virtual decimal GetNodeFullScore(NodeBase node)
{
if (node.NodeState == NodeState.New)
return 0;
decimal fullScore;
switch (node.NodeType)
{
case NodeType.ScenePackage:
//方案包总分 为各轮次分总和
fullScore = node.Children.Sum(a => a.NodeFullScore);
break;
case NodeType.SceneRound:
fullScore = ((SceneRoundNode)node).RoundFullScore;
break;
case NodeType.FlowNode:
var childFullWeights = ((FlowNode) node).SelfFlow.ChildFullWeights;
if (childFullWeights == 0)
return 0;
fullScore = ((FlowNode)node).SelfFlow.NodeFullScore * (node.ChildFullWeights / childFullWeights);
break;
case NodeType.SceneInfo:
var sceneFullWeights = ((FlowNode) node.Parent).SceneFullWeights;
if (sceneFullWeights == 0)
return 0;
fullScore = node.Parent.NodeFullScore * (node.Weights / sceneFullWeights);
break;
default:
if (node.Parent.ChildFullWeights == 0)
return 0;
fullScore = node.HasParent ? node.Parent.NodeFullScore * (node.Weights / node.Parent.ChildFullWeights) : 0;
break;
}
fullScore = Math.Round(fullScore, 2);
return fullScore;
}
///
/// 获取子节点权重之和
///
///
public virtual decimal GetChildFullWeights(NodeBase node)
{
if (node.NodeState == NodeState.New)
{
return 0;
}
decimal fullWeights;
switch (node.NodeType)
{
case NodeType.SceneRound:
case NodeType.SceneFlowBlock:
//运行的权重总和
fullWeights = node.HasChild
? node.Children.Where(a => a.NodeState != NodeState.New).Sum(a => a.Weights)
: 0;
break;
case NodeType.SceneFlow:
FlowNode flowNode = node.HasChild ? (FlowNode)node.Children.FirstOrDefault(a => a.NodeState != NodeState.New) : null;
fullWeights = GetAllFlowNodeWeights(flowNode, false);
break;
case NodeType.FlowNode:
fullWeights = 0;
var sceneInfos = ((FlowNode)node).SceneInfos;
if (sceneInfos != null && sceneInfos.Count > 0)
{
foreach (var sceneInfo in sceneInfos)
{
var sceneFullWeights = ((FlowNode) node).SceneFullWeights;
fullWeights += sceneFullWeights == 0
? 0
: sceneInfo.ChildFullWeights * (sceneInfo.Weights / sceneFullWeights);
}
}
break;
case NodeType.SceneInfo:
fullWeights = node.HasChild ? node.Children.Select(a => (BehaviorNode)a).Where(a => a.BehaviorScoreType == BehaviorScoreType.Normal).Sum(a => a.Weights) : 0;
break;
case NodeType.Behavior:
fullWeights = node.HasChild ? node.Children.Sum(a => a.Weights) : 0;
break;
case NodeType.KeyWord:
return 0;
default:
fullWeights = node.HasChild ? node.Children.Sum(a => a.Weights) : 0;
break;
}
fullWeights = Math.Round(fullWeights, 2);
return fullWeights;
}
///
/// 获取定性评估结果
///
///
public string GetEvalQualitativeResult(PackageNode node, string exp)
{
try
{
if (string.IsNullOrEmpty(exp) || node.Children?.Count <= 0)
{
return "";
}
decimal fullScore = node.Children?.Sum(a => a.NodeFullScore) ?? 0;
if (fullScore == 0)
{
return "";
}
var per = (node.Children?.Sum(a => a.ActualScore) * 100) / fullScore;
var arr1 = exp.Split('@').ToList();
foreach (var s in arr1)
{
var arr2 = s.Split('|');
if (arr2.Length > 1 && int.TryParse(arr2[0], out var resultPer))
{
if (per < resultPer)
{
return arr2[1];
}
}
else if (arr2.Length == 1)
{
return arr2[0];
}
}
}
catch (Exception e)
{
Console.WriteLine(e);
return "";
}
return "";
}
///
/// 获取节点的权重
///
///
///
///
private decimal GetAllFlowNodeWeights(FlowNode node, bool isActual = true)
{
decimal weights = 0;
if (node == null || node.NodeState == NodeState.New)
{
return weights;
}
weights = isActual ? node.ActualWeights : node.ChildFullWeights;
FlowNode nextNode = node.HasChild ? node.Children.FirstOrDefault(a => a.NodeState != NodeState.New) : null;
if (nextNode != null)
{
weights += GetAllFlowNodeWeights(nextNode, isActual);
}
return weights;
}
}
}