private SudokuGridPosition GetPosition(ushort cellDist, SudokuGridMetrics metrics)
 {
     for (byte i = 0; i < metrics.MaximumNumber; ++i)
     {
         for (byte j = 0; j < metrics.MaximumNumber; ++j)
         {
             if (metrics.MaximumNumber * i + j == cellDist)
             {
                 return(new SudokuGridPosition(j, i, false));
             }
         }
     }
     return(Empty);
 }
        /// <summary>
        /// Shifts this position for the specified number of cells.
        /// </summary>
        /// <param name="cellsShifting">Left shift performed if the value is negative;
        /// right shift performed if the value is positive;
        /// no shift performed if the value is 0.</param>
        /// <param name="metrics">Metrics of the grid with this position.</param>
        /// <returns></returns>
        internal bool Shift(ushort cellsShifting, SudokuGridMetrics metrics)
        {
            if (cellsShifting == 0)
            {
                return(false);
            }
            int  cellDist       = metrics.MaximumNumber * Y + X;
            bool crossedEarlier = crossedGridBorder;

            this = GetPosition((ushort)((cellDist + cellsShifting) % metrics.CellsTotal), metrics);
            if (crossedEarlier ||
                !crossedGridBorder && ((cellDist + Math.Abs(cellsShifting)) / metrics.CellsTotal) == 1)
            {
                crossedGridBorder = true;
            }
            return(true);
        }
Exemple #3
0
        /// <summary>
        /// Creates binary file with compressed data.
        /// </summary>
        /// <param name="textFile">File with text representation of a grid.</param>
        /// <param name="outputFilePath">Fully qualified name of output file.</param>
        /// <param name="alg">Preferable compression algorithm.</param>
        /// <returns>Seeked to the beginning binary file with read-write acessibilty 
        /// (existing file will be overwritten).</returns>
        public static FileStream CreateBinaryFromText(FileStream textFile, string outputFilePath, 
            SudokuConvertionAlgorithm alg)
        {
            // TODO: ? duplicate functionality -- use ToBinary(FileStream,  ...) instead
            textFile.Position = 0;
            string content = new StreamReader(textFile).ReadToEnd();
            textFile.Position = 0;

            var restrictions = SudokuGridConstraints.Traditional;
            var metrics = new SudokuGridMetrics(9, 3, 3);
            byte[] binary = SudokuConverter.ToBinary(content, alg, restrictions, metrics);

            var outputFile = new FileStream(outputFilePath, FileMode.Create, FileAccess.ReadWrite);
            outputFile.Write(binary, 0, binary.Length);
            outputFile.Position = 0;

            return outputFile;
        }
Exemple #4
0
 protected SudokuGrid(SudokuGridConstraints constraints, byte maxNumber, byte blockWidth, byte blockHeight)
 {
     this.constraints = constraints;
     metrics = new SudokuGridMetrics(maxNumber, blockWidth, blockHeight);
     cells = new SudokuGridCell[maxNumber, maxNumber];
 }
Exemple #5
0
 protected SudokuGrid(SudokuGridConstraints constraints, byte maxNumber, byte blockWidth, byte blockHeight)
 {
     this.constraints = constraints;
     metrics          = new SudokuGridMetrics(maxNumber, blockWidth, blockHeight);
     cells            = new SudokuGridCell[maxNumber, maxNumber];
 }
Exemple #6
0
        public static byte[] ToBinary(string content, SudokuConvertionAlgorithm algorithm, 
            SudokuGridConstraints constraints, SudokuGridMetrics metrics)
        {
            byte[] compressedContent;
            byte[] result;
            switch (algorithm)
            {
                case SudokuConvertionAlgorithm.Uniform:
                    compressedContent = TextToBinaryUniform(content, metrics.MaximumNumber);
                    result = new byte[(constraints == SudokuGridConstraints.Traditional)
                        ? HEADER_UNIFORM_LENGTH
                        : HEADER_UNIFORM_RESTRICTED_LENGTH
                        + compressedContent.Length];
                    //if (constraints == SudokuGridConstraints.Traditional)
                    //{
                    //    result = new byte[HEADER_UNIFORM_LENGTH + compressedContent.Length];
                    //}
                    //else
                    //{
                    //    result = new byte[HEADER_UNIFORM_RESTRICTED_LENGTH + compressedContent.Length];
                    //}
                    result[0] = (byte)SudokuConvertionAlgorithm.Uniform;
                    result[1] = (byte)constraints;
                    result[2] = metrics.MaximumNumber;
                    result[3] = metrics.BlockWidth;
                    result[4] = metrics.BlockHeight;
                    if (constraints != SudokuGridConstraints.Traditional)
                    {
                        throw new NotImplementedException();
                        //var restrictionsPos = (ushort)();
                        //result[5] = (byte)();
                    }
                    Array.Copy(compressedContent, 0, result, (constraints == SudokuGridConstraints.Traditional)
                        ? HEADER_UNIFORM_LENGTH
                        : HEADER_UNIFORM_RESTRICTED_LENGTH,
                        compressedContent.Length);
                    return result;

                case SudokuConvertionAlgorithm.NonUniform:
                    ushort zerosPairsPos;
                    byte bitsPerPos;
                    byte bitsPerZerosQuantity;
                    compressedContent = TextToBinaryNonUniform(content, metrics.MaximumNumber, out zerosPairsPos,
                        out bitsPerPos, out bitsPerZerosQuantity);
                    result = new byte[(constraints == SudokuGridConstraints.Traditional)
                        ? HEADER_NONUNIFORM_LENGTH
                        : HEADER_NONUNIFORM_RESTRICTED_LENGTH
                        + compressedContent.Length];
                    result[0] = (byte)SudokuConvertionAlgorithm.NonUniform;
                    result[1] = (byte)(zerosPairsPos >> 8);
                    result[2] = (byte)zerosPairsPos;
                    result[3] = (byte)(((bitsPerPos - 1) << 4) | (bitsPerZerosQuantity - 1));
                    result[4] = (byte)constraints;
                    result[5] = metrics.MaximumNumber;
                    result[6] = metrics.BlockWidth;
                    result[7] = metrics.BlockHeight;
                    Array.Copy(compressedContent, 0, result, (constraints == SudokuGridConstraints.Traditional)
                        ? HEADER_NONUNIFORM_LENGTH
                        : HEADER_NONUNIFORM_RESTRICTED_LENGTH,
                        compressedContent.Length);
                    //Array.Copy(compressedContent, 0, result, NONLINEAR_HEADER_LENGTH, compressedContent.Length);
                    return result;

                default:
                    return null;
            }
        }
Exemple #7
0
        private static string BinaryNonUniformToText(byte[] data, SudokuGridMetrics metrics,
            ushort zerosPairsPos, byte bitsPerPos, byte bitsPerZerosQuantity, SudokuGridConstraints constraints)
        {
            // extraction
            var numbers = new byte[zerosPairsPos];
            Array.Copy(data, 0, numbers, 0, zerosPairsPos);
            numbers = DecompressNumbers(numbers, metrics.MaximumNumber);
            if (numbers[numbers.Length - 1] == 0)
            {
                var nums = new byte[numbers.Length - 1];
                Array.Copy(numbers, 0, nums, 0, nums.Length);
                numbers = nums;
            }
            var zerosPairsCompressed = new byte[data.Length - zerosPairsPos];
            Array.Copy(data, zerosPairsPos, zerosPairsCompressed, 0, zerosPairsCompressed.Length);
            ushort[] zerosPairs = DecompressZerosPairs(zerosPairsCompressed, bitsPerPos,
                bitsPerZerosQuantity);

            // combining decompressed sequences
            var sb = new StringBuilder(metrics.CellsTotal);
            ushort j;
            ushort indNumbers = 0;
            ushort indZerosPairs = 0;
            for (ushort i = 0; i < metrics.CellsTotal; )
            {
                if ((indZerosPairs < zerosPairs.Length) &&
                    (i < zerosPairs[indZerosPairs])) // possible numbers are at the beginning
                {
                    sb.Append(numbers[indNumbers++]);
                    ++i;
                }
                else if ((indZerosPairs < zerosPairs.Length) &&
                    (i == zerosPairs[indZerosPairs])) // zeros (either at the beginning or later)
                {
                    indZerosPairs++;
                    for (j = 0; j < zerosPairs[indZerosPairs]; ++j, ++i)
                    {
                        sb.Append("0");
                    }
                    indZerosPairs++;
                }
                else // numbers are at the end
                {
                    for (j = i; j < metrics.CellsTotal; ++j, ++i)
                    {
                        sb.Append(numbers[indNumbers++]);
                    }
                }
            }

            return sb.ToString();
        }
Exemple #8
0
 public static string ToText(FileStream binaryFile, out SudokuGridConstraints constraints, 
     out byte[] numbersKinds, out SudokuGridMetrics metrics)
 {
     var binary = new byte[binaryFile.Length];
     binaryFile.Position = 0;
     binaryFile.Read(binary, 0, (int)binaryFile.Length);
     binaryFile.Position = 0;
     return ToText(binary, out constraints, out numbersKinds, out metrics);
 }
Exemple #9
0
        public static string ToText(byte[] binary, out SudokuGridConstraints constraints, 
            out byte[] numbersKinds, out SudokuGridMetrics metrics)
        {
            // !!! temporary !!!
            numbersKinds = null;
            var alg = (SudokuConvertionAlgorithm)(binary[0]);
            byte[] data;
            switch (alg)
            {
                case SudokuConvertionAlgorithm.Uniform:
                    constraints = (SudokuGridConstraints)(binary[1]);
                    metrics = new SudokuGridMetrics(binary[2], binary[3], binary[4]);
                    data = new byte[binary.Length - ((constraints == SudokuGridConstraints.Traditional)
                        ? HEADER_UNIFORM_LENGTH
                        : HEADER_UNIFORM_RESTRICTED_LENGTH)];
                    Array.Copy(binary, (constraints == SudokuGridConstraints.Traditional)
                        ? HEADER_UNIFORM_LENGTH
                        : HEADER_UNIFORM_RESTRICTED_LENGTH,
                        data, 0, data.Length);
                    return BinaryUniformToText(data, binary[2], constraints);

                case SudokuConvertionAlgorithm.NonUniform:
                    var zerosPairsPos = (ushort)((binary[1] << 8) | binary[2]);
                    var bitsPerPos = (byte) ((binary[3] >> 4) + 1);
                    var bitsPerZerosQuantity = (byte) (((byte) (binary[3] << 4) >> 4) + 1);
                    constraints = (SudokuGridConstraints)(binary[4]);
                    metrics = new SudokuGridMetrics(binary[5], binary[6], binary[7]);
                    data = new byte[binary.Length - ((constraints == SudokuGridConstraints.Traditional)
                        ? HEADER_NONUNIFORM_LENGTH
                        : HEADER_NONUNIFORM_RESTRICTED_LENGTH)];
                    Array.Copy(binary, (constraints == SudokuGridConstraints.Traditional)
                        ? HEADER_NONUNIFORM_LENGTH
                        : HEADER_NONUNIFORM_RESTRICTED_LENGTH,
                        data, 0, data.Length);
                    return BinaryNonUniformToText(data, metrics, zerosPairsPos, bitsPerPos,
                        bitsPerZerosQuantity, constraints);

                default:
                    // dummy code
                    constraints = SudokuGridConstraints.Traditional;
                    metrics = SudokuGridMetrics.Empty;
                    return null;
            }
        }