using System.Collections.Generic; using uqac_ia_sudoku_csp.Interfaces; namespace uqac_ia_sudoku_csp.Solver.NextValueChoosers { public class MrvNextCellChooser : INextCellChooser { private readonly INextCellChooser _nextCellChooser; public MrvNextCellChooser(INextCellChooser nextCellChooser) { _nextCellChooser = nextCellChooser; } public void SelectVariable(Board board, out int x, out int y, IList constraints) { var avail = 1; var vars = new List>(); while (avail <= board.Size && vars.Count == 0) { for (var xx = 0; xx < board.Size; ++xx) { for (var yy = 0; yy < board.Size; ++yy) { if (board.GetNumber(xx, yy) == null) { var remaining = GetRemainingValue(board, xx, yy, constraints); if (remaining == avail) { vars.Add(new KeyValuePair(xx, yy)); } } } } ++avail; } if (vars.Count == 0) { x = -1; y = -1; } else if (vars.Count == 1 || _nextCellChooser == null) { x = vars[0].Key; y = vars[0].Value; } else { _nextCellChooser.SelectVariable(board, out x, out y, constraints); } } protected int GetRemainingValue(Board board, int x, int y, IList constraints) { var c = 0; for (var i = 0; i < board.Size; ++i) { board.SetNumber(x, y, i); if (board.IsConsistent(x, y, constraints)) { ++c; } } board.ClearNumber(x, y); return c; } } }