Files
mir_server/server/robot/AI/AITree.cpp
aixianling 5c9f1dae4a init
2025-01-09 17:45:40 +08:00

395 lines
9.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "stdafx.h"
#include "AITree.h"
#include <iostream>
#include <sstream>
using namespace std;
AINodeHelper * AINodeHelper::m_nodeHlper(NULL);
AINodeHelper * AINodeHelper::SharedHelper()
{
if(m_nodeHlper == NULL)
m_nodeHlper = new AINodeHelper();
return m_nodeHlper;
}
void AINodeHelper::RegisterNodeCreate(int type, BaseNodeCreate create)
{
m_type2Create[type] = create;
}
void AINodeHelper::RegisterNodeName(int type, std::string name)
{
m_type2Name[type] = name;
}
AINodeBase * AINodeHelper::CreateNode(int type)
{
AINodeBase * nodeBase = NULL;
do
{
map<int, BaseNodeCreate>::iterator iter = m_type2Create.find(type);
if(iter == m_type2Create.end())
break;
nodeBase = (*iter).second();
if(nodeBase == NULL)
break;
map<int, string>::iterator iter_name = m_type2Name.find(type);
if(iter_name != m_type2Name.end())
{
string & name = (*iter_name).second;
nodeBase->SetName(name);
}
}while(0);
return nodeBase;
}
AINodeBase * AINodeHelper::CreateNodeTree(vector<AINodeDescribe> des)
{
if(des.size() == 0)
return NULL;
OutputMsg(rmTip, "CreateNodeTree all count = %d", (int)des.size());
map<int, AINodeBase *> m_type2Create;
AINodeBase * rootNode = NULL;
for(vector<AINodeDescribe>::iterator iter = des.begin(); iter != des.end(); ++iter)
{
AINodeDescribe &item = (*iter);
AINodeBase * node = CreateNode(item.AINodeTypeId);
OutputMsg(rmTip, "CreateNodeTree %d", item.AINodeTypeId);
if(node == NULL)
continue;
if(strlen(item.Describe) != 0)
{
node->SetDescribe(item.Describe);
}
m_type2Create[item.Id] = node;
if(item.ParentId == 0)
{
rootNode = node;
}
else
{
do
{
AINodeBase * parentNode = m_type2Create[item.ParentId];
if(parentNode == NULL)
break;
AIListNode * listParentNode = dynamic_cast<AIListNode *>(parentNode);
if(listParentNode != NULL)
{
listParentNode->AddChildNode(node);
break;
}
AISingleNode * singleNode = dynamic_cast<AISingleNode *>(parentNode);
if(singleNode != NULL)
{
singleNode->SetChildNode(node);
break;
}
} while (0);
}
}
return rootNode;
}
void AINodeHelper::printAITree(AINodeBase * node, int level)
{
ostringstream oss;
for (int i = 0; i < level; ++i)
{
oss << "\t";
}
oss << node->GetDescribe() << " " << node->GetDescribe() << " " << node;
OutputMsg(rmTip, oss.str().c_str());
do
{
AIListNode * listNode = dynamic_cast<AIListNode *>(node);
if(listNode != NULL)
{
vector<AINodeBase *> & childs = listNode->GetChildNodes();
if(childs.size() > 0)
{
for (std::vector<AINodeBase *>::iterator i = childs.begin(); i != childs.end(); ++i)
{
printAITree(*i, level + 1);
}
}
break;
}
AISingleNode * singleNode = dynamic_cast<AISingleNode *>(node);
if(singleNode != NULL)
{
AINodeBase * child = singleNode->GetChildNode();
if(child != NULL)
{
printAITree(child, level + 1);
}
}
} while (0);
}
//最根层节点
void AINodeBase::Destroy()
{
OutputMsg(rmTip, "Destroy %s %p", GetDescribe().c_str(), this);
delete this;
}
void AINodeBase::SetDescribe(std::string describe)
{
m_nodeDescribe = describe;
}
string AINodeBase::GetDescribe()
{
return m_nodeDescribe;
}
void AINodeBase::SetName(string name)
{
m_nodeName = name;
}
string AINodeBase::GetName()
{
return m_nodeName;
}
//列表节点
void AIListNode::AddChildNode(AINodeBase * node)
{
m_childNodes.push_back(node);
}
std::vector<AINodeBase *> & AIListNode::GetChildNodes()
{
return m_childNodes;
}
void AIListNode::Destroy()
{
if(m_childNodes.size() > 0)
{
for(vector<AINodeBase *>::iterator iter = m_childNodes.begin(); iter != m_childNodes.end(); ++iter)
{
(*iter)->Destroy();
}
}
AINodeBase::Destroy();
}
//单条节点
void AISingleNode::SetChildNode(AINodeBase * node)
{
if(m_childNode != node)
{
if(m_childNode != NULL)
m_childNode->Destroy();
m_childNode = node;
}
}
AINodeBase * AISingleNode::GetChildNode()
{
return m_childNode;
}
void AISingleNode::Destroy()
{
if(m_childNode != NULL)
{
m_childNode->Destroy();
}
AINodeBase::Destroy();
}
//选择节点
AINodeRegister<AISelectNode> AISelectNode::reg(ANBT_SELECT, "AISelectNode");
NodeExecState AISelectNode::Execute(CRobotClient* pActor, int level, bool isLog)
{
if(isLog)
{
ostringstream oss;
for (int i = 0; i < level; ++i) {
oss << " ";
}
oss << GetDescribe();
OutputMsg(rmTip, "%s", oss.str().c_str());
}
for(vector<AINodeBase *>::iterator iter = m_childNodes.begin(); iter != m_childNodes.end(); ++iter)
{
AINodeBase * node = (*iter);
NodeExecState nRet = node->Execute(pActor, level + 1, isLog);
if(isLog && !node->IsMiddle())
{
ostringstream oss;
for (int i = 0; i < level + 1; ++i) {
oss << " ";
}
oss << node->GetDescribe() << " Execute " << nRet;
OutputMsg(rmTip, "%s", oss.str().c_str());
}
switch (nRet)
{
case NodeExec_Success:
case NodeExec_Running:
return nRet;
}
}
return NodeExec_Fail;
}
//顺序节点
AINodeRegister<AISequenceNode> AISequenceNode::reg(ANBT_SEQUENCE, "AISequenceNode");
NodeExecState AISequenceNode::Execute(CRobotClient* pActor, int level, bool isLog)
{
if(isLog)
{
ostringstream oss;
for (int i = 0; i < level; ++i) {
oss << " ";
}
oss << GetDescribe();
OutputMsg(rmTip, "%s", oss.str().c_str());
}
for(vector<AINodeBase *>::iterator iter = m_childNodes.begin(); iter != m_childNodes.end(); ++iter)
{
AINodeBase * node = (*iter);
NodeExecState nRet = node->Execute(pActor, level + 1, isLog);
if(isLog && !node->IsMiddle())
{
ostringstream oss;
for (int i = 0; i < level + 1; ++i) {
oss << " ";
}
oss << node->GetDescribe() << " Execute " << nRet;
OutputMsg(rmTip, "%s", oss.str().c_str());
}
switch (nRet)
{
case NodeExec_Fail:
case NodeExec_Running:
return nRet;
}
}
return NodeExec_Success;
}
//并列节点
AINodeRegister<AIParallelNode> AIParallelNode::reg(ANBT_PARALLEL, "AIParallelNode");
NodeExecState AIParallelNode::Execute(CRobotClient* pActor, int level, bool isLog)
{
if(isLog)
{
ostringstream oss;
for (int i = 0; i < level; ++i) {
oss << " ";
}
oss << GetDescribe();
OutputMsg(rmTip, "%s", oss.str().c_str());
}
int nRetCnt[3] = {0};
for(vector<AINodeBase *>::iterator iter = m_childNodes.begin(); iter != m_childNodes.end(); ++iter)
{
AINodeBase * node = (*iter);
NodeExecState nRet = node->Execute(pActor, level + 1, isLog);
if(isLog && !node->IsMiddle())
{
ostringstream oss;
for (int i = 0; i < level + 1; ++i) {
oss << " ";
}
oss << node->GetDescribe() << " Execute " << nRet;
OutputMsg(rmTip, "%s", oss.str().c_str());
}
if (nRet == NodeExec_Running)
return NodeExec_Running;
++ nRetCnt[nRet];
}
//全部succ返回succ否则fail
return (nRetCnt[NodeExec_Fail] == 0) ? NodeExec_Success : NodeExec_Fail;
}
//取反节点
AINodeRegister<AINotNode> AINotNode::reg(ANBT_NOT, "AINotNode");
NodeExecState AINotNode::Execute(CRobotClient* pActor, int level, bool isLog)
{
NodeExecState nRet = (m_childNode->Execute(pActor, level + 1, isLog));
if(isLog)
{
ostringstream oss;
for (int i = 0; i < level + 1; ++i) {
oss << " ";
}
if(m_childNode != NULL)
{
oss << m_childNode->GetDescribe() << " Execute " << !nRet;
}
else
{
oss << "no child";
}
OutputMsg(rmTip, "%s", oss.str().c_str());
}
switch (nRet)
{
case NodeExec_Fail:
return NodeExec_Success;
case NodeExec_Success:
return NodeExec_Fail;
case NodeExec_Running:
return NodeExec_Running;
}
assert(false);
return NodeExec_Fail;
}