Now have the ability to do partial solutions that will create potential paths to the goal, and a test that runs the scripts from plans in different scenarios. Also, this ai_debug thing needs some work.

This commit is contained in:
Zed A. Shaw 2025-03-11 15:33:14 -04:00
parent 3f83d3f0bb
commit fc66d221d4
11 changed files with 252 additions and 107 deletions

View file

@ -2,6 +2,7 @@
#include "dbc.hpp"
#include "ai.hpp"
#include <iostream>
#include "ai_debug.hpp"
using namespace dbc;
using namespace nlohmann;
@ -92,11 +93,11 @@ TEST_CASE("basic feature tests", "[ai]") {
actions.push_back(move_closer);
auto result = ai::plan_actions(actions, start, goal);
REQUIRE(result != std::nullopt);
REQUIRE(result.complete);
auto state = start;
for(auto& action : *result) {
for(auto& action : result.script) {
state = action.apply_effect(state);
}
@ -105,19 +106,61 @@ TEST_CASE("basic feature tests", "[ai]") {
TEST_CASE("ai as a module like sound/sprites", "[ai]") {
ai::reset();
ai::init("tests/ai_fixture.json");
auto start = ai::load_state("test_start");
auto goal = ai::load_state("test_goal");
auto script = ai::plan("test1", start, goal);
REQUIRE(script != std::nullopt);
auto a_plan = ai::plan("test1", start, goal);
REQUIRE(a_plan.complete);
auto state = start;
for(auto& action : *script) {
for(auto& action : a_plan.script) {
fmt::println("ACTION: {}", action.$name);
state = action.apply_effect(state);
}
REQUIRE(state[ai::state_id("target_dead")]);
REQUIRE(ai::test(state, "target_dead"));
}
TEST_CASE("ai autowalker ai test", "[ai]") {
ai::reset();
ai::init("assets/ai.json");
ai::AIProfile* profile = ai::profile();
auto start = ai::load_state("Walker::initial_state");
auto goal = ai::load_state("Walker::final_state");
int enemy_count = 5;
ai::set(start, "no_more_enemies", enemy_count == 0);
// find an enemy and kill them
auto a_plan = ai::plan("Walker::actions", start, goal);
REQUIRE(!a_plan.complete);
auto result = ai::dump_script(*profile, "\n\nWALKER KILL STUFF", start, a_plan.script);
REQUIRE(ai::test(result, "enemy_found"));
REQUIRE(ai::test(result, "enemy_dead"));
REQUIRE(!ai::test(result, "no_more_enemies"));
// health is low, go heal
ai::set(result, "health_good", false);
REQUIRE(!ai::test(result, "health_good"));
auto health_plan = ai::plan("Walker::actions", result, goal);
result = ai::dump_script(*profile, "\n\nWALKER NEED HEALTH", result, health_plan.script);
REQUIRE(!health_plan.complete);
REQUIRE(ai::test(result, "health_good"));
// health is good, enemies dead, go get stuff
ai::set(result, "no_more_enemies", true);
REQUIRE(ai::test(result, "no_more_enemies"));
auto new_plan = ai::plan("Walker::actions", result, goal);
result = ai::dump_script(*profile, "\n\nWALKER COMPLETE", result, new_plan.script);
REQUIRE(new_plan.complete);
REQUIRE(ai::test(result, "enemy_found"));
REQUIRE(ai::test(result, "enemy_dead"));
REQUIRE(ai::test(result, "no_more_enemies"));
}