This does a 'fit_sort' whenever the state is changed. fit_sort effectively sorts the actions by distance+cost so that the cost is actually present unlike the original algorithm.
This commit is contained in:
parent
c014e65c13
commit
c1aba2d5c8
5 changed files with 30 additions and 27 deletions
20
goap.cpp
20
goap.cpp
|
@ -4,6 +4,8 @@
|
|||
#include "stats.hpp"
|
||||
#include <queue>
|
||||
|
||||
// #define DEBUG_CYCLES 1
|
||||
|
||||
namespace ai {
|
||||
|
||||
using namespace nlohmann;
|
||||
|
@ -63,11 +65,8 @@ namespace ai {
|
|||
}
|
||||
}
|
||||
|
||||
inline void path_invariant(std::unordered_map<Action, Action>& came_from, Action& current) {
|
||||
#if defined(NDEBUG)
|
||||
(void)came_from; // disable errors about unused
|
||||
(void)current;
|
||||
#else
|
||||
inline void path_invariant(std::unordered_map<Action, Action>& came_from, Action current) {
|
||||
#if defined(DEBUG_CYCLES)
|
||||
bool final_found = current == FINAL_ACTION;
|
||||
|
||||
for(size_t i = 0; i <= came_from.size() && came_from.contains(current); i++) {
|
||||
|
@ -79,6 +78,9 @@ namespace ai {
|
|||
dump_came_from("CYCLE DETECTED!", came_from, current);
|
||||
dbc::sentinel("AI CYCLE FOUND!");
|
||||
}
|
||||
#else
|
||||
(void)came_from; // disable errors about unused
|
||||
(void)current;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -156,15 +158,21 @@ namespace ai {
|
|||
auto neighbor = neighbor_action.apply_effect(current.state);
|
||||
if(closed_set.contains(neighbor)) continue;
|
||||
|
||||
// BUG: no matter what I do cost really doesn't impact the graph
|
||||
// Additionally, every other GOAP implementation has the same problem, and
|
||||
// it's probably because the selection of actions is based more on sets matching
|
||||
// than actual weights of paths. This reduces the probability that an action will
|
||||
// be chosen over another due to only cost.
|
||||
int d_score = d(current.state, neighbor) + neighbor_action.cost;
|
||||
|
||||
int tentative_g_score = g_score[current.state] + d_score;
|
||||
int neighbor_g_score = g_score.contains(neighbor) ? g_score[neighbor] : SCORE_MAX;
|
||||
|
||||
if(tentative_g_score < neighbor_g_score) {
|
||||
if(tentative_g_score + neighbor_action.cost < neighbor_g_score) {
|
||||
came_from.insert_or_assign(neighbor_action, current.action);
|
||||
|
||||
g_score.insert_or_assign(neighbor, tentative_g_score);
|
||||
|
||||
ActionState neighbor_as{neighbor_action, neighbor};
|
||||
|
||||
int score = tentative_g_score + h(neighbor, goal);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue