395 lines
9.2 KiB
C++
395 lines
9.2 KiB
C++
#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;
|
||
}
|