implement naive db
This commit is contained in:
parent
63a7fc3114
commit
8a9b05e9a1
@ -2,3 +2,5 @@ cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
|
||||
|
||||
add_executable(main1 main1.cpp)
|
||||
|
||||
target_compile_features(main1 PUBLIC cxx_std_17)
|
||||
|
||||
|
@ -1,11 +1,15 @@
|
||||
// this is a naive-ish implementation
|
||||
// this is not pure naive, since it implements the less-branch Criterion compare variant discussed in the valve talk
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <limits>
|
||||
#include <random>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
@ -50,6 +54,7 @@ struct Query {
|
||||
}
|
||||
|
||||
bool match_criterion(const Criterion& crit) const {
|
||||
// TODO: lookup is performed 2x, optimize
|
||||
return dict.count(crit.key) && crit.compare(dict.at(crit.key));
|
||||
}
|
||||
|
||||
@ -68,7 +73,15 @@ struct Query {
|
||||
struct Response {
|
||||
Rules rules;
|
||||
|
||||
// normally you would give it the caller(entity f is called on?)
|
||||
std::function<void(void)> f;
|
||||
|
||||
Response(void) = default;
|
||||
Response(const Rules& r, std::function<void(void)>&& _f) : rules(r), f(_f) {}
|
||||
|
||||
size_t criterion_size(void) const {
|
||||
return rules.crits.size();
|
||||
}
|
||||
};
|
||||
|
||||
// special keys (usually bucketalbe):
|
||||
@ -76,6 +89,53 @@ struct Response {
|
||||
// - "who": which char talked. gonna name this differently
|
||||
|
||||
struct ResponseDB {
|
||||
std::vector<Response> responses;
|
||||
|
||||
// returns index
|
||||
template<typename RNG>
|
||||
std::optional<size_t> match(const Query& q, RNG& rng) const {
|
||||
size_t crit_count_for_match = 0;
|
||||
|
||||
std::vector<size_t> match_list;
|
||||
|
||||
//for (const auto& r : responses) {
|
||||
for (size_t i = 0; i < responses.size(); i++) {
|
||||
const auto& r = responses[i];
|
||||
|
||||
// skip rules with less criteria matching
|
||||
if (r.criterion_size() < crit_count_for_match) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (q.match_rules(r.rules)) {
|
||||
if (crit_count_for_match < r.criterion_size()) {
|
||||
match_list.clear();
|
||||
crit_count_for_match = r.criterion_size();
|
||||
}
|
||||
|
||||
match_list.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (match_list.empty()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::shuffle(match_list.begin(), match_list.end(), rng);
|
||||
|
||||
return match_list.front();
|
||||
}
|
||||
|
||||
template<typename RNG>
|
||||
bool match_and_run(const Query& q, RNG& rng) const {
|
||||
auto idx = match(q, rng);
|
||||
if (idx.has_value()) {
|
||||
responses.at(*idx).f();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
int main(void) {
|
||||
@ -148,9 +208,11 @@ int main(void) {
|
||||
.add("in_danger", 1.f)
|
||||
;
|
||||
|
||||
// add junk to q2
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
q2.add(std::to_string(i) + "asdf", (i - 155) * 12399.3249f);
|
||||
// add junk to q1
|
||||
// 100'000 -> >200ms
|
||||
// 10'000 -> >ms
|
||||
for (int i = 0; i < 10'000; i++) {
|
||||
q1.add(std::to_string(i) + "asdf", (i - 155) * 12399.3249f);
|
||||
}
|
||||
|
||||
assert(q1.match_criterion(hp_not_critical) == true);
|
||||
@ -162,6 +224,20 @@ int main(void) {
|
||||
assert(q1.match_rules(rules_hero_idle_chatter) == true);
|
||||
assert(q2.match_rules(rules_hero_idle_chatter) == false);
|
||||
|
||||
// response DB
|
||||
|
||||
std::mt19937 rng{1337*433};
|
||||
|
||||
ResponseDB db;
|
||||
size_t fn_called = 0;
|
||||
db.responses.emplace_back(rules_hero_idle_chatter, [&fn_called](){ fn_called++; });
|
||||
|
||||
assert(fn_called == 0);
|
||||
assert(db.match_and_run(q1, rng) == true);
|
||||
assert(fn_called == 1);
|
||||
assert(db.match_and_run(q2, rng) == false);
|
||||
assert(fn_called == 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user