コード例 #1
0
        public static SudokuBoard ClassicWith3x3BoxesAndHyperRegions()
        {
            SudokuBoard board       = ClassicWith3x3Boxes();
            const int   HyperSecond = HyperMargin + BoxSize + HyperMargin;

            // Create the four extra hyper regions
            board.CreateRule("HyperA", from pos in box(3, 3) select board.Tile(pos.Item1 + HyperMargin, pos.Item2 + HyperMargin));
            board.CreateRule("HyperB", from pos in box(3, 3) select board.Tile(pos.Item1 + HyperSecond, pos.Item2 + HyperMargin));
            board.CreateRule("HyperC", from pos in box(3, 3) select board.Tile(pos.Item1 + HyperMargin, pos.Item2 + HyperSecond));
            board.CreateRule("HyperD", from pos in box(3, 3) select board.Tile(pos.Item1 + HyperSecond, pos.Item2 + HyperSecond));
            return(board);
        }
コード例 #2
0
        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);
        }
コード例 #3
0
ファイル: SudokuFactory.cs プロジェクト: Zomis/SudokuSharp
        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;
        }
コード例 #4
0
        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;
        }
コード例 #5
0
ファイル: SudokuFactory.cs プロジェクト: Zomis/SudokuSharp
        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;
        }
コード例 #6
0
        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);
        }
コード例 #7
0
ファイル: SudokuBoard.cs プロジェクト: Zomis/SudokuSharp
        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;
        }