You are on page 1of 6

#include <string>

#include <vector>
#include <stack>
#include <iostream>
#include <stdexcept>
#include "rectangularvectors.h"
using Random = util::Random;
using Stack = util::Stack;
//heuristic function f(h) is lowest possible f (n) from current state
class Eight_Puzzle
{

//solution state of the 8-puzzle game


public:
std::vector<std::vector<int>> goal_state =
{
{1, 2, 3},
{8, 0, 4},
{7, 6, 5}
};

//problem board of 8-puzzle game


std::vector<std::vector<int>> game_board =
{
{2, 6, 3},
{1, 0, 4},
{8, 7, 5}
};
/* one local maxima input example input
{2, 8, 3},
{1, 6, 4},
{7, 0, 5}
*/
/* one solved input example
{1, 3, 4},
{8, 2, 5},
{0, 7, 6}

{2, 0, 6},
{1, 4, 3},
{8, 7, 5}
//nice backtrack not solved in local maxima
{2, 6, 3},
{1, 0, 4},
{8, 7, 5}
*/
/* one no backtrack local maxima test input example
{1, 4, 0},
{8, 3, 2},
{7, 6, 5}
*/
/* one impossible local maxima test input example
{1, 2, 0},
{8, 3, 4},
{7, 6, 5}

using best solved


{8, 2, 3},
{0, 6, 4},
{7, 1, 5}

not using best


{1, 0, 2},
{8, 3, 6},
{7, 4, 5}
*/
//initial empty tile position
int emptyTile_row = 0;
int emptyTile_col = 0;
int stepCounter = 0;

int min_fn = 0;
Node *min_fn_node;

Random *random = new Random();


std::stack<Node*> stack_state; //for backtracking

//initializations
virtual ~Eight_Puzzle()
{
delete min_fn_node;
delete random;
}

virtual void initializations();

//start hill climbing search for 8-puzzle problem


virtual void hill_climbing_search();

private:
Node *getLowestPossible_fn_node();

//----------------------------
//return number of misplaced tiles for left state
Node *get_fn_left();

//return number of misplaced tiles for right state


Node *get_fn_right();

//return number of misplaced tiles for up state


Node *get_fn_up();

//return number of misplaced tiles for down state


Node *get_fn_down();

//takes a game state and returns number of misplaced tiles


int get_fn(std::vector<std::vector<int>> &game_state);

//takes parent removed, sorted node array and add states to stack in high to
low order
void addToStackState(std::vector<Node*> &nodeArray);

//find out the new empty tile position for current state
void locateEmptyTilePosition();

//print the current state of the game board


void printState(std::vector<std::vector<int>> &state, const std::wstring
&message);
};
#include <vector>
class RectangularVectors
{
public:
static std::vector<std::vector<int>> RectangularIntVector(int size1, int size2)
{
std::vector<std::vector<int>> newVector(size1);
for (int vector1 = 0; vector1 < size1; vector1++)
{
newVector[vector1] = std::vector<int>(size2);
}

return newVector;
}
};

#include "snippet.h"

using Random = util::Random;


using Stack = util::Stack;

void Eight_Puzzle::initializations()
{

locateEmptyTilePosition(); //set empty tile position


min_fn = get_fn(game_board); //-? min fn

std::wcout << L"=========================================" << std::endl;


printState(game_board, L"initial problem state");
std::wcout << L"initial empty tile position: " << emptyTile_row << L", " <<
emptyTile_col << std::endl;
std::wcout << L"initial fn (number of misplaced tiles): " << min_fn <<
std::endl;
std::wcout << L"=========================================" << std::endl;

//start hill climbing search


try
{
hill_climbing_search();
}
catch (const std::runtime_error &e)
{
std::wcout << L"Goal can not be reached, found closest solution state"
<< std::endl;
printState(min_fn_node->state, L"---------solution state------with min
fn " + std::to_wstring(min_fn));
}
}

void Eight_Puzzle::hill_climbing_search()
{

while (true)
{
std::wcout << L">========================================<" <<
std::endl;
std::wcout << L"cost/steps: " << (++stepCounter) << std::endl;
std::wcout << L"-------------" << std::endl;
//Priority.preState = game_board;//change pre state
Node *lowestPossible_fn_node = getLowestPossible_fn_node();
addToStackState(Priority::neighbors_nodeArray); //add neighbors to
stack in high to low order fn

printState(lowestPossible_fn_node->state, L"-------new state");


//print all fn values

//check for local maxima


int fnCounter = 1;
for (int i = 1; i < Priority::neighbors_nodeArray->length; i++)
{
if (Priority::neighbors_nodeArray[i - 1]->fn ==
Priority::neighbors_nodeArray[i].fn)
{ //fns are equal
fnCounter++;
}
}
if (Priority::neighbors_nodeArray->length != 1 && fnCounter ==
Priority::neighbors_nodeArray->length)
{ //all fns are equal, equal chances to choose
std::wcout << L"---fn's are equal, found in local maxima---" <<
std::endl;

//backtracking
for (int i = 0; i < Priority::neighbors_nodeArray->length; i++)
{
if (stack_state != nullptr)
{
std::wcout << L"pop " << (i + 1) << std::endl;
stack_state.pop();
}
else
{
std::wcout << L"empty stack inside loop" <<
std::endl;
}
}

if (stack_state != nullptr)
{
Node *gameNode = stack_state.pop();
game_board = gameNode->state; //update game board
Priority->preState = gameNode->parent; //update prestate
locateEmptyTilePosition(); //locate empty tile for updated
state

printState(game_board, L"popped state from all equal fn");


std::wcout << L"empty tile position: " << emptyTile_row <<
L", " << emptyTile_col << std::endl;
}
else
{
std::wcout << L"stack empty inside first lm check" <<
std::endl;
}
}
else
{ //for backtracking

std::wcout << L"lowest fn: " << lowestPossible_fn_node->fn <<


std::endl;

if (lowestPossible_fn_node->fn == 0)
{ //no misplaced found
std::wcout << L"-------------------------" << std::endl;
std::wcout << L"8-Puzzle has been solved!" << std::endl;
std::wcout << L"-------------------------" << std::endl;
std::wcout << L"Total cost/steps to reach the goal: " <<
stepCounter << std::endl;
std::wcout << L"-------------------------------------" <<
std::endl;
break;
}

if (lowestPossible_fn_node->fn <= min_fn)


{
min_fn = lowestPossible_fn_node->fn;
min_fn_node = lowestPossible_fn_node; //store lowest fn
solution

if (stack_state != nullptr)
{
Node *gameNode = stack_state.pop();
game_board = gameNode->state; //update game board
Priority->preState = gameNode->parent; //update
prestate
locateEmptyTilePosition(); //locate empty tile for
updated state

printState(game_board, L"-------new state as going


deeper");
std::wcout << L"empty tile position: " <<
emptyTile_row << L", " << emptyTile_col << std::endl;
}
else
{
std::wcout << L"stack empty" << std::endl;
}

}
else
{
std::wcout << L"---stuck in local maxima---" << std::endl;
std::wcout << L"getting higher, not possible" << std::endl;
//break;

//backtracking
for (int i = 0; i < Priority::neighbors_nodeArray->length;
i++)
{
if (stack_state != nullptr)
{
//System.out.println("pop " + (i + 1));
stack_state.pop();
}
else
{
std::wcout << L"empty stack inside loop" <<
std::endl;
}

}
if (stack_state != nullptr)
{

Node *gameNode = stack_state.pop();


game_board = gameNode->state; //update game board
Priority->preState = gameNode->parent; //update
prestate
locateEmptyTilePosition(); //locate empty tile for
updated state

printState(game_board, L"popped state from getting


higher");
std::wcout << L"empty tile position: " <<
emptyTile_row << L", " << emptyTile_col << std::endl;
}
else
{
std::wcout << L"stack empty inside second lm check"
<< std::endl;
}
} //end of if cond: new fn<=pre min fn
} //end of if cond: all fn equal
} //while end
}

Node *Eight_Puzzle::getLowestPossible_fn_node()
{

if (emptyTile_row == 0 && emptyTile_col == 0)


{ //0,0 position is empty tile
//System.out.println("Empty 0,0");
std::vector<Node*> fn_array = {get_fn_down(), get_fn_right()};
Node *lowest_fn_node = Priority::sort(fn_array);
return lowest_fn_node;

}
else if (emptyTile_row == 0 && emptyTile_col == 1)
{ //0,1 position is empty tile
//System.out.println("Empty 0,1");
std::vector<Node*> fn_array = {get_fn_left(), get_fn_down(),
get_fn_right()};
Node *lowest_fn_node = Priority::sort(fn_array);
return lowest_fn_node;

You might also like