using System.Collections.Generic; using System.Linq; using uqac_ia_sudoku_csp.Interfaces; using uqac_ia_sudoku_csp.Solver.Constraints; namespace uqac_ia_sudoku_csp.Solver { public class BacktrackSearch : ISolver { private readonly INextValueChooser _nextValueChooser; protected IList Constraints; public BacktrackSearch(INextValueChooser nextValueChooser) { _nextValueChooser = nextValueChooser; Constraints = new List { new LineContraint(), new ColumnConstraint(), new BlockConstraint() }; } public SolverResult Resolve(Board board) { var domain = Enumerable.Range(0, board.Size).ToList(); var result = new SolverResult(); result.Success = RecursiveResolve(board, result, domain); return result; } protected bool RecursiveResolve(Board board, SolverResult result, IList domain) { if (board.IsComplete()) { return true; } int x, y; _nextValueChooser.SelectVariable(board, out x, out y, Constraints); if (x != -1 && y != -1) { foreach (var value in domain) { ++result.TryCount; board.SetNumber(x, y, value); if (board.IsConsistent(x, y, Constraints)) { if (RecursiveResolve(board, result, domain)) { return true; } } } board.ClearNumber(x, y); } return false; } } }