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:
Zed A. Shaw 2025-04-03 10:14:50 -04:00
parent c014e65c13
commit c1aba2d5c8
5 changed files with 30 additions and 27 deletions

31
ai.cpp
View file

@ -155,6 +155,7 @@ namespace ai {
}
void set(State& state, std::string name, bool value) {
// resort by best fit
state.set(state_id(name), value);
}
@ -162,39 +163,32 @@ namespace ai {
return state.test(state_id(name));
}
ai::Action& EntityAI::best_fit() {
dbc::check(plan.script.size() > 0, "empty action plan script");
int lowest_cost = plan.script[0].cost;
size_t best_action = 0;
for(size_t i = 0; i < plan.script.size(); i++) {
auto& action = plan.script[i];
if(!action.can_effect(start)) continue;
if(action.cost < lowest_cost) {
lowest_cost = action.cost;
best_action = i;
}
void EntityAI::fit_sort() {
if(active()) {
std::sort(plan.script.begin(), plan.script.end(),
[&](auto& l, auto& r) {
int l_cost = l.cost + (!l.can_effect(start) * ai::SCORE_MAX);
int r_cost = r.cost + (!r.can_effect(start) * ai::SCORE_MAX);
return l_cost < r_cost;
});
}
return plan.script[best_action];
}
bool EntityAI::wants_to(std::string name) {
ai::check_valid_action(name, "EntityAI::wants_to");
dbc::check(plan.script.size() > 0, "empty action plan script");
return best_fit().name == name;
return plan.script.size() > 0 && plan.script[0].name == name;
}
bool EntityAI::active() {
if(plan.script.size() == 1) {
return plan.script[0] != FINAL_ACTION;
} else {
return plan.script.size() == 0;
return plan.script.size() != 0;
}
}
void EntityAI::set_state(std::string name, bool setting) {
fit_sort();
ai::set(start, name, setting);
}
@ -204,6 +198,7 @@ namespace ai {
void EntityAI::update() {
plan = ai::plan(script, start, goal);
fit_sort();
}
AIProfile* profile() {