Ejemplo n.º 1
0
    /// <summary>
    /// Refreshes the sudoku view after a change is made.
    /// </summary>
    public void RecalculateSudoku()
    {
        print("Recalculating sudoku");
        TakePicture.debugText.enabled = true;
        TakePicture.Status            = "Solving Sudoku";
        Sudoku.transform.parent.gameObject.SetActive(false);

        TakePicture.Instance.unsolvedSudoku = new int[9, 9];
        TakePicture.Instance.solvedSudoku   = new int[9, 9];
        SudokuTile[] sudokuTiles = Sudoku.GetComponentsInChildren <SudokuTile>(true);

        //Reads the values from the sudoku tiles, see TakePicture.FillSudoku
        int x, y;

        for (int i = 0; i < 81; i++)
        {
            x = (i / 3) % 3 + (i / 27) * 3;
            y = 8 - (i % 3 + ((i / 9) % 3) * 3);
            if (sudokuTiles[i].Defined)
            {
                TakePicture.Instance.unsolvedSudoku[x, y] = sudokuTiles[i].Value;
            }
        }

        TakePicture.Instance.allZero = ArrayHandling.OnlyZeroes(TakePicture.Instance.unsolvedSudoku);

        //there should not be an active work thread at this point, but if there is, shut it down
        if (TakePicture.Instance.workThread != null && TakePicture.Instance.workThread.IsAlive)
        {
            TakePicture.Instance.workThread.Abort();
            TakePicture.Instance.workThread.Join(200);
        }
        //start reworker in a new thread
        TakePicture.Instance.workThread = new System.Threading.Thread(Reworker);
        TakePicture.Instance.workThread.Start();
    }
Ejemplo n.º 2
0
    /// <summary>
    /// The main working method. Handles the flow from creating a bitmap
    /// from the scanned image to analysing its digits and solving the sudoku.
    /// </summary>
    /// <param name="pixels">The scanned image as a one-dimensional array of Colors.</param>
    public void Worker(Color[] pixels)
    {
        try
        {
            var timer = System.Diagnostics.Stopwatch.StartNew();
            //cut out the sudoku part
            pixels = ArrayHandling.Cut(pixels, textureWidth, textureHeight,
                                       (textureWidth - side) / 2, (textureHeight - side) / 2, side, side);

            Status = "Creating Bitmap";                                                 //the current status is displayed while the background thread is active
            bool[] bits = Bitify(pixels, side, side, HorizontalChunks, VerticalChunks); //generate a "black-and-white" bitmap from the picture

            int[] coords;
            int   searchRadius;
            Status = "Finding Corners";

            int[][] corners = OCR.FindCorners2(bits, side, side, CornerQueueLength); //find the corners of the sudoku
            if (corners == null)
            {
                Popup.queued = new KeyValuePair <string, System.Action>(OCR.NoSudokuMessage, null);
                corners      = new int[][] { new int[] { 0, 0 }, new int[] { 0, 0 }, new int[] { 0, 0 }, new int[] { 0, 0 } };
            }

            #if WRITE_IMAGES_TO_DISK
            foreach (int[] corner in corners)
            {
                colorq.Enqueue(new KeyValuePair <int, Color>(corner[0] + corner[1] * side, Color.yellow));
            }
            #endif

            searchRadius = Mathf.RoundToInt(SearchRadiusFactor * Mathf.Sqrt(
                                                Mathf.Pow((corners[2][0] - corners[0][0]) / 9f, 2) +
                                                Mathf.Pow((corners[2][1] - corners[0][1]) / 9f, 2)
                                                ));

            Status = "Finding Digits";
            coords = OCR.FindDigitCoordinates(corners, side);             //calculate where the digits should be

            Status         = "Identifying Digits";
            unsolvedSudoku = OCR.GetSudoku(bits, side, side, coords, searchRadius, storedBitmaps, InstantMatchPercent, MaxStoredBitmapsPerDigit);             //identify all digits

            allZero = ArrayHandling.OnlyZeroes(unsolvedSudoku);

            var sb = new System.Text.StringBuilder();
            for (int y = 8; y >= 0; y--)
            {
                for (int x = 0; x < 9; x++)
                {
                    sb.Append(unsolvedSudoku[x, y]);
                }
                sb.AppendLine();
            }
            print(sb);

            Status       = "Solving Sudoku";
            solvedSudoku = ArrayHandling.Solve(unsolvedSudoku, ref success);             //solve the sudoku

            if (!success)
            {
                Popup.queued = new KeyValuePair <string, System.Action>(CannotSolveMessage, null);
            }

            sb = new System.Text.StringBuilder();
            for (int y = 8; y >= 0; y--)
            {
                for (int x = 0; x < 9; x++)
                {
                    sb.Append(solvedSudoku[x, y]);
                }
                sb.AppendLine();
            }
            print(sb);

            #if WRITE_IMAGES_TO_DISK
            Status = "Rendering Debug Picture";
            for (int i = 0; i < pixels.Length; i++)
            {
                pixels[i] = bits[i] ? Color.white : Color.black;
            }

            while (colorq.Count > 0)
            {
                var kvp = colorq.Dequeue();
                if (kvp.Key >= 0 && kvp.Key < pixels.Length)
                {
                    pixels[kvp.Key] = kvp.Value;
                }
            }
            #endif
            debugPicture = pixels;


            timer.Stop();
            print("Done");
            print("Time: " + timer.ElapsedMilliseconds + " ms");
            Status = StatusDone;             //signal to the main thread that the solved sudoku is availible
        }
        catch (System.Exception e)
        {
            print(e);
            Status = StatusError + e.Message;
        }
    }