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)
|
||||
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user