ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Lua, C++ behavior tree 최적화3
    카테고리 없음 2025. 4. 3. 16:53

    현재 구조에서는 부모 노드(Parent Node)로 이동하는 기능이 없습니다.
    이제 각 노드가 부모 정보를 저장하도록 변경하고,
    필요할 때 부모 노드로 이동 가능하도록 개선해보겠습니다! 🚀


    📌 개선 사항

    1️⃣ 각 노드에 parent 포인터 추가
    2️⃣ 부모로 이동하는 기능 (getParent()) 추가
    3️⃣ Lua에서 정의한 트리 구조를 유지하면서, 부모 정보를 자동으로 설정


    🔹 수정된 C++ 코드

    1️⃣ Node 클래스 (부모 정보 추가)

    class Node {
    protected:
        Node* parent = nullptr;  // 부모 노드 포인터
    
    public:
        virtual ~Node() = default;
        virtual bool execute() = 0;
    
        void setParent(Node* p) { parent = p; }
        Node* getParent() { return parent; }
    };
    

    2️⃣ CompositeNode (부모 설정)

    class CompositeNode : public Node {
    protected:
        std::vector<std::unique_ptr<Node>> children;
        NodeType type;
    
    public:
        explicit CompositeNode(NodeType type) : type(type) {}
    
        void addChild(std::unique_ptr<Node> child) {
            child->setParent(this);  // 부모 설정
            children.push_back(std::move(child));
        }
    
        bool execute() override {
            if (type == NodeType::Sequence) {
                for (auto& child : children) {
                    if (!child->execute()) return false;
                }
                return true;
            } else {  // Selector
                for (auto& child : children) {
                    if (child->execute()) return true;
                }
                return false;
            }
        }
    };
    

    3️⃣ Leaf 노드 (부모 설정)

    class Leaf : public Node {
    protected:
        Monster* monster;
    
    public:
        explicit Leaf(Monster* monster) : monster(monster) {}
        virtual ~Leaf() = default;
        virtual bool execute() override = 0;
    };
    

    4️⃣ Lua에서 트리 생성 시 부모 설정

    std::unique_ptr<Node> parseNode(lua_State* L, int index, Monster* monster, Node* parent = nullptr) {
        lua_getfield(L, index, "type");
        std::string typeStr = lua_tostring(L, -1);
        lua_pop(L, 1);
    
        std::unique_ptr<Node> node;
    
        if (typeStr == "Leaf") {
            lua_getfield(L, index, "name");
            std::string name = lua_tostring(L, -1);
            lua_pop(L, 1);
            node = LeafFactory::createLeaf(name, monster);
        } 
        else if (typeStr == "Sequence" || typeStr == "Selector") {
            lua_getfield(L, index, "children");
            auto compositeNode = std::make_unique<CompositeNode>(
                (typeStr == "Sequence") ? NodeType::Sequence : NodeType::Selector
            );
    
            if (lua_istable(L, -1)) {
                int len = luaL_len(L, -1);
                for (int i = 1; i <= len; ++i) {
                    lua_rawgeti(L, -1, i);
                    auto child = parseNode(L, lua_gettop(L), monster, compositeNode.get());
                    compositeNode->addChild(std::move(child));
                    lua_pop(L, 1);
                }
            }
            lua_pop(L, 1);
            node = std::move(compositeNode);
        }
    
        if (node) {
            node->setParent(parent);  // 부모 설정
        }
    
        return node;
    }
    

    5️⃣ 부모로 이동하는 예제 코드

    class CheckEnemyLeaf : public Leaf {
    public:
        using Leaf::Leaf;
    
        bool execute() override {
            if (monster) {
                std::cout << monster->getName() << " is checking for enemies...\n";
    
                // 부모 노드로 이동
                if (Node* parent = getParent()) {
                    std::cout << "Moving up to parent node!\n";
                }
            }
            return true;
        }
    };
    

    🔹 주요 개선점

    기능 기존 변경

    부모 이동 가능 여부 ❌ 부모 노드 정보 없음 ✅ Node* parent 추가
    부모 노드로 이동 ❌ 불가능 ✅ getParent() 로 가능
    트리 생성 시 부모 설정 ❌ 자동 설정 없음 ✅ setParent() 활용

    🎯 최종 결과

    이제 각 노드에서 부모 노드로 이동 가능하고,
    트리에서 상위 노드의 로직을 활용할 수 있습니다! 🚀🔥

Designed by Tistory.