1+ #include < iostream>
2+ #include < vector>
3+ #include < set>
4+ #include < cmath>
5+ #include < algorithm>
6+
7+ using namespace std ;
8+
9+ const int N = 3 ;
10+
11+ // Goal state
12+ vector<vector<int >> goal = {
13+ {1 , 2 , 3 },
14+ {4 , 5 , 6 },
15+ {7 , 8 , 0 }
16+ };
17+
18+ int dx[] = {-1 , 1 , 0 , 0 };
19+ int dy[] = {0 , 0 , -1 , 1 };
20+ string dir[] = {" Up" , " Down" , " Left" , " Right" };
21+
22+ struct Puzzle {
23+ vector<vector<int >> board;
24+ int x, y;
25+ string path;
26+
27+ Puzzle (vector<vector<int >> b, int x_, int y_, string p = " " ) : board(b), x(x_), y(y_), path(p) {}
28+
29+ bool isGoal () const {
30+ return board == goal;
31+ }
32+
33+ int heuristic () const {
34+ int dist = 0 ;
35+ for (int i = 0 ; i < N; i++)
36+ for (int j = 0 ; j < N; j++)
37+ if (board[i][j] != 0 ) {
38+ int val = board[i][j] - 1 ;
39+ int targetX = val / N;
40+ int targetY = val % N;
41+ dist += abs (i - targetX) + abs (j - targetY);
42+ }
43+ return dist;
44+ }
45+ };
46+
47+ // Global variables to track best solution
48+ int bestCost = 501 ;
49+ string bestPath = " " ;
50+
51+ set<vector<vector<int >>> visited;
52+
53+ void BestFirstSearch (Puzzle current, int depth = 0 , int maxDepth = 500 ) {
54+ int estimate = depth + current.heuristic ();
55+
56+ // Prune if worse than best
57+ if (estimate >= bestCost || depth > maxDepth)
58+ return ;
59+
60+ // Goal check
61+ if (current.isGoal ()) {
62+ if (depth < bestCost) {
63+ bestCost = depth;
64+ bestPath = current.path ;
65+ }
66+ return ;
67+ }
68+
69+ visited.insert (current.board );
70+
71+ vector<Puzzle> nextStates;
72+
73+ // Generate next states
74+ for (int i = 0 ; i < 4 ; i++) {
75+ int newX = current.x + dx[i];
76+ int newY = current.y + dy[i];
77+ if (newX >= 0 && newX < N && newY >= 0 && newY < N) {
78+ vector<vector<int >> newBoard = current.board ;
79+ swap (newBoard[current.x ][current.y ], newBoard[newX][newY]);
80+
81+ if (visited.count (newBoard)) continue ;
82+
83+ nextStates.emplace_back (newBoard, newX, newY, current.path + " " + dir[i]);
84+ }
85+ }
86+
87+ // Sort by heuristic (Greedy Best-First)
88+ sort (nextStates.begin (), nextStates.end (), [](const Puzzle& a, const Puzzle& b) {
89+ return a.heuristic () < b.heuristic ();
90+ });
91+
92+ // Recurse
93+ for (Puzzle& next : nextStates) {
94+ BestFirstSearch (next, depth + 1 , maxDepth);
95+ }
96+
97+ // Backtrack: remove from visited
98+ visited.erase (current.board );
99+ }
100+
101+ int main () {
102+ vector<vector<int >> start = {
103+ {1 , 2 , 3 },
104+ {4 , 0 , 5 },
105+ {6 , 7 , 8 }
106+ };
107+
108+ // Find the position of 0
109+ int x = 0 , y = 0 ;
110+ for (int i = 0 ; i < N; i++)
111+ for (int j = 0 ; j < N; j++)
112+ if (start[i][j] == 0 ) x = i, y = j;
113+
114+ Puzzle startPuzzle (start, x, y);
115+ BestFirstSearch (startPuzzle);
116+
117+ if (bestCost < 501 ) {
118+ cout << " Solved! Cost: " << bestCost << endl;
119+ cout << " Path: " << bestPath << endl;
120+ } else {
121+ cout << " No solution found within depth limit." << endl;
122+ }
123+
124+ return 0 ;
125+ }
0 commit comments