Esempio n. 1
0
        // Constructor
        // filename - file from which to read the puzzle
        public Sudoku(string filename)
        {
            // TODO:  Add the following exception handling
            //        - Validate that the length of the first row is a perfect square value
            //        - Validate that each line contains the same number of elements
            //        - Validate that each element is a numeric value between 1 and gridSize or the unknown value
            using (TextFieldParser parser = new TextFieldParser(filename))
            {
                int row = 0;
                parser.Delimiters = new string[] { "," };
                while (!parser.EndOfData)
                {
                    // Read in a line of the puzzle
                    string[] parts = parser.ReadFields();

                    if (row == 0)
                    {
                        //Initialize the grid
                        gridSize = parts.Length;
                        subGridSize = Convert.ToInt32(Math.Sqrt(gridSize));
                        sudokuGrid = new NumberBlock[gridSize, gridSize];

                        // Initialize the range of possible block values
                        rangeOfValues = new List<int>(Enumerable.Range(1, gridSize).ToList());
                    }

                    // Populate the puzzle
                    for (var col = 0; col < gridSize; col++)
                    {
                        sudokuGrid[row, col] = new NumberBlock(row, col, subGridSize, Convert.ToInt32(parts[col]));
                    }
                    row++;
                }
            }
        }
Esempio n. 2
0
        // Constructor
        // puzzle - the sudoku puzzle to be solved
        public Sudoku(int[,] puzzle)
        {
            // TODO:  Error checking - check puzzle is actually a grid

            //Initialize the grid
            gridSize = puzzle.GetLength(0);
            subGridSize = Convert.ToInt32(Math.Sqrt(gridSize));
            sudokuGrid = new NumberBlock[gridSize, gridSize];

            // Initialize the range of possible block values
            rangeOfValues = new List<int>(Enumerable.Range(1, gridSize).ToList());

            // Populate the grid with the data passed in
            for (var row = 0; row < gridSize; row++)
                for (var col = 0; col < gridSize; col++)
                {
                    try
                    {
                        sudokuGrid[row, col] = new NumberBlock(row, col, subGridSize, puzzle[row, col]);
                    }
                    catch (Exception e)
                    {
                        // TODO:  Do something more intelligent with the exception...
                        return;
                    }
                }
        }
Esempio n. 3
0
        public void NumberBlockConstructorSuccessful()
        {
            try
            {
                NumberBlock nb = new NumberBlock(1, 2, 3);
                Assert.IsFalse(nb.ValueSet);
                Assert.AreEqual(nb.PossibleValues.Count, 9);
                Assert.AreEqual(nb.Row, 1);
                Assert.AreEqual(nb.Column, 2);
                Assert.AreEqual(nb.Grid, 0);
                Assert.AreEqual(nb.RangeOfValues.Count, 9);
            }
            catch (NumberBlock.PositionException e)
            {
                Assert.Fail("Constructor should not have thrown the PositionExcpetion");
            }
            catch (NumberBlock.ValueException e)
            {
                Assert.Fail("Constructor should not have thrown the ValueException");
            }

            try
            {
                NumberBlock nb = new NumberBlock(4, 3, 3, 8);
                Assert.IsTrue(nb.ValueSet);
                Assert.AreEqual(nb.Value, 8);
                Assert.AreEqual(nb.Row, 4);
                Assert.AreEqual(nb.Column, 3);
                Assert.AreEqual(nb.Grid, 4);
                Assert.AreEqual(nb.PossibleValues.Count, 0);
                Assert.AreEqual(nb.RangeOfValues.Count, 9);
            }
            catch (NumberBlock.PositionException e)
            {
                Assert.Fail("Constructor should not have thrown the PositionExcpetion");
            }
            catch (NumberBlock.ValueException e)
            {
                Assert.Fail("Constructor should not have thrown the ValueException");
            }
        }
Esempio n. 4
0
        // This method handles updating a specific block's possible values
        private void UpdateBlockPossibleValues(NumberBlock block, int value)
        {
            var possibleVals = block.PossibleValues;
            if (possibleVals.Contains(value))
            {
                possibleVals.Remove(value);
                block.PossibleValues = possibleVals;

                // If the block is now set, recurively call MarkValueAsUsed
                if (block.ValueSet)
                {
                    MarkValueAsUsed(block);
                }
            }
        }
Esempio n. 5
0
        // This method iterated through the row, column and grid for a block that has been set
        // and removes the block value from the possibleValues list of each block.  This may result
        // in another block being set.  This method is called recursively to set subsequent blocks.
        private void MarkValueAsUsed(NumberBlock block)
        {
            for (var col = 0; col < gridSize; col++)
            {
                UpdateBlockPossibleValues(sudokuGrid[block.Row, col], block.Value);
            }

            for (var row = 0; row < gridSize; row++)
            {
                UpdateBlockPossibleValues(sudokuGrid[row, block.Column], block.Value);
            }

            int startingRow = (block.Grid / subGridSize) * subGridSize;
            int startingCol = (block.Grid % subGridSize) * subGridSize;
            for (int row = startingRow; row < startingRow + subGridSize; row++)
                for (int col = startingCol; col < startingCol + subGridSize; col++)
                {
                    UpdateBlockPossibleValues(sudokuGrid[row, col], block.Value);
                }
        }
Esempio n. 6
0
        public void UpdatePossibleValues()
        {
            List<int> possibleValues = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
            NumberBlock nb = null;

            try
            {
                nb = new NumberBlock(0, 0, 3);
            }
            catch (NumberBlock.PositionException e)
            {
                Assert.Fail("No exception should have been raised, PositionException raised");
            }
            catch (NumberBlock.ValueException e)
            {
                Assert.Fail("No exception should have been raised, ValueException raised");
            }
            Assert.IsFalse(nb.ValueSet);
            Assert.AreEqual(possibleValues.Count, nb.PossibleValues.Count);
            foreach (var value in nb.PossibleValues)
            {
                Assert.IsTrue(possibleValues.Contains(value));
            }

            // Only even numbers possible
            possibleValues = new List<int>() { 2, 4, 6, 8 };
            nb.PossibleValues = possibleValues;
            Assert.AreEqual(possibleValues.Count, nb.PossibleValues.Count);
            Assert.IsFalse(nb.ValueSet);
            foreach (var value in nb.PossibleValues)
            {
                Assert.IsTrue(possibleValues.Contains(value));
            }

            // Only the value 6 left
            possibleValues = new List<int> { 6 };
            nb.PossibleValues = possibleValues;
            Assert.AreEqual(nb.PossibleValues.Count, 0);
            Assert.IsTrue(nb.ValueSet);
            Assert.AreEqual(6, nb.Value);
        }
Esempio n. 7
0
        public void NumbeBlockConstructorThrowsPositionException()
        {
            // Row number < 0
            try
            {
                NumberBlock nb = new NumberBlock(-1, 0, 3, 1);
                Assert.Fail("Constructor should have thown a PositionException, no exception thrown");
            }
            catch (NumberBlock.PositionException e)
            {
                // success
            }
            catch (NumberBlock.ValueException e)
            {
                Assert.Fail("Constructor should have thrown a PositionException, ValueException thrown");
            }

            // Row number >= 9
            try
            {
                NumberBlock nb = new NumberBlock(9, 0, 3, 1);
                Assert.Fail("Constructor should have thown a PositionException, no exception thrown");
            }
            catch (NumberBlock.PositionException e)
            {
                // success
            }
            catch (NumberBlock.ValueException e)
            {
                Assert.Fail("Constructor should have thrown a PositionException, ValueException thrown");
            }

            // Column number < 0
            try
            {
                NumberBlock nb = new NumberBlock(0, -1, 3, 1);
                Assert.Fail("Constructor should have thown a PositionException, no exception thrown");
            }
            catch (NumberBlock.PositionException e)
            {
                // success
            }
            catch (NumberBlock.ValueException e)
            {
                Assert.Fail("Constructor should have thrown a PositionException, ValueException thrown");
            }

            // Column number >= 9
            try
            {
                NumberBlock nb = new NumberBlock(0, 9, 3, 1);
                Assert.Fail("Constructor should have thown a PositionException, no exception thrown");
            }
            catch (NumberBlock.PositionException e)
            {
                // success
            }
            catch (NumberBlock.ValueException e)
            {
                Assert.Fail("Constructor should have thrown a PositionException, ValueException thrown");
            }
        }
Esempio n. 8
0
        public void NumberBlockConstructorThrowsValueException()
        {
            // Value < -1
            try
            {
                NumberBlock nb = new NumberBlock(0, 0, 2, -3);
            }
            catch (NumberBlock.ValueException e)
            {
                // success
            }
            catch (NumberBlock.PositionException e)
            {
                Assert.Fail("Constructor should have thrown a ValueException, PositionException thrown");
            }

            // Value > 9
            try
            {
                NumberBlock nb = new NumberBlock(0, 0, 4, 10);
            }
            catch (NumberBlock.ValueException e)
            {
                // success
            }
            catch (NumberBlock.PositionException e)
            {
                Assert.Fail("Constructor should have thrown a ValueException, PositionException thrown");
            }
        }