diff --git a/examples/main.cpp b/examples/main.cpp index a3b78d8..3ba9dd0 100644 --- a/examples/main.cpp +++ b/examples/main.cpp @@ -34,32 +34,30 @@ class VacuumCleaner : public Problem { } return !vacuum_state->dirty0 && !vacuum_state->dirty1; } - std::vector actions(std::shared_ptr state) override { - auto *vacuum_state = dynamic_cast(state.get()); - std::vector actions; + std::vector> actions(std::shared_ptr state) override { + auto vacuum_state = std::dynamic_pointer_cast(state); + std::vector> actions; - // Define lambda to create a new VacuumState safely auto create_state = [&](int x, bool dirty0, bool dirty1) { return std::make_shared(x, dirty0, dirty1); }; - // Check possible moves and construct actions + // Add possible actions with smart pointers if (vacuum_state->x == 0) { if (vacuum_state->dirty0) { - actions.emplace_back("Suck", 1, std::make_shared(*vacuum_state), create_state(0, false, vacuum_state->dirty1)); + actions.push_back(std::make_shared("Suck", 1, state, create_state(0, false, vacuum_state->dirty1))); } else { - actions.emplace_back("Right", 1, std::make_shared(*vacuum_state), create_state(1, vacuum_state->dirty0, vacuum_state->dirty1)); + actions.push_back(std::make_shared("Right", 1, state, create_state(1, vacuum_state->dirty0, vacuum_state->dirty1))); } } else { if (vacuum_state->dirty1) { - actions.emplace_back("Suck", 1, std::make_shared(*vacuum_state), create_state(1, vacuum_state->dirty0, false)); + actions.push_back(std::make_shared("Suck", 1, state, create_state(1, vacuum_state->dirty0, false))); } else { - actions.emplace_back("Left", 1, std::make_shared(*vacuum_state), create_state(0, vacuum_state->dirty0, vacuum_state->dirty1)); + actions.push_back(std::make_shared("Left", 1, state, create_state(0, vacuum_state->dirty0, vacuum_state->dirty1))); } } - return actions; - + return actions; } double heuristic(State *state) override { @@ -125,32 +123,34 @@ class MazeProblem : public Problem { auto *maze_state = dynamic_cast(state); return maze_state->maze[maze_state->x][maze_state->y] == -1; } - std::vector actions(std::shared_ptr state) override { - auto *maze_state = dynamic_cast(state.get()); - std::vector actions; - // Define lambda to create a new MazeState safely + std::vector> actions(std::shared_ptr state) override { + auto maze_state = std::dynamic_pointer_cast(state); + std::vector> actions; + auto create_state = [&](int x, int y) { return std::make_shared(maze_state->maze, x, y); }; - // Check possible moves and construct actions + // Add possible actions with smart pointers if (maze_state->x > 0 && maze_state->maze[maze_state->x - 1][maze_state->y] != 1) { - actions.emplace_back("Up", 1, std::make_shared(*maze_state), create_state(maze_state->x - 1, maze_state->y)); + actions.push_back(std::make_shared("Up", 1, state, create_state(maze_state->x - 1, maze_state->y))); } if (maze_state->x < maze_state->maze.size() - 1 && maze_state->maze[maze_state->x + 1][maze_state->y] != 1) { - actions.emplace_back("Down", 1, std::make_shared(*maze_state), create_state(maze_state->x + 1, maze_state->y)); + actions.push_back(std::make_shared("Down", 1, state, create_state(maze_state->x + 1, maze_state->y))); } if (maze_state->y > 0 && maze_state->maze[maze_state->x][maze_state->y - 1] != 1) { - actions.emplace_back("Left", 1, std::make_shared(*maze_state), create_state(maze_state->x, maze_state->y - 1)); + actions.push_back(std::make_shared("Left", 1, state, create_state(maze_state->x, maze_state->y - 1))); } if (maze_state->y < maze_state->maze[0].size() - 1 && maze_state->maze[maze_state->x][maze_state->y + 1] != 1) { - actions.emplace_back("Right", 1, std::make_shared(*maze_state), create_state(maze_state->x, maze_state->y + 1)); + actions.push_back(std::make_shared("Right", 1, state, create_state(maze_state->x, maze_state->y + 1))); } + return actions; } + double heuristic(State *state) override { auto *maze_state = dynamic_cast(state); return abs(maze_state->x - 3) + abs(maze_state->y - 3); @@ -184,6 +184,8 @@ int main () { std::cout << "Solution found!" << std::endl; State *maze_state = node->state.get(); maze_state->print(); + Solution solution(node.get()); + solution.print(); } else { std::cout << "Solution not found!" << std::endl; } diff --git a/include/definitions.h b/include/definitions.h index f3dc710..614e3c4 100644 --- a/include/definitions.h +++ b/include/definitions.h @@ -97,7 +97,7 @@ class Problem { * @param state The current state. * @return A vector of actions applicable to the given state. */ - virtual std::vector actions(std::shared_ptr state) = 0; + virtual std::vector> actions(std::shared_ptr state) = 0; /** * @brief Computes a heuristic estimate for a given state. diff --git a/include/search.h b/include/search.h index 21ab5ad..0f26f03 100644 --- a/include/search.h +++ b/include/search.h @@ -12,9 +12,9 @@ class Node { public: - std::weak_ptr parent; // Weak pointer to prevent circular references + std::shared_ptr parent; // Weak pointer to prevent circular references std::shared_ptr state; // Smart pointer to manage state memory - const Action *action; // Pointer to an immutable Action object + const std::shared_ptr action; // Pointer to an immutable Action object double path_cost; // Cost to reach this node double heuristic; // Heuristic value (if applicable) @@ -22,7 +22,7 @@ class Node { Node() : action(nullptr), path_cost(0), heuristic(0) {} // Parameterized constructor - Node(std::shared_ptr parent, std::shared_ptr state, const Action *action, double path_cost, double heuristic) + Node(std::shared_ptr parent, std::shared_ptr state, const std::shared_ptr action, double path_cost, double heuristic) : parent(parent), state(state), action(action), path_cost(path_cost), heuristic(heuristic) {} }; diff --git a/src/search.cpp b/src/search.cpp index f15eab8..5f3fb9a 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -19,14 +19,15 @@ Search *create_search(SearchAlgorithmIndex search_algorithm_index, Problem *prob BreadthFirstSearch::~BreadthFirstSearch() { } - void Solution::print() { - std::weak_ptr current = node->parent; + Node * current = this->node; std::vector actions; - while (current.lock()) { - auto parent = current.lock(); - actions.push_back(*parent->action); - current = parent->parent; + auto parent = current->parent; + // Traverse the solution path by following the parent pointers + while (parent != nullptr) { + actions.push_back(*current->action); + current = parent.get(); + parent = current->parent; } for (auto it = actions.rbegin(); it != actions.rend(); ++it) { @@ -62,11 +63,11 @@ std::shared_ptr BreadthFirstSearch::search() { // Expand the node by generating its child nodes for (const auto &action : problem->actions(node->state)) { auto child = std::make_shared( - node, // Parent node - action.effect, // Resulting state (shared_ptr) - &action, // Pointer to the action - node->path_cost + action.cost, // Cumulative path cost - problem->heuristic(action.effect.get()) // Heuristic value + std::shared_ptr(node), // Parent node + action->effect, + action, // Pointer to the action + node->path_cost + action->cost, // Path cost + problem->heuristic(action->effect.get()) // Heuristic value ); frontier.push(child); }