public static SudokuBoard Samurai() { SudokuBoard board = new SudokuBoard(SamuraiAreas*BoxSize, SamuraiAreas*BoxSize, DefaultSize); // Removed the empty areas where there are no tiles var queriesForBlocked = new List<IEnumerable<SudokuTile>>(); queriesForBlocked.Add(from pos in box(BoxSize, BoxSize*2) select board.Tile(pos.Item1 + DefaultSize, pos.Item2 )); queriesForBlocked.Add(from pos in box(BoxSize, BoxSize*2) select board.Tile(pos.Item1 + DefaultSize, pos.Item2 + DefaultSize * 2 - BoxSize)); queriesForBlocked.Add(from pos in box(BoxSize*2, BoxSize) select board.Tile(pos.Item1 , pos.Item2 + DefaultSize)); queriesForBlocked.Add(from pos in box(BoxSize*2, BoxSize) select board.Tile(pos.Item1 + DefaultSize * 2 - BoxSize, pos.Item2 + DefaultSize)); foreach (var query in queriesForBlocked) { foreach (var tile in query) tile.Block(); } // Select the tiles in the 3 x 3 area (area.X, area.Y) and create rules for them foreach (var area in box(SamuraiAreas, SamuraiAreas)) { var tilesInArea = from pos in box(BoxSize, BoxSize) select board.Tile(area.Item1 * BoxSize + pos.Item1, area.Item2 * BoxSize + pos.Item2); if (tilesInArea.First().IsBlocked) continue; board.CreateRule("Area " + area.Item1.ToString() + ", " + area.Item2.ToString(), tilesInArea); } // Select all rows and create columns for them var cols = from pos in box(board.Width, 1) select new { X = pos.Item1, Y = pos.Item2 }; var rows = from pos in box(1, board.Height) select new { X = pos.Item1, Y = pos.Item2 }; foreach (var posSet in Enumerable.Range(0, board.Width)) { board.CreateRule("Column Upper " + posSet, from pos in box(1, DefaultSize) select board.Tile(posSet, pos.Item2)); board.CreateRule("Column Lower " + posSet, from pos in box(1, DefaultSize) select board.Tile(posSet, pos.Item2 + DefaultSize + BoxSize)); board.CreateRule("Row Left " + posSet, from pos in box(DefaultSize, 1) select board.Tile(pos.Item1, posSet)); board.CreateRule("Row Right " + posSet, from pos in box(DefaultSize, 1) select board.Tile(pos.Item1 + DefaultSize + BoxSize, posSet)); if (posSet >= BoxSize*2 && posSet < BoxSize*2 + DefaultSize) { // Create rules for the middle sudoku board.CreateRule("Column Middle " + posSet, from pos in box(1, 9) select board.Tile(posSet, pos.Item2 + BoxSize*2)); board.CreateRule("Row Middle " + posSet, from pos in box(9, 1) select board.Tile(pos.Item1 + BoxSize*2, posSet)); } } return board; }
public static SudokuBoard ClassicWithSpecialBoxes(string[] areas) { int sizeX = areas[0].Length; int sizeY = areas.Length; SudokuBoard board = new SudokuBoard(sizeX, sizeY); var joinedString = String.Join("", areas); var grouped = joinedString.Distinct(); // Loop through all the unique characters foreach (var ch in grouped) { // Select the rule tiles based on the index of the character var ruleTiles = from i in Enumerable.Range(0, joinedString.Length) where joinedString[i] == ch // filter out any non-matching characters select board.Tile(i % sizeX, i / sizeY); board.CreateRule("Area " + ch.ToString(), ruleTiles); } return board; }
private static void CompleteSolve(SudokuBoard board) { Console.WriteLine("Rules:"); board.OutputRules(); Console.WriteLine("Board:"); board.Output(); var solutions = board.Solve().ToList(); Console.WriteLine("Base Board Progress:"); board.Output(); Console.WriteLine("--"); Console.WriteLine("--"); Console.WriteLine("All " + solutions.Count + " solutions:"); var i = 1; foreach (var solution in solutions) { Console.WriteLine("----------------"); Console.WriteLine("Solution " + i++.ToString() + " / " + solutions.Count + ":"); solution.Output(); } }
public SudokuBoard(SudokuBoard copy) { _maxValue = copy._maxValue; tiles = new SudokuTile[copy.Width, copy.Height]; CreateTiles(); // Copy the tile values foreach (var pos in SudokuFactory.box(Width, Height)) { tiles[pos.Item1, pos.Item2] = new SudokuTile(pos.Item1, pos.Item2, _maxValue); tiles[pos.Item1, pos.Item2].Value = copy.tiles[pos.Item1, pos.Item2].Value; } // Copy the rules foreach (SudokuRule rule in copy.rules) { var ruleTiles = new HashSet <SudokuTile>(); foreach (SudokuTile tile in rule) { ruleTiles.Add(tiles[tile.X, tile.Y]); } rules.Add(new SudokuRule(ruleTiles, rule.Description)); } }
public SudokuBoard(SudokuBoard copy) { _maxValue = copy._maxValue; tiles = new SudokuTile[copy.Width, copy.Height]; CreateTiles(); // Copy the tile values foreach (var pos in SudokuFactory.box(Width, Height)) { tiles[pos.Item1, pos.Item2] = new SudokuTile(pos.Item1, pos.Item2, _maxValue); tiles[pos.Item1, pos.Item2].Value = copy.tiles[pos.Item1, pos.Item2].Value; } // Copy the rules foreach (SudokuRule rule in copy.rules) { var ruleTiles = new HashSet<SudokuTile>(); foreach (SudokuTile tile in rule) { ruleTiles.Add(tiles[tile.X, tile.Y]); } rules.Add(new SudokuRule(ruleTiles, rule.Description)); } }
public IEnumerable<SudokuBoard> Solve() { ResetSolutions(); SudokuProgress simplify = SudokuProgress.PROGRESS; while (simplify == SudokuProgress.PROGRESS) simplify = Simplify(); if (simplify == SudokuProgress.FAILED) yield break; // Find one of the values with the least number of alternatives, but that still has at least 2 alternatives var query = from rule in rules from tile in rule where tile.PossibleCount > 1 orderby tile.PossibleCount ascending select tile; SudokuTile chosen = query.FirstOrDefault(); if (chosen == null) { // The board has been completed, we're done! yield return this; yield break; } Console.WriteLine("SudokuTile: " + chosen.ToString()); foreach (var value in Enumerable.Range(1, _maxValue)) { // Iterate through all the valid possibles on the chosen square and pick a number for it if (!chosen.IsValuePossible(value)) continue; var copy = new SudokuBoard(this); copy.Tile(chosen.X, chosen.Y).Fix(value, "Trial and error"); foreach (var innerSolution in copy.Solve()) yield return innerSolution; } yield break; }
public static SudokuBoard SizeAndBoxes(int width, int height, int boxCountX, int boxCountY) { SudokuBoard board = new SudokuBoard(width, height); board.AddBoxesCount(boxCountX, boxCountY); return board; }