/// <summary> /// Method for solving the sudoku in a separate thread. /// </summary> public void Reworker() { TakePicture.Instance.solvedSudoku = ArrayHandling.Solve(TakePicture.Instance.unsolvedSudoku, ref TakePicture.Instance.success); if (TakePicture.Instance.success) { Popup.queued = new KeyValuePair <string, System.Action>(SolvedMessage, null); } TakePicture.Status = TakePicture.StatusDone; //triggers a check in TakePicture.Update to refill the sudoku with the new solution print("Recalculation done"); }
/// <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; } }