Mostly fixed up but I have to figure out why cost on actions isn't changing the priority.
This commit is contained in:
parent
862d8b4d81
commit
52f45e1d45
5 changed files with 17 additions and 29 deletions
4
Makefile
4
Makefile
|
@ -22,7 +22,7 @@ tracy_build:
|
||||||
meson compile -j 10 -C builddir
|
meson compile -j 10 -C builddir
|
||||||
|
|
||||||
test: build
|
test: build
|
||||||
./builddir/runtests "[rituals]"
|
./builddir/runtests "[combat]"
|
||||||
|
|
||||||
run: build test
|
run: build test
|
||||||
powershell "cp ./builddir/zedcaster.exe ."
|
powershell "cp ./builddir/zedcaster.exe ."
|
||||||
|
@ -41,7 +41,7 @@ clean:
|
||||||
meson compile --clean -C builddir
|
meson compile --clean -C builddir
|
||||||
|
|
||||||
debug_test: build
|
debug_test: build
|
||||||
gdb --nx -x .gdbinit --ex run --args builddir/runtests.exe -e "[rituals]"
|
gdb --nx -x .gdbinit --ex run --args builddir/runtests.exe -e "[combat]"
|
||||||
|
|
||||||
win_installer:
|
win_installer:
|
||||||
powershell 'start "C:\Program Files (x86)\solicus\InstallForge\bin\ifbuilderenvx86.exe" win_installer.ifp'
|
powershell 'start "C:\Program Files (x86)\solicus\InstallForge\bin\ifbuilderenvx86.exe" win_installer.ifp'
|
||||||
|
|
|
@ -31,11 +31,8 @@
|
||||||
"needs": {
|
"needs": {
|
||||||
"tough_personality": false,
|
"tough_personality": false,
|
||||||
"in_combat": true,
|
"in_combat": true,
|
||||||
"no_more_enemies": false,
|
|
||||||
"have_healing": false,
|
"have_healing": false,
|
||||||
"health_good": false,
|
"health_good": false
|
||||||
"enemy_found": true,
|
|
||||||
"enemy_dead": false
|
|
||||||
},
|
},
|
||||||
"effects": {
|
"effects": {
|
||||||
"in_combat": false
|
"in_combat": false
|
||||||
|
|
31
goap.cpp
31
goap.cpp
|
@ -111,43 +111,34 @@ namespace ai {
|
||||||
return distance_to_goal(start, goal);
|
return distance_to_goal(start, goal);
|
||||||
}
|
}
|
||||||
|
|
||||||
using FScorePair = std::pair<int, ActionState>;
|
ActionState find_lowest(std::unordered_map<ActionState, int>& open_set) {
|
||||||
auto FScorePair_cmp = [](const FScorePair& l, const FScorePair& r) {
|
|
||||||
return l.first < r.first;
|
|
||||||
};
|
|
||||||
using FScoreQueue = std::vector<FScorePair>;
|
|
||||||
|
|
||||||
ActionState find_lowest(std::unordered_map<ActionState, int>& open_set,
|
|
||||||
FScoreQueue& f_scores)
|
|
||||||
{
|
|
||||||
check(!open_set.empty(), "open set can't be empty in find_lowest");
|
check(!open_set.empty(), "open set can't be empty in find_lowest");
|
||||||
|
int found_score = SCORE_MAX;
|
||||||
|
ActionState found_as;
|
||||||
|
|
||||||
for(auto& [score, astate] : f_scores) {
|
for(auto& kv : open_set) {
|
||||||
if(open_set.contains(astate)) {
|
if(kv.second < found_score) {
|
||||||
return astate;
|
found_score = kv.second;
|
||||||
|
found_as = kv.first;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dbc::sentinel("lowest not found!");
|
return found_as;
|
||||||
}
|
}
|
||||||
|
|
||||||
ActionPlan plan_actions(std::vector<Action>& actions, State start, State goal) {
|
ActionPlan plan_actions(std::vector<Action>& actions, State start, State goal) {
|
||||||
std::unordered_map<ActionState, int> open_set;
|
std::unordered_map<ActionState, int> open_set;
|
||||||
std::unordered_map<Action, Action> came_from;
|
std::unordered_map<Action, Action> came_from;
|
||||||
std::unordered_map<State, int> g_score;
|
std::unordered_map<State, int> g_score;
|
||||||
FScoreQueue f_score;
|
|
||||||
std::unordered_map<State, bool> closed_set;
|
std::unordered_map<State, bool> closed_set;
|
||||||
ActionState current{FINAL_ACTION, start};
|
ActionState current{FINAL_ACTION, start};
|
||||||
|
|
||||||
g_score.insert_or_assign(start, 0);
|
g_score.insert_or_assign(start, 0);
|
||||||
f_score.emplace_back(h(start, goal), current);
|
|
||||||
std::push_heap(f_score.begin(), f_score.end(), FScorePair_cmp);
|
|
||||||
|
|
||||||
open_set.insert_or_assign(current, h(start, goal));
|
open_set.insert_or_assign(current, h(start, goal));
|
||||||
|
|
||||||
while(!open_set.empty()) {
|
while(!open_set.empty()) {
|
||||||
// current := the node in openSet having the lowest fScore[] value
|
// current := the node in openSet having the lowest fScore[] value
|
||||||
current = find_lowest(open_set, f_score);
|
current = find_lowest(open_set);
|
||||||
|
|
||||||
if(is_subset(current.state, goal)) {
|
if(is_subset(current.state, goal)) {
|
||||||
return {true,
|
return {true,
|
||||||
|
@ -175,9 +166,7 @@ namespace ai {
|
||||||
g_score.insert_or_assign(neighbor, tentative_g_score);
|
g_score.insert_or_assign(neighbor, tentative_g_score);
|
||||||
ActionState neighbor_as{neighbor_action, neighbor};
|
ActionState neighbor_as{neighbor_action, neighbor};
|
||||||
|
|
||||||
int score = tentative_g_score + h(neighbor, goal);
|
int score = tentative_g_score + h(neighbor, goal) + neighbor_action.cost;
|
||||||
f_score.emplace_back(score, neighbor_as);
|
|
||||||
std::push_heap(f_score.begin(), f_score.end(), FScorePair_cmp);
|
|
||||||
|
|
||||||
// this maybe doesn't need score
|
// this maybe doesn't need score
|
||||||
open_set.insert_or_assign(neighbor_as, score);
|
open_set.insert_or_assign(neighbor_as, score);
|
||||||
|
|
2
goap.hpp
2
goap.hpp
|
@ -58,6 +58,8 @@ namespace ai {
|
||||||
ActionState(Action action, State state) :
|
ActionState(Action action, State state) :
|
||||||
action(action), state(state) {}
|
action(action), state(state) {}
|
||||||
|
|
||||||
|
ActionState() : action(FINAL_ACTION), state(0) {}
|
||||||
|
|
||||||
bool operator==(const ActionState& other) const {
|
bool operator==(const ActionState& other) const {
|
||||||
return other.action == action && other.state == state;
|
return other.action == action && other.state == state;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,10 +27,10 @@ TEST_CASE("RitualEngine basic tests", "[rituals]") {
|
||||||
|
|
||||||
fmt::println("\n\n------------ TEST WILL DO MAGICK TOO");
|
fmt::println("\n\n------------ TEST WILL DO MAGICK TOO");
|
||||||
ritual.dump();
|
ritual.dump();
|
||||||
REQUIRE(ritual.will_do("pierce_type"));
|
REQUIRE(ritual.will_do("magick_type"));
|
||||||
|
|
||||||
ritual.pop();
|
ritual.pop();
|
||||||
REQUIRE(ritual.will_do("magick_type"));
|
REQUIRE(ritual.will_do("pierce_type"));
|
||||||
|
|
||||||
re.reset(ritual);
|
re.reset(ritual);
|
||||||
re.set_state(ritual, "has_magick", true);
|
re.set_state(ritual, "has_magick", true);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue