Example #1
0
        public ActionResult Index(int k = 0)
        {
            int?[,] numbers = new int?[9, 9];

            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    string key = string.Format("f{0}{1}", i, j);
                    int number;
                    if (int.TryParse(Request[key], out number))
                        numbers[i, j] = number;
                }
            }

            Game game = new Game(numbers);
            Solver solver = new Solver();

            try
            {
                DateTime start = DateTime.Now;
                solver.Solve(game);
                DateTime end = DateTime.Now;

                ViewBag.Interval = string.Format("Solved in {0} ms.", end.Subtract(start).Milliseconds);
            }
            catch (InvalidGameException)
            {
                ViewBag.Message = "Invalid entry.  There is no solution for the game!";
            }

            ViewBag.Numbers = game.Numbers;
            return View();
        }
Example #2
0
        public void Solve(Game game)
        {
            bool progress = true;

            while (progress && !game.IsSolved)
            {
                //Console.Out.Write(game);
                //Console.Out.WriteLine("");

                progress = SolveIteration(game);

                if (!progress && !game.IsSolved)
                {
                    progress = SearchSolution(game);
                }
            }
        }
Example #3
0
        private bool SearchSolution(Game game)
        {
            // Plan B if SearchIteration doesn't make progress.
            // Make a copy of the game, and do a depth first search on possible permutations, until a feasible solution is found.

            Stack<Game> gameStack = new Stack<Game>();
            gameStack.Push(game);

            bool result = SearchSolutionRecursive(gameStack);

            Game copy = gameStack.Peek();
            var unsolvedTiles = game.GetFlattenedTiles().Where(t => !t.IsSolved);
            foreach (Tile tile in unsolvedTiles)
            {
                tile.Number = copy[tile.XIndex, tile.YIndex].Number;
            }

            return result;
        }
Example #4
0
        public void TestExpert()
        {
            int?[,] setup = new int?[,]
            {
                { 5, null, 6, null, null, 4, null, null, null },
                { 4, null, null, null, null, null, null, 2, null },
                { null, 2, null, null, null, null, 5, null, 7 },
                { null, null, null, 7, null, 8, null, null, null },
                { null, null, null, null, 3, null, 2, null, 1 },
                { null, null, null, null, null, null, 3, null, null },
                { 1, null, null, 4, null, 2, null, null, 5 },
                { null, null, 4, null, null, 5, 8, null, null },
                { null, null, 3, 6, 8, null, null, null, 2 }
            };

            Game game = new Game(setup);
            Solver solver = new Solver();
            solver.Solve(game);

            Console.Out.Write(game);
            Assert.IsTrue(game.IsSolved);
        }
Example #5
0
        public void TestEasy()
        {
            int?[,] setup = new int?[,]
            {
                { null, null, 9, 1, null, null, null, null, 3 },
                { null, 5, 6, 2, 8, 9, 7, 1, 4 },
                { null, 7, 8, 6, 4, 3, 2, null, null },
                { null, null, 2, null, null, null, 1, null, 9 },
                { null, 3, 7, 5, null, null, 8, null, null },
                { null, 1, 4, 9, null, null, null, 6, null },
                { 8, null, 5, null, null, null, null, null, 1 },
                { 4, 6, 3, null, null, null, null, 2, null },
                { 7, 9, null, null, 5, null, null, null, null }
            };

            Game game = new Game(setup);
            Solver solver = new Solver();
            solver.Solve(game);

            Console.Out.Write(game);
            Assert.IsTrue(game.IsSolved);
        }
Example #6
0
        private bool SolveIteration(Game game)
        {
            bool tileSolved = false;
            IEnumerable<int> allNumbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            // The main idea here: first search all tiles and determine if any unsolved tiles are solvable (i.e. we can narrow the candidates to a single number).
            // Then walk through all of the numbers and determine if there are any rows, columns, or squares for which that number can fit in only one of the nine tiles.
            // Return true if at least one tile is solved this way (so we can try again), false otherwise.

            foreach (Tile tile in game.GetFlattenedTiles())
            {
                if (tile.IsSolved)
                    continue;

                IEnumerable<int> numbers = allNumbers.Except(tile.Row.Numbers)
                                                     .Except(tile.Column.Numbers)
                                                     .Except(tile.Square.Numbers);

                if (numbers.Count() == 0)
                {
                    throw new InvalidGameException();
                }

                if (numbers.Count() == 1)
                {
                    tile.Number = numbers.First();
                    tileSolved = true;
                }
            }

            foreach (int number in allNumbers)
            {
                tileSolved |= SolveForNumber(game.Rows, number);
                tileSolved |= SolveForNumber(game.Columns, number);
                tileSolved |= SolveForNumber(game.Squares, number);
            }

            return tileSolved;
        }