Skip to content

Commit 0d8ad19

Browse files
committed
refactor: update AStarSearchNode structure and cost calculations
1 parent f61dd38 commit 0d8ad19

File tree

2 files changed

+55
-67
lines changed

2 files changed

+55
-67
lines changed

src/search/astar/astar.cpp

Lines changed: 33 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -12,43 +12,30 @@ vector<AStarSearchNode> astar::generate_successors_astar(const AStarSearchNode&
1212
for (int direction = -1; direction <= 1; direction += 2) {
1313
for (int steps = 1; ; ++steps) {
1414
vector<Piece> next_pieces_state = current_pieces;
15-
Piece& piece_moved_in_state = next_pieces_state[piece_idx]; // ambil referensi ke piece yang akan digerakkan di state baru
15+
Piece& piece_moved_in_state = next_pieces_state[piece_idx];
1616
bool move_possible = true;
17-
18-
Coordinates original_coords_of_moving_piece = piece_to_move.coordinates; // simpan koordinat asli sebelum modifikasi
17+
Coordinates original_coords_of_moving_piece = piece_to_move.coordinates;
1918

2019
if (piece_to_move.is_vertical) {
2120
for (int s = 1; s <= steps; ++s) {
2221
int y_check;
23-
if (direction > 0) {
24-
y_check = piece_to_move.coordinates.y + piece_to_move.size - 1 + s;
25-
} else {
26-
y_check = piece_to_move.coordinates.y - s;
27-
}
22+
if (direction > 0) { y_check = piece_to_move.coordinates.y + piece_to_move.size - 1 + s;}
23+
else { y_check = piece_to_move.coordinates.y - s; }
2824
if (!Utils::is_cell_clear(board_node, y_check, piece_to_move.coordinates.x, current_pieces, piece_to_move.id)) {
29-
move_possible = false;
30-
break;
25+
move_possible = false; break;
3126
}
3227
}
33-
if (move_possible) {
34-
piece_moved_in_state.coordinates.y += (direction * steps);
35-
}
28+
if (move_possible) { piece_moved_in_state.coordinates.y += (direction * steps); }
3629
} else {
3730
for (int s = 1; s <= steps; ++s) {
3831
int x_check;
39-
if (direction > 0) {
40-
x_check = piece_to_move.coordinates.x + piece_to_move.size - 1 + s;
41-
} else {
42-
x_check = piece_to_move.coordinates.x - s;
43-
}
32+
if (direction > 0) { x_check = piece_to_move.coordinates.x + piece_to_move.size - 1 + s; }
33+
else { x_check = piece_to_move.coordinates.x - s; }
4434
if (!Utils::is_cell_clear(board_node, piece_to_move.coordinates.y, x_check, current_pieces, piece_to_move.id)) {
45-
move_possible = false;
46-
break;
35+
move_possible = false; break;
4736
}
4837
}
49-
if (move_possible) {
50-
piece_moved_in_state.coordinates.x += (direction * steps);
51-
}
38+
if (move_possible) { piece_moved_in_state.coordinates.x += (direction * steps); }
5239
}
5340

5441
if (!move_possible) {
@@ -57,11 +44,11 @@ vector<AStarSearchNode> astar::generate_successors_astar(const AStarSearchNode&
5744

5845
vector<PieceMove> next_path = current_astar_node.path;
5946
PieceMove current_pm;
60-
current_pm.old_coordinates = original_coords_of_moving_piece; // gunakan koordinat asli
61-
current_pm.new_coordinates = piece_moved_in_state.coordinates; // koordinat baru setelah bergerak
47+
current_pm.old_coordinates = original_coords_of_moving_piece;
48+
current_pm.new_coordinates = piece_moved_in_state.coordinates;
6249
next_path.push_back(current_pm);
6350

64-
int g_cost_successor = current_astar_node.g_cost + COST_PER_MOVE; // biaya pergerakan umumnya 1
51+
int g_cost_successor = current_astar_node.actual_g_cost + COST_PER_MOVE;
6552
int h_cost_successor = Utils::calculate(board_node, next_pieces_state);
6653

6754
successors.emplace_back(next_pieces_state, board_node, next_path, g_cost_successor, h_cost_successor, piece_to_move.id, original_coords_of_moving_piece);
@@ -71,25 +58,25 @@ vector<AStarSearchNode> astar::generate_successors_astar(const AStarSearchNode&
7158
return successors;
7259
}
7360

74-
7561
Solution astar::search_astar(const Board& initial_board, const vector<Piece>& initial_pieces) {
7662
auto time_start = chrono::high_resolution_clock::now();
7763
Solution result;
7864
result.is_solved = false;
7965
result.node = 0;
8066

81-
const int COST_PER_MOVE = 1; // biaya setiap gerakan adalah 1
67+
const int COST_PER_MOVE = 1;
8268

8369
priority_queue<AStarSearchNode, vector<AStarSearchNode>, greater<AStarSearchNode>> pq;
8470
set<string> visited_states;
8571

86-
// node awal
8772
int initial_g_cost = 0;
8873
int initial_h_cost = Utils::calculate(initial_board, initial_pieces);
8974
AStarSearchNode initial_astar_node(initial_pieces, initial_board, {}, initial_g_cost, initial_h_cost);
9075
pq.push(initial_astar_node);
9176

92-
UtilityFunctions::print("ASTAR: Initial g_cost: 0, h_cost: " + godot::String::num_int64(initial_h_cost) + ", f_cost: " + godot::String::num_int64(initial_astar_node.f_cost));
77+
godot::UtilityFunctions::print("ASTAR: Initial g_cost: " + godot::String::num_int64(initial_astar_node.actual_g_cost) +
78+
", h_cost: " + godot::String::num_int64(initial_astar_node.h_cost) +
79+
", f_cost: " + godot::String::num_int64(initial_astar_node.val)); // val dari base class adalah f_cost
9380

9481
while (!pq.empty()) {
9582
AStarSearchNode current_node = pq.top();
@@ -102,29 +89,32 @@ Solution astar::search_astar(const Board& initial_board, const vector<Piece>& in
10289
}
10390
visited_states.insert(current_state_str);
10491

105-
UtilityFunctions::print("ASTAR: Exploring node. " +
106-
godot::String("f(n):") + godot::String::num_int64(current_node.f_cost) +
107-
godot::String(", g(n):") + godot::String::num_int64(current_node.g_cost) +
92+
godot::UtilityFunctions::print("ASTAR: Exploring node. " +
93+
godot::String("f(n):") + godot::String::num_int64(current_node.val) + // f_cost dari base.val
94+
godot::String(", g(n):") + godot::String::num_int64(current_node.actual_g_cost) +
10895
godot::String(", h(n):") + godot::String::num_int64(current_node.h_cost) +
109-
". Path length: " + godot::String::num_int64(static_cast<int64_t>(current_node.path.size())));
96+
". Path length: " + godot::String::num_int64(static_cast<int64_t>(current_node.path.size()))); // path dari base
11097

111-
if (current_node.piece_moved != ' ') {
98+
if (current_node.piece_moved != ' ') { // piece_moved dari base
11299
Coordinates new_pos_for_log = {-1, -1};
113-
// cari piece yang digerakkan di state saat ini untuk mendapatkan posisi barunya
114-
for(const auto& p_state : current_node.pieces) {
100+
for(const auto& p_state : current_node.pieces) { // pieces dari base
115101
if (p_state.id == current_node.piece_moved) {
116102
new_pos_for_log = p_state.coordinates;
117103
break;
118104
}
119105
}
120-
UtilityFunctions::print("Moved piece: ", godot::String::utf8(&current_node.piece_moved, 1), " from (", current_node.original_position.x, ",", current_node.original_position.y, ") to (", new_pos_for_log.x, ",", new_pos_for_log.y, ")");
106+
godot::UtilityFunctions::print("Moved piece: ", godot::String::utf8(&current_node.piece_moved, 1),
107+
" from (", current_node.original_position.x, ",", current_node.original_position.y,
108+
") to (", new_pos_for_log.x, ",", new_pos_for_log.y, ")"); // original_position dari base
121109
}
122110

123-
124-
if (Utils::is_exit(current_node.board, current_node.pieces)) {
111+
if (Utils::is_exit(current_node.board, current_node.pieces)) { // board dan pieces dari base
125112
result.is_solved = true;
126-
result.moves = current_node.path;
127-
UtilityFunctions::print("ASTAR: Solution Found! Optimal steps (g_cost): " + godot::String::num_int64(current_node.g_cost) + ". Total moves: " + godot::String::num_int64(result.moves.size()) + ". Nodes visited: " + godot::String::num_int64(static_cast<int64_t>(result.node)));
113+
result.moves = current_node.path; // path dari base
114+
godot::UtilityFunctions::print("ASTAR: Solution Found! Optimal steps (g_cost): " +
115+
godot::String::num_int64(current_node.actual_g_cost) + ". Total moves: " +
116+
godot::String::num_int64(result.moves.size()) + ". Nodes visited: " +
117+
godot::String::num_int64(static_cast<int64_t>(result.node)));
128118
break;
129119
}
130120

@@ -142,7 +132,7 @@ Solution astar::search_astar(const Board& initial_board, const vector<Piece>& in
142132
result.duration = chrono::duration<double, milli>(time_end - time_start);
143133

144134
if (!result.is_solved) {
145-
UtilityFunctions::print("ASTAR: No solution found. Nodes visited: " + godot::String::num_int64(static_cast<int64_t>(result.node)));
135+
godot::UtilityFunctions::print("ASTAR: No solution found. Nodes visited: " + godot::String::num_int64(static_cast<int64_t>(result.node)));
146136
}
147137
return result;
148138
}

src/search/astar/astar.hpp

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,45 +9,43 @@
99

1010
#include "../../utils/utils.hpp"
1111

12-
struct AStarSearchNode {
13-
vector<Piece> pieces;
14-
Board board;
15-
vector<PieceMove> path;
16-
int g_cost;
12+
struct AStarSearchNode : public SearchNode {
1713
int h_cost;
18-
int f_cost;
14+
int actual_g_cost;
15+
16+
AStarSearchNode(const std::vector<Piece>& p,
17+
const Board& b,
18+
const std::vector<PieceMove>& path_taken,
19+
int g,
20+
int h,
21+
char pid_moved = ' ',
22+
Coordinates opos_moved = {-1,-1})
23+
: SearchNode(p, b, path_taken, g + h, pid_moved, opos_moved),
24+
h_cost(h),
25+
actual_g_cost(g) {}
1926

20-
char piece_moved;
21-
Coordinates original_position;
22-
23-
AStarSearchNode(const vector<Piece>& p, const Board& b, const vector<PieceMove>& path, int g, int h, char pid = ' ', Coordinates opos = {-1,-1})
24-
: pieces(p), board(b), path(path), g_cost(g), h_cost(h), f_cost(g + h), piece_moved(pid), original_position(opos) {}
25-
26-
// operator untuk priority queue
2727
bool operator>(const AStarSearchNode& other) const {
28-
if (f_cost != other.f_cost) {
29-
return f_cost > other.f_cost;
28+
if (this->val != other.val) {
29+
return this->val > other.val;
3030
}
31-
// jika f_cost sama, bisa menggunakan h_cost sebagai tie-breaker
32-
return h_cost > other.h_cost;
31+
return this->h_cost > other.h_cost;
3332
}
3433

35-
// fungsi untuk mendapatkan representasi string dari state untuk set 'visited'
36-
string get_state_string() const {
37-
string s = "";
38-
vector<Piece> sorted_pieces = pieces;
34+
std::string get_state_string() const {
35+
std::string s = "";
36+
std::vector<Piece> sorted_pieces = this->pieces;
3937

40-
sort(sorted_pieces.begin(), sorted_pieces.end(), [](const Piece& a, const Piece& b) {
38+
std::sort(sorted_pieces.begin(), sorted_pieces.end(), [](const Piece& a, const Piece& b) {
4139
return a.id < b.id;
4240
});
4341

4442
for (const auto& piece : sorted_pieces) {
4543
if (piece.id == 'K') continue;
4644
s += piece.id;
4745
s += ':';
48-
s += to_string(piece.coordinates.x);
46+
s += std::to_string(piece.coordinates.x);
4947
s += ',';
50-
s += to_string(piece.coordinates.y);
48+
s += std::to_string(piece.coordinates.y);
5149
s += (piece.is_vertical ? "V" : "H");
5250
s += ";";
5351
}

0 commit comments

Comments
 (0)