basic criterion and rules querying
This commit is contained in:
parent
c0db6e3c30
commit
63a7fc3114
@ -1,2 +1,4 @@
|
|||||||
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
|
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
|
||||||
|
|
||||||
|
add_executable(main1 main1.cpp)
|
||||||
|
|
||||||
|
161
src/main1.cpp
161
src/main1.cpp
@ -1,5 +1,166 @@
|
|||||||
|
// 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 <string>
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
#include <functional>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
// context aka, kv-dict
|
||||||
|
|
||||||
|
// criterion, predicate that returns true or false based on state and context(query)
|
||||||
|
// equal: value == min == max
|
||||||
|
// smaller: value == max -e; min == -inf
|
||||||
|
// greater: value == min +e; max == +inf
|
||||||
|
struct Criterion {
|
||||||
|
std::string key;
|
||||||
|
float min, max;
|
||||||
|
|
||||||
|
bool compare(const float x) const {
|
||||||
|
return x >= min && x <= max;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator<(const Criterion& other) const {
|
||||||
|
return key < other.key && min < other.min && max < other.max;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// rule, list of criterions (obv &&)
|
||||||
|
struct Rules {
|
||||||
|
std::set<Criterion> crits;
|
||||||
|
};
|
||||||
|
|
||||||
|
// query, ...?
|
||||||
|
struct Query {
|
||||||
|
// sorted?
|
||||||
|
std::map<std::string, float> dict;
|
||||||
|
|
||||||
|
Query& add(const std::string& key, float value) {
|
||||||
|
dict[key] = value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Query& add(const std::string& key, const std::string& value) {
|
||||||
|
// lol
|
||||||
|
dict[key] = std::hash<std::string>{}(value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool match_criterion(const Criterion& crit) const {
|
||||||
|
return dict.count(crit.key) && crit.compare(dict.at(crit.key));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool match_rules(const Rules& rules) const {
|
||||||
|
for (const auto& crit : rules.crits) {
|
||||||
|
if (!match_criterion(crit)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// response -> action (list?)
|
||||||
|
struct Response {
|
||||||
|
Rules rules;
|
||||||
|
|
||||||
|
std::function<void(void)> f;
|
||||||
|
};
|
||||||
|
|
||||||
|
// special keys (usually bucketalbe):
|
||||||
|
// - concept: onHit, onIdle, onResponse, onObject?
|
||||||
|
// - "who": which char talked. gonna name this differently
|
||||||
|
|
||||||
|
struct ResponseDB {
|
||||||
|
};
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
|
std::map<float, std::string> reverse_string_map;
|
||||||
|
reverse_string_map[std::hash<std::string>{}("who")] = "who";
|
||||||
|
|
||||||
|
// crit test
|
||||||
|
|
||||||
|
Criterion hp_not_critical {
|
||||||
|
"hp",
|
||||||
|
// have at least 15% of max hp
|
||||||
|
0.15f,
|
||||||
|
std::numeric_limits<float>::infinity()
|
||||||
|
};
|
||||||
|
|
||||||
|
assert(hp_not_critical.compare(0.0f) == false);
|
||||||
|
assert(hp_not_critical.compare(0.15f) == true);
|
||||||
|
assert(hp_not_critical.compare(0.15f - std::numeric_limits<float>::epsilon()) == false);
|
||||||
|
assert(hp_not_critical.compare(1.0f) == true);
|
||||||
|
|
||||||
|
Criterion is_hero {
|
||||||
|
"who",
|
||||||
|
// tmp
|
||||||
|
0.f, 0.f
|
||||||
|
};
|
||||||
|
// key "who" is value "hero"
|
||||||
|
is_hero.min = std::hash<std::string>{}("hero");
|
||||||
|
is_hero.max = std::hash<std::string>{}("hero");
|
||||||
|
|
||||||
|
assert(is_hero.compare(std::hash<std::string>{}("hero")) == true);
|
||||||
|
assert(is_hero.compare(std::hash<std::string>{}("enemy")) == false);
|
||||||
|
assert(is_hero.compare(std::hash<std::string>{}("ally")) == false);
|
||||||
|
|
||||||
|
Criterion on_idle {
|
||||||
|
"concept",
|
||||||
|
// tmp
|
||||||
|
0.f, 0.f
|
||||||
|
};
|
||||||
|
// key "concept" is value "idle"
|
||||||
|
on_idle.min = std::hash<std::string>{}("idle");
|
||||||
|
on_idle.max = std::hash<std::string>{}("idle");
|
||||||
|
|
||||||
|
assert(on_idle.compare(std::hash<std::string>{}("idle")) == true);
|
||||||
|
assert(on_idle.compare(std::hash<std::string>{}("hero")) == false);
|
||||||
|
assert(on_idle.compare(std::hash<std::string>{}("hit")) == false);
|
||||||
|
|
||||||
|
Rules rules_hero_idle_chatter {{
|
||||||
|
on_idle, is_hero, hp_not_critical
|
||||||
|
}};
|
||||||
|
|
||||||
|
// query test
|
||||||
|
|
||||||
|
Query q1{};
|
||||||
|
q1
|
||||||
|
.add("concept", "idle")
|
||||||
|
.add("who", "hero")
|
||||||
|
.add("hp", 0.843122f)
|
||||||
|
.add("ally_near", 1.f)
|
||||||
|
.add("enemy_near", 0.f)
|
||||||
|
.add("in_danger", 0.f)
|
||||||
|
;
|
||||||
|
|
||||||
|
Query q2{};
|
||||||
|
q2
|
||||||
|
.add("concept", "hit")
|
||||||
|
.add("who", "enemy")
|
||||||
|
.add("hp", 0.12333f)
|
||||||
|
.add("ally_near", 0.f)
|
||||||
|
.add("enemy_near", 1.f)
|
||||||
|
.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(q1.match_criterion(hp_not_critical) == true);
|
||||||
|
assert(q1.match_criterion(is_hero) == true);
|
||||||
|
|
||||||
|
assert(q2.match_criterion(hp_not_critical) == false);
|
||||||
|
assert(q2.match_criterion(is_hero) == false);
|
||||||
|
|
||||||
|
assert(q1.match_rules(rules_hero_idle_chatter) == true);
|
||||||
|
assert(q2.match_rules(rules_hero_idle_chatter) == false);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user