package sudoku.solver;

import java.util.List;
import java.util.concurrent.CancellationException;

import sudoku.structure.Cell;
import sudoku.structure.MultiDoku;

public class BacktrackingSolver implements Solver {

	/**
	 * Résout le MultiDoku passé en paramètre, avec backtracking.
	 *
	 * @param doku MultiDoku, MultiDoku à résoudre.
	 * @return boolean, valant true si le MultiDoku est résolu, false sinon.
	 */
	@Override
	public boolean solve(MultiDoku doku, List<SolverStep> steps) {
		if (Thread.interrupted())
			throw new CancellationException("User wants to stop the solver");

		if (doku.isSolved()) {
			return true;
		}

		Cell cellToFill = doku.getFirstEmptyCell();
		if (cellToFill == null) {
			return false;
		}

		List<Integer> possibleSymbols = cellToFill.getPossibleSymbols();
		if (possibleSymbols.isEmpty()) {
			return false;
		}

		for (int symbol : possibleSymbols) {
			cellToFill.setSymbolIndex(symbol);
			addStep(cellToFill, steps);
			if (this.solve(doku, steps)) {
				return true;
			} else {
				cellToFill.setSymbolIndex(Cell.NOSYMBOL);
				addStep(cellToFill, steps);
			}
		}
		return false;
	}

}
