OneCompiler

Lp2

115

#include<iostream>
#include<cmath>
#include<limits.h>

using namespace std;

//A* alogrithm to solve 8 puzzle problem

//Global variable to keep track of number of moves taken
int g = 0;

void Print(int puzzle[]){
for(int i = 0; i < 9; i++){
if(i % 3 == 0) cout << '\n';
if(puzzle[i] == -1) cout << "_ ";
else cout << puzzle[i] << " ";
}
cout << "\n\n";
}

void moveLeft(int start[], int position){
swap(start[position], start[position - 1]);
}

void moveRight(int start[], int position){
swap(start[position], start[position + 1]);
}

void moveUp(int start[], int position){
swap(start[position], start[position - 3]);
}

void moveDown(int start[], int position){
swap(start[position], start[position + 3]);
}

void Copy(int temp[], int real[]){
for(int i = 0; i < 9; i++) temp[i] = real[i];
}

/*
For every number find difference in position in goal state and inital state
Difference in vertical + difference in horizontal i.e Manhattan Distance
*/
int heuristic(int start[], int goal[]){
int h = 0;
for(int i = 0; i < 9; i++){
for(int j = 0; j < 9; j++){
if (start[i] == goal[j] && start[i] != -1){
h += abs((j - i) / 3) + abs((j - i) % 3);
}
}
}
return h + g;
}

void moveTile(int start[], int goal[]){
int emptyAt = 0;
for(int i = 0; i < 9; i++){
if(start[i] == -1){
emptyAt = i;
break;
}
}

int t1[9],t2[9],t3[9],t4[9],f1 = INT_MAX,f2 = INT_MAX,f3 = INT_MAX,f4 = INT_MAX;
Copy(t1, start);
Copy(t2, start);
Copy(t3, start);
Copy(t4, start);

int row = emptyAt / 3;
int col = emptyAt % 3;

if(col - 1 >= 0){
    moveLeft(t1, emptyAt);
    f1 = heuristic(t1, goal);
}

if(col + 1 < 3){
    moveRight(t2, emptyAt);
    f2 = heuristic(t2, goal);
}

if(row + 1 < 3){
    moveDown(t3, emptyAt);
    f3 = heuristic(t3, goal);
}

if(row - 1 >= 0){
    moveUp(t4, emptyAt);
    f4 = heuristic(t4, goal);
}


//Find Least Heuristic State and Make the Move
if(f1 <= f2 && f1 <= f3 && f1 <= f4 ){
    moveLeft(start, emptyAt);
}
else if(f2 <= f1 && f2 <= f3 && f2 <= f4 ){
    moveRight(start, emptyAt);
}
else if(f3 <= f1 && f3 <= f2 && f3 <= f4 ){
    moveDown(start, emptyAt);
}
else{
    moveUp(start, emptyAt);
}

}

void solveEight(int start[], int goal[]){
g++;
//Move Tile
moveTile(start, goal);
Print(start);
//Get Heuristic Value
int f = heuristic(start, goal);
if(f == g){
cout << "Solved in " << f << " moves\n";
return;
}
solveEight(start, goal);
}

/*
Count the number of inversion
If odd then unsolvable
else solvable
*/

bool solvable(int start[]){
int invrs = 0;
for(int i = 0; i < 9; i++){
//1 2 3 -1 4 6 7 5 8

    if(start[i] <= 1) continue;
    for(int j = i + 1; j < 9; j++){
        if(start[j] == -1) continue;
        if(start[i] > start[j]) invrs++;
    }
}
return invrs & 1 ? false : true;

}

// void printImpossible(){
// cout << R"(| ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄|
// ITS IMPOSSIBLE TO SOLVE
// |___________|
// (__/) ||
// (•ㅅ•) ||
// /   づ
// )" << '\n';
// }

int main(){
int start[9];
int goal[9];
cout << "Enter the start state:(Enter -1 for empty):";
for(int i = 0; i < 9; i++){
cin >> start[i];
}
cout << "Enter the goal state:(Enter -1 for empty):";
for(int i = 0; i < 9; i++){
cin >> goal[i];
}

// verify if possible to solve
Print(start);
if(solvable(start)) solveEight(start, goal);
else cout << "\nImpossible To Solve\n";

return 0;

}

/*
Test Cases
1 2 3 -1 4 6 7 5 8
1 2 3 4 5 6 7 8 -1

1 2 3 4 8 -1 7 6 5
1 2 3 4 5 6 7 8 -1

1 2 3 4 5 6 -1 8 7
1 2 3 4 5 6 7 8 -1

*/