gpt4 book ai didi

c++ - 构造行为排序函数

转载 作者:搜寻专家 更新时间:2023-10-31 02:11:23 25 4
gpt4 key购买 nike

我正在为我的一个项目编写一个简单的行为模型引擎。我现在一直在尝试制作一个特定的函数 constexpr。

问题在底部,其余是背景信息

框架工作原理的简短说明

行为节点可以返回三种状态之一:

enum class State { Fail, Success, Running }; 

默认叶节点总是返回这三种状态之一:

constexpr inline auto success() { return []{ return State::Success; }; }                                 
constexpr inline auto fail() { return []{ return State::Fail; }; }
constexpr inline auto running() { return []{ return State::Running; }; }

可以执行不同的操作,例如取反:

constexpr inline auto operator~(auto rule) {
return [rule]{
const auto result = rule();
return result == State::Fail ? State::Success :
result == State::Success ? State::Fail :
State::Running;
};
}

...和其他逻辑操作:

constexpr inline auto operator&&(auto left, auto right) {
return [left, right]{
const auto lresult = left();
const auto rresult = right();
return (lresult == State::Fail || rresult == State::Fail) ? State::Fail :
(lresult == State::Success && rresult == State::Success) ? State::Success :
State::Running;
};
}

最后是评价函数,很简单:

inline State execute(auto rule) {
return rule();
}

例子

CHECK( State::Success == execute(success() && success()) );
CHECK( State::Fail == execute(success() && fail()) );

例子

编写此示例时我无法访问 C++17 编译器,因此无法实际编译和测试它。

在这里,我们混合使用可能在编译时评估的规则,以及一些在运行时评估的规则。一个家伙走到一扇锁着的门前并试图打开它,如果他有 key 是在编译时决定的。

auto walking                 = false;
auto door_open = false;
auto is_at_door = false;
constexpr auto dude_has_key = false;

constexpr auto unlock_door = []{return []{
return dude_has_key ? State::Success : State::Fail;
};};

const auto walk_to_door = [&]{return []{
if(walking) { // Stop at the door
walking = false;
is_at_door = true;
return State::Success;
}
if(!is_at_door) {
walking = true;
return State::Running;
}
return State::Fail; // Cannot walk through the door
};};

const auto open_door = [&]{return []{
// We want to compile-time check if the door is locked
// hence we never check for that condition here.
if(!door_open) {
door_open = true;
}
return State::Success
};};

const auto rules = sequence({walk_to_door, unlock_door && open_door});
CHECK( State::Running == execute(rules) ); // Walking to door
CHECK( State::Fail == execute(rules) ); // Cannot unlock door

例子

编写此示例时我无法访问 C++17 编译器,因此无法实际编译和测试它。

struct MyThing {
static constexpr bool PropertyA = true;
static constexpr int PowerLevel = 42;
};

struct YourThing {
static constexpr bool PropertyA = false;
static constexpr int PowerLevel = 43;
};

constexpr auto has_property_a(auto thing) {
return []{ return decltype(thing)::PropertyA ? State::Success :: State::Fail; };
}

constexpr auto has_minimum_power_level(auto thing, auto min_pl) {
return []{ return decltype(thing)::PowerLevel > min_pl ? Satet::Success ::State::Fail; };
}

template<typename ThingA, typename ThingB>
constexpr auto rule = sequence({
has_property_a(ThingA{}),
has_minimum_power_level(ThingB{}, 9000)
});
execute(sequence({rule<MyThing,YourThing>, __some_runtime_rule});

当前问题

...是应该通过以下测试的排序函数

CHECK( State::Success       == execute(sequence({success(), success(), success()})) );
CHECK( State::Fail == execute(sequence({success(), success(), fail()})) );
CHECK( State::Running == execute(sequence({success(), success(), running()})) );
// last (fail) never evaluated due to 2nd being running
CHECK( State::Running == execute(sequence({success(), running(), fail()})) );

换句话说,当序列中的所有节点都返回 State::Success 时,它返回 State::Success。如果遇到 State::Running,它会在那里“等待”,直到 State::SuccessState::FailState::Fail 使整个序列失败。

这个函数的当前 make-the-tests-pass-implementation 看起来像

using Rule = std::function<State()>;
inline auto sequence(std::initializer_list<Rule> rules) {
return [rules]{
auto result = State::Success;
for(auto next : rules) {
const auto next_result = next();
result = (result == State::Success && next_result == State::Success) ? State::Success :
(result == State::Success && next_result == State::Running) ? State::Running :
State::Fail;
if(result == State::Fail || result == State::Running) {
return result;
}
}
return State::Success;
};
}

现在我该如何制作这个 constexpr?

最佳答案

如果你的序列只是为了重复应用&&,那么你可以用折叠来指定它

允许空的sequence()(返回等同于success)

template <typename ... Rules>
constexpr auto sequence(Rules ... rules)
{
return [rules...](){ return State::Success && ... && rules(); };
}

或者要求至少一条规则

template <typename First, typename ... Rules>
constexpr auto sequence(First first, Rules ... rules)
{
return [first, rules...](){ return first() && ... && rules(); };
}

关于c++ - 构造行为排序函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43674431/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com