
#include "Grille.h"
#include <iostream>
#include <stack>
#include <ctime>
using namespace std;

int hard[9][9]={
	{0,0,6,0,0,5,8,0,0},
	{9,0,0,0,8,0,0,3,0},
	{0,0,0,2,0,0,0,1,0},
	{0,0,0,4,0,2,0,0,0},
	{0,2,9,0,6,0,4,8,0},
	{4,0,0,7,0,0,0,0,2},
	{0,9,4,0,2,0,7,0,0},
	{0,8,0,0,7,0,0,0,1},
	{0,7,0,8,4,3,0,2,0}};

int moy[9][9]={
	{9,6,3,0,0,0,0,4,0},
	{5,4,7,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,7,5},
	{1,0,0,7,0,9,0,0,0},
	{0,0,0,0,1,0,0,0,0},
	{3,2,0,8,0,0,0,9,0},
	{0,9,2,0,8,0,3,6,0},
	{0,5,0,6,0,0,0,0,0},
	{0,3,6,1,0,7,0,5,4}};

int easy[9][9]={
	{2,0,4,5,0,0,8,0,0},
	{0,0,7,0,1,2,0,0,4},
	{0,0,0,0,0,0,0,0,0},
	{1,3,2,6,0,5,0,9,0},
	{5,0,0,0,0,0,0,0,3},
	{0,4,0,3,0,9,5,2,1},
	{0,0,0,0,0,0,0,0,0},
	{7,0,0,4,5,0,1,0,0},
	{0,0,6,0,0,1,3,0,8}};


int evil[9][9]={
	{4,2,0,0,0,0,0,1,0},
	{0,0,0,5,4,0,0,3,0},
	{0,0,6,0,0,7,0,0,0},
	{0,0,0,0,0,0,2,7,9},
	{0,1,0,0,0,0,0,6,0},
	{3,4,2,0,0,0,0,0,0},
	{0,0,0,9,0,0,3,0,0},
	{0,6,0,0,3,8,0,0,0},
	{0,8,0,0,0,0,0,5,7}};


int test[9][9]={
	{0,0,6,0,0,8,0,0,2},
	{9,0,0,0,2,0,0,0,0},
	{0,0,7,0,0,0,5,9,0},
	{1,0,0,7,3,0,0,0,9},
	{8,0,0,4,0,2,0,0,1},
	{3,0,0,0,8,9,0,0,6},
	{0,8,4,0,0,0,2,0,0},
	{0,0,0,0,5,0,0,0,4},
	{7,0,0,2,0,0,8,0,0}
	};


bool simple_choice(Grid& g)
{
	Grid current(g);
	unsigned maxIter = 100;
	unsigned iter = 0;
	bool newChoice = true;
	stack<Grid> gridSave;
	gridSave.push(g);
	cout << "(/!\) Initial solution" << endl;
	print(cout, current); cout << endl;

	while (++iter < maxIter)
	{
		cout << iter << " <------------------- " << endl;
		current.best();
		current.remove_best();

		do { current.simplify(); } while (current.once());

		if (not current.deprecated())
		{
			cout << "(?) not deprecated" << endl;
			print(cout, current); cout << endl;

			if (current.final())
			{
				g = current;
				return true;
			}
			iter = 0;
			current.setProbability();
			gridSave.push(current);
		}
		else
		{
			cout << "(!) Deprecated..." << endl;
			cout << current << endl;

			if (gridSave.size() == 0)
				continue;
			else
			{
				cout << "(!) view the previous solution..." << endl;
				current = gridSave.top();
				gridSave.pop();
			}
		}
	}
	return false;
}


int main(int argc, char *argv[])
{
	Grid g;
	g.load(test);
	g.simplify();

	cout << g << endl;
	bool once_passed = false;


	double start, end;
	int it = 0; int maxIter = 100;
	start = clock();
	while(it < maxIter)
	{
		if (not once_passed) 
		{
			while (g.once())
				g.simplify();
			once_passed = true;
		}
		else
		{
			if (not g.final())
			{
				//cout << "Oops, no more possible substitution" << endl;
				// running another method

				/*
					set the proba
				*/
				g.setProbability();
				while (g.once())
					g.simplify();

				if (not simple_choice(g))
				{
					print(cout, g);
					cout << "Oops, it does nothing..." << endl;
				}
				else
				{
					cout << "The solution is..." << endl;
					break;
				}
			}
			else
			{
				cout << "The solution is..." << endl;
				break;
			}
		}
		++it;
	}
	end = clock();
	double v = end - start;
	cout << (v) << " ms" << endl;

	cout << endl << "Okay ?" << endl;
	cout << g << endl;
	return 0;
}

