Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Sudoku Solver By TechKiwiGadgets May 2019
- /*
- * V1 - Final Product Version for First Instructables Release based off dev version 101
- * - Solve now includes help test at end of solve to highlight any errors in red
- * - Includes 5th Hard puzzle as a challenge!
- *
- *
- *
- *
- *
- *
- *
- *
- *
- * ARRAY POSITIONS & KEY VARIABLES BELOW *************************************************************
- // Array with following locations: {0 , 1 , 2 3 4, 5, 6, 7, 8, 9,10,11,12, 13 }
- // Array with following Structure: {Solved, value , X , Y , V1,V2,V3,V4,V5,V6,V7,V8,V9 panel# }
- colcoord[9] = { 10, 34, 58, 90, 114, 138, 170, 194, 218 };
- rowcoord[9] = { 8, 33, 58, 88, 113, 138, 170, 194, 218 };
- int location = 1;
- const int sudoku[81][12];
- */
- #include <Adafruit_GFX.h> // Core graphics library
- #include <Adafruit_TFTLCD.h> // Hardware-specific library
- #include <TouchScreen.h>
- #define YP A3 // must be an analog pin, use "An" notation!
- #define XM A2 // must be an analog pin, use "An" notation!
- #define YM 9 // can be a digital pin
- #define XP 8 // can be a digital pin
- // Revised Touch Callibration numbers
- #define TS_MINX 130
- #define TS_MINY 88
- #define TS_MAXX 915
- //#define TS_MAXY 927
- #define TS_MAXY 880
- // For better pressure precision, we need to know the resistance
- // between X+ and X- Use any multimeter to read it
- // For the one we're using, its 300 ohms across the X plate
- TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
- #define LCD_CS A3
- #define LCD_CD A2
- #define LCD_WR A1
- #define LCD_RD A0
- // optional
- #define LCD_RESET A4
- // Assign human-readable names to some common 16-bit color values:
- // I had to reverse these colors for my screen
- int BLACK = 0x0000;
- int RED = 0x001F;
- int BLUE = 0xF800;
- int GREEN = 0x07E0;
- int YELLOW = 0x07FF;
- int MAGENTA = 0xF81F;
- int CYAN = 0xFFE0;
- int WHITE = 0xFFFF;
- Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
- #define BOX 78 // Block to clear screen
- #define BOXSIZE 80
- #define BUTTON 20
- boolean debounce = false; // Used to debounce touch screen input
- // Array with following Structure: {value , X , Y , Solved }
- const byte colcoord[9] = { 10, 34, 58, 90, 114, 138, 170, 194, 218 };
- const byte rowcoord[9] = { 8, 33, 58, 88, 113, 138, 170, 194, 218 };
- byte location = 1;
- byte puzzlenum = 1; // These identifier for 5 puzzles stored in memory
- byte sudoku[82][14];
- byte touchlocation = 0; // Used to track the array value that the stylis is closest to in the Sudoku 9x9 framework
- int delay1 = 400; // Pause input into screen
- byte tempreading = 0;
- void setup(void) {
- // Serial.begin(9600);
- // Serial.println(F("Paint!"));
- tft.reset();
- uint16_t identifier = tft.readID();
- identifier=0x9325;
- tft.begin(identifier);
- tft.setRotation(1);
- tft.fillScreen(BLACK);
- // **** Splash Screen
- tft.drawRoundRect(0, 0, 320, 240, 20, BLUE);
- tft.drawRoundRect(1, 1, 318, 238, 20, BLUE);
- byte g = 70;
- tft.drawCircle(46, g, 25, GREEN);
- tft.fillCircle(46, g, 20, GREEN);
- tft.setTextColor(BLACK); tft.setTextSize(3);
- tft.setCursor(39, g-10); tft.println("S");
- tft.drawCircle(91, g+30, 25, BLUE);
- tft.fillCircle(91, g+30, 20, BLUE);
- tft.setTextColor(BLACK); tft.setTextSize(3);
- tft.setCursor(84, g+20); tft.println("U");
- tft.drawCircle(137, g, 25, YELLOW);
- tft.fillCircle(137, g, 20, YELLOW);
- tft.setTextColor(BLACK); tft.setTextSize(3);
- tft.setCursor(130, g-10); tft.println("D");
- tft.drawCircle(183, g+30, 25, RED);
- tft.fillCircle(183, g+30, 20, RED);
- tft.setTextColor(BLACK); tft.setTextSize(3);
- tft.setCursor(176, g+20); tft.println("O");
- tft.drawCircle(229, g, 25, GREEN);
- tft.fillCircle(229, g, 20, GREEN);
- tft.setTextColor(BLACK); tft.setTextSize(3);
- tft.setCursor(222, g-10); tft.println("K");
- tft.drawCircle(274, g+30, 25, YELLOW);
- tft.fillCircle(274, g+30, 20, YELLOW);
- tft.setTextColor(BLACK); tft.setTextSize(3);
- tft.setCursor(267, g+20); tft.println("U");
- tft.setTextColor(WHITE); tft.setTextSize(2);
- tft.setCursor(25, 170); tft.println("Play, Create, Solve");
- tft.setTextColor(GREEN); tft.setTextSize(1);
- tft.setCursor(25, 200); tft.println("By TechKiwiGadgets 2019");
- delay(4000);
- tft.fillScreen(BLACK);
- drawscreen(); // Clearscreen and setup Sudoku matrix
- resetmatrix(); // Initialize the sudoku matrix by setting all locations to zero and loading in the coordinates for each touch location
- loadpaneldata(); // Load specifc Panel identification Data into the Array for each of the 81 locations
- solvealigndata(); // Sanitize test puzzle data with correct data format
- // Test Display by showing all values in the puzzle - White are Solved , Blue are others
- tft.setTextSize(2);
- for (byte a = 1; a < 82; a++) {
- //Test solve or set condition
- if (sudoku[a][1] != 0) {
- if (sudoku[a][0] != 0) {
- tft.setTextColor(WHITE);
- } else {
- tft.setTextColor(GREEN); // Set this colour if not a genuine set clue
- }
- tft.setCursor( sudoku[a][3], sudoku[a][2]);
- tft.println(sudoku[a][1]);
- }
- }
- drawbuttons();
- pinMode(13, OUTPUT);
- // testText();
- }
- #define MINPRESSURE 5
- #define MAXPRESSURE 1000
- // tft.begin(identifier);
- void loop()
- {
- // Read the Touch Screen Locations
- digitalWrite(13, HIGH);
- TSPoint p = ts.getPoint();
- digitalWrite(13, LOW);
- // if sharing pins, you'll need to fix the directions of the touchscreen pins
- pinMode(XM, OUTPUT);
- pinMode(YP, OUTPUT);
- // we have some minimum pressure we consider 'valid'
- // pressure of 0 means no pressing!
- if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
- /*
- Serial.print("X = "); Serial.print(p.x);
- Serial.print("\tY = "); Serial.print(p.y);
- Serial.print("\tPressure = "); Serial.println(p.z);
- */
- // scale from 0->1023 to tft.width
- p.x = map(p.x, TS_MINX, TS_MAXX, 0, 240);
- p.y = map(p.y, TS_MINY, TS_MAXY, 0, 320); // Original Code
- /*
- Serial.print("X = "); Serial.print(p.x);
- Serial.print("\tY = "); Serial.print(p.y);
- Serial.print("\tPressure = "); Serial.println(p.z);
- */
- // Calculate the position of the screen touch based on the input values of p.x and p.y
- if ((p.x > 0) && (p.x < 27)) { // Coloumn 1
- if ((p.y > 0) && (p.y < 27)) { // Row 1
- touchlocation = 1;
- }
- if ((p.y > 28) && (p.y < 53)) { // Row 2
- touchlocation = 2;
- }
- if ((p.y > 54) && (p.y < 80)) { // Row 3
- touchlocation = 3;
- }
- if ((p.y > 81) && (p.y < 107)) { // Row 4
- touchlocation = 4;
- }
- if ((p.y > 108) && (p.y < 133)) { // Row 5
- touchlocation = 5;
- }
- if ((p.y > 134) && (p.y < 160)) { // Row 6
- touchlocation = 6;
- }
- if ((p.y > 161) && (p.y < 187)) { // Row 7
- touchlocation = 7;
- }
- if ((p.y > 188) && (p.y < 213)) { // Row 8
- touchlocation = 8;
- }
- if ((p.y > 214) && (p.y < 240)) { // Row 9
- touchlocation = 9;
- }
- } else
- if ((p.x > 28) && (p.x < 53)) { // Coloumn 2
- if ((p.y > 0) && (p.y < 27)) { // Row 1
- touchlocation = 10;
- }
- if ((p.y > 28) && (p.y < 53)) { // Row 2
- touchlocation = 11;
- }
- if ((p.y > 54) && (p.y < 80)) { // Row 3
- touchlocation = 12;
- }
- if ((p.y > 81) && (p.y < 107)) { // Row 4
- touchlocation = 13;
- }
- if ((p.y > 108) && (p.y < 133)) { // Row 5
- touchlocation = 14;
- }
- if ((p.y > 134) && (p.y < 160)) { // Row 6
- touchlocation = 15;
- }
- if ((p.y > 161) && (p.y < 187)) { // Row 7
- touchlocation = 16;
- }
- if ((p.y > 188) && (p.y < 213)) { // Row 8
- touchlocation = 17;
- }
- if ((p.y > 214) && (p.y < 240)) { // Row 9
- touchlocation = 18;
- }
- } else
- if ((p.x > 54) && (p.x < 80)) { // Coloumn 3
- if ((p.y > 0) && (p.y < 27)) { // Row 1
- touchlocation = 19;
- }
- if ((p.y > 28) && (p.y < 53)) { // Row 2
- touchlocation = 20;
- }
- if ((p.y > 54) && (p.y < 80)) { // Row 3
- touchlocation = 21;
- }
- if ((p.y > 81) && (p.y < 107)) { // Row 4
- touchlocation = 22;
- }
- if ((p.y > 108) && (p.y < 133)) { // Row 5
- touchlocation = 23;
- }
- if ((p.y > 134) && (p.y < 160)) { // Row 6
- touchlocation = 24;
- }
- if ((p.y > 161) && (p.y < 187)) { // Row 7
- touchlocation = 25;
- }
- if ((p.y > 188) && (p.y < 213)) { // Row 8
- touchlocation = 26;
- }
- if ((p.y > 214) && (p.y < 240)) { // Row 9
- touchlocation = 27;
- }
- } else
- if ((p.x > 81) && (p.x < 107)) { // Coloumn 4
- if ((p.y > 0) && (p.y < 27)) { // Row 1
- touchlocation = 28;
- }
- if ((p.y > 28) && (p.y < 53)) { // Row 2
- touchlocation = 29;
- }
- if ((p.y > 54) && (p.y < 80)) { // Row 3
- touchlocation = 30;
- }
- if ((p.y > 81) && (p.y < 107)) { // Row 4
- touchlocation = 31;
- }
- if ((p.y > 108) && (p.y < 133)) { // Row 5
- touchlocation = 32;
- }
- if ((p.y > 134) && (p.y < 160)) { // Row 6
- touchlocation = 33;
- }
- if ((p.y > 161) && (p.y < 187)) { // Row 7
- touchlocation = 34;
- }
- if ((p.y > 188) && (p.y < 213)) { // Row 8
- touchlocation = 35;
- }
- if ((p.y > 214) && (p.y < 240)) { // Row 9
- touchlocation = 36;
- }
- } else
- if ((p.x > 108) && (p.x < 133)) { // Coloumn 5
- if ((p.y > 0) && (p.y < 27)) { // Row 1
- touchlocation = 37;
- }
- if ((p.y > 28) && (p.y < 53)) { // Row 2
- touchlocation = 38;
- }
- if ((p.y > 54) && (p.y < 80)) { // Row 3
- touchlocation = 39;
- }
- if ((p.y > 81) && (p.y < 107)) { // Row 4
- touchlocation = 40;
- }
- if ((p.y > 108) && (p.y < 133)) { // Row 5
- touchlocation = 41;
- }
- if ((p.y > 134) && (p.y < 160)) { // Row 6
- touchlocation = 42;
- }
- if ((p.y > 161) && (p.y < 187)) { // Row 7
- touchlocation = 43;
- }
- if ((p.y > 188) && (p.y < 213)) { // Row 8
- touchlocation = 44;
- }
- if ((p.y > 214) && (p.y < 240)) { // Row 9
- touchlocation = 45;
- }
- } else
- if ((p.x > 134) && (p.x < 160)) { // Coloumn 6
- if ((p.y > 0) && (p.y < 27)) { // Row 1
- touchlocation = 46;
- }
- if ((p.y > 28) && (p.y < 53)) { // Row 2
- touchlocation = 47;
- }
- if ((p.y > 54) && (p.y < 80)) { // Row 3
- touchlocation = 48;
- }
- if ((p.y > 81) && (p.y < 107)) { // Row 4
- touchlocation = 49;
- }
- if ((p.y > 108) && (p.y < 133)) { // Row 5
- touchlocation = 50;
- }
- if ((p.y > 134) && (p.y < 160)) { // Row 6
- touchlocation = 51;
- }
- if ((p.y > 161) && (p.y < 187)) { // Row 7
- touchlocation = 52;
- }
- if ((p.y > 188) && (p.y < 213)) { // Row 8
- touchlocation = 53;
- }
- if ((p.y > 214) && (p.y < 240)) { // Row 9
- touchlocation = 54;
- }
- } else
- if ((p.x > 161) && (p.x < 187)) { // Coloumn 7
- if ((p.y > 0) && (p.y < 27)) { // Row 1
- touchlocation = 55;
- }
- if ((p.y > 28) && (p.y < 53)) { // Row 2
- touchlocation = 56;
- }
- if ((p.y > 54) && (p.y < 80)) { // Row 3
- touchlocation = 57;
- }
- if ((p.y > 81) && (p.y < 107)) { // Row 4
- touchlocation = 58;
- }
- if ((p.y > 108) && (p.y < 133)) { // Row 5
- touchlocation = 59;
- }
- if ((p.y > 134) && (p.y < 160)) { // Row 6
- touchlocation = 60;
- }
- if ((p.y > 161) && (p.y < 187)) { // Row 7
- touchlocation = 61;
- }
- if ((p.y > 188) && (p.y < 213)) { // Row 8
- touchlocation = 62;
- }
- if ((p.y > 214) && (p.y < 240)) { // Row 9
- touchlocation = 63;
- }
- } else
- if ((p.x > 188) && (p.x < 213)) { // Coloumn 8
- if ((p.y > 0) && (p.y < 27)) { // Row 1
- touchlocation = 64;
- }
- if ((p.y > 28) && (p.y < 53)) { // Row 2
- touchlocation = 65;
- }
- if ((p.y > 54) && (p.y < 80)) { // Row 3
- touchlocation = 66;
- }
- if ((p.y > 81) && (p.y < 107)) { // Row 4
- touchlocation = 67;
- }
- if ((p.y > 108) && (p.y < 133)) { // Row 5
- touchlocation = 68;
- }
- if ((p.y > 134) && (p.y < 160)) { // Row 6
- touchlocation = 69;
- }
- if ((p.y > 161) && (p.y < 187)) { // Row 7
- touchlocation = 70;
- }
- if ((p.y > 188) && (p.y < 213)) { // Row 8
- touchlocation = 71;
- }
- if ((p.y > 214) && (p.y < 240)) { // Row 9
- touchlocation = 72;
- }
- } else
- if ((p.x > 214) && (p.x < 240)) { // Coloumn 9
- if ((p.y > 0) && (p.y < 27)) { // Row 1
- touchlocation = 73;
- }
- if ((p.y > 28) && (p.y < 53)) { // Row 2
- touchlocation = 74;
- }
- if ((p.y > 54) && (p.y < 80)) { // Row 3
- touchlocation = 75;
- }
- if ((p.y > 81) && (p.y < 107)) { // Row 4
- touchlocation = 76;
- }
- if ((p.y > 108) && (p.y < 133)) { // Row 5
- touchlocation = 77;
- }
- if ((p.y > 134) && (p.y < 160)) { // Row 6
- touchlocation = 78;
- }
- if ((p.y > 161) && (p.y < 187)) { // Row 7
- touchlocation = 79;
- }
- if ((p.y > 188) && (p.y < 213)) { // Row 8
- touchlocation = 80;
- }
- if ((p.y > 214) && (p.y < 240)) { // Row 9
- touchlocation = 81;
- }
- }
- // debounce function to remove issue with first touch screen reading being spurious
- if (debounce == false) {
- touchlocation = 0;
- debounce = true;
- }
- // This code only applies to stylis activity within the Sudokumatrix
- if ( ((p.x < 235)&&(p.y < 230))&& (touchlocation != 0)) {
- // tft.fillRect(250, 80, 15, 10, BLACK);
- /*
- Serial.print("Y = "); Serial.print(p.x);
- Serial.print("\tX = "); Serial.print(p.y);
- Serial.print("\tLocation = "); Serial.println(touchlocation);
- */
- // Calculate the incremental changes to the data array
- // Array Structure: {value , X , Y , Solved }
- // Only increment if has not been solved, Debounce by checking if this is the second time the same range is selected
- if ((tempreading == touchlocation)&&(sudoku[touchlocation][0]==0)||(tempreading == touchlocation)&&(sudoku[touchlocation][0]==2)) {
- sudoku[touchlocation][1]++;
- if (sudoku[touchlocation][1] > 9) {
- sudoku[touchlocation][1] = 0;
- }
- // Test to see if changing an item can be classified as solved
- if (sudoku[touchlocation][1]!=0) {
- sudoku[touchlocation][0]=2; // Set to Solved if a manually changed number however flag as manual change with va,ue of 2
- } else {
- sudoku[touchlocation][0]=0; // Set to Not Solved if 0
- }
- // Finally reset all of the data values in this location that have been manually changed to unsolved
- for (byte u = 1; u < 82; u++) {
- // If preprogrammed from a game then leave values otherwise reset data to baseline
- if (sudoku[u][0]!=1){
- for (byte q = 4; q < 13; q++) {
- sudoku[u][q]=q-3;
- }
- }
- }
- }
- // tft.setTextColor(WHITE); tft.setTextSize(1);
- // tft.setCursor(250, 80); tft.println(touchlocation);
- // Refresh only the location concerned with new value and show colour coded
- //First Clear Location
- tft.fillRect(sudoku[touchlocation][3], sudoku[touchlocation][2], 15, 15, BLACK);
- tft.setTextSize(2);
- if (sudoku[touchlocation][0] != 0) { // Do not draw 0 just leave blank square
- if (sudoku[touchlocation][0] == 1) {
- tft.setTextColor(WHITE);
- } else if (sudoku[touchlocation][0] == 2) {
- tft.setTextColor(GREEN); // Set this colour if not a genuine set clue
- }
- tft.setCursor( sudoku[touchlocation][3], sudoku[touchlocation][2]);
- tft.println(sudoku[touchlocation][1]);
- }
- if (tempreading == touchlocation) {
- delay(delay1);
- }
- tempreading = touchlocation; // take a first sample then repeat and compare to debounce
- }
- // Inside touch sensor reading if statement
- // HOME Button Pressed ************************************************
- if ( ((p.y > 255)&&(p.y < 300))&& ((p.x > 10)&&(p.x < 40))) {
- tft.fillCircle(280, 30, 20, WHITE);
- tft.setTextColor(BLACK); tft.setTextSize(1);
- tft.setCursor(268, 27); tft.println("HOME");
- delay(delay1/2);
- drawscreen(); // Clearscreen and setup Sudoku matrix
- resetmatrix(); // Initialize the sudoku matrix by setting all locations to zero:
- refreshdisplay();
- drawbuttons();
- }
- // PLAY Button Pressed ************************************************
- if ( ((p.y > 255)&&(p.y < 300))&& ((p.x > 80)&&(p.x < 110))) {
- //PLAY Button pressed
- //Button 2
- tft.fillCircle(280, 90, 20, WHITE);
- tft.setTextColor(BLACK); tft.setTextSize(1);
- tft.setCursor(268, 87); tft.println("PLAY");
- delay(delay1/2);
- drawscreen(); // Clearscreen and setup Sudoku matrix
- resetmatrix(); // Initialize the sudoku matrix by setting all locations to zero:
- loadtestpuzzle1(); // Loads test puzzle into the location array
- solvealigndata(); // Sanitize test puzzle data with correct data format
- refreshdisplay(); // Only display testpuzzle data locations that are
- drawbuttons(); // Redraw buttons togive push button effect
- tft.setCursor(277, 97); tft.println(puzzlenum);
- // Manage Puzzle Number
- puzzlenum++; // increment puzzle number
- if (puzzlenum > 5) {
- puzzlenum = 1;
- }
- }
- // HELP Button Pressed ************************************************
- if ( ((p.y > 255)&&(p.y < 300))&& ((p.x > 140)&&(p.x < 160))) {
- //Button 3
- tft.fillCircle(280, 150, 20, WHITE);
- tft.setTextColor(BLACK); tft.setTextSize(1);
- tft.setCursor(268, 147); tft.println("HELP");
- delay(delay1/2);
- // drawscreen(); // Clearscreen and setup Sudoku matrix
- // solvehorizontal(); // Solve horiontal rule
- // solvevertical(); // Solve vertical rule
- // solvepanel(); // Solve Panel rule
- helpbutton(); // Run algorythm and test for incorrect locations then highlight in red
- // reversesolve();
- delay(800);// Display the changes before reverting to original colors
- refreshdisplay(); // Only display testpuzzle data locations that are
- drawbuttons(); // Redraw buttons togive push button effect
- }
- // SOLVE Button Pressed ************************************************
- if ( ((p.y > 255)&&(p.y < 300))&& ((p.x > 200)&&(p.x < 220))) {
- //SOLVE Button Pressed
- //Button 4
- tft.fillCircle(280, 210, 20, WHITE);
- tft.setTextColor(BLACK); tft.setTextSize(1);
- tft.setCursor(266, 207); tft.println("SOLVE");
- delay(delay1/2);
- solvepanel(); // Solve Panel rule
- solvehorizontal(); // Solve horiontal rule
- solvevertical(); // Solve vertical rule
- reversesolvecolor();
- uniquecandidate(); // Test
- solvealigndata();
- reversesolvecolor();
- solvehorizontal(); // Solve horiontal rule
- solvevertical(); // Solve vertical rule
- solvepanel(); // Solve Panel rule
- reversesolvecolor();
- solvehorizontal(); // Solve horiontal rule
- solvevertical(); // Solve vertical rule
- solvepanel(); // Solve Panel rule
- reversesolvecolor();
- solvehorizontal(); // Solve horiontal rule
- solvevertical(); // Solve vertical rule
- solvepanel(); // Solve Panel rule
- reversesolvecolor();
- solvehorizontal(); // Solve horiontal rule
- solvevertical(); // Solve vertical rule
- solvepanel(); // Solve Panel rule
- reversesolvecolor();
- solvehorizontal(); // Solve horiontal rule
- solvevertical(); // Solve vertical rule
- solvepanel(); // Solve Panel rule
- reversesolvecolor();
- solvehorizontal(); // Solve horiontal rule
- solvevertical(); // Solve vertical rule
- solvepanel(); // Solve Panel rule
- reversesolvecolor();
- solvehorizontal(); // Solve horiontal rule
- solvevertical(); // Solve vertical rule
- solvepanel(); // Solve Panel rule
- reversesolvecolor();
- solvehorizontal(); // Solve horiontal rule
- solvevertical(); // Solve vertical rule
- solvepanel(); // Solve Panel rule
- reversesolvecolor();
- solvehorizontal(); // Solve horiontal rule
- solvevertical(); // Solve vertical rule
- solvepanel(); // Solve Panel rule
- reversesolvecolor();
- solvehorizontal(); // Solve horiontal rule
- solvevertical(); // Solve vertical rule
- solvepanel(); // Solve Panel rule
- reversesolvecolor();
- solvepanel(); // Solve Panel rule
- solvehorizontal(); // Solve horiontal rule
- solvevertical(); // Solve vertical rule
- reversesolvecolor();
- uniquecandidate(); // Test
- solvealigndata();
- reversesolvecolor();
- solvepanel(); // Solve Panel rule
- solvehorizontal(); // Solve horiontal rule
- solvevertical(); // Solve vertical rule
- reversesolvecolor();
- uniquecandidate(); // Test
- solvealigndata();
- reversesolvecolor();
- solvepanel(); // Solve Panel rule
- solvehorizontal(); // Solve horiontal rule
- solvevertical(); // Solve vertical rule
- reversesolvecolor();
- uniquecandidate(); // Test
- solvealigndata();
- reversesolvecolor();
- drawscreen(); // Clearscreen and setup Sudoku matrix
- refreshdisplay(); // Only display testpuzzle data locations that are
- helpbutton(); // Run algorythm and test for incorrect locations then highlight in red
- drawbuttons(); // Redraw buttons togive push button effect
- }
- /*
- Serial.print("Y = "); Serial.print(p.x);
- Serial.print("\tX = "); Serial.println(p.y);
- */
- p.z = 0;// Force the sensor value below threshold to avoid ghost values
- }
- }
- void loadtestpuzzle1(){
- // Test Puzzle example 1 loaded into array
- if (puzzlenum == 1 ){
- // Load Numbers
- sudoku[1][1] = 2; sudoku[3][1] = 9; sudoku[19][1] = 3; sudoku[21][1] = 5;
- sudoku[5][1] = 6; sudoku[6][1] = 3; sudoku[14][1] = 2; sudoku[23][1] = 9;
- sudoku[7][1] = 4; sudoku[9][1] = 8; sudoku[26][1] = 7;
- sudoku[39][1] = 1; sudoku[46][1] = 9; sudoku[47][1] = 7; sudoku[48][1] = 2;
- sudoku[31][1] = 9; sudoku[32][1] = 8; sudoku[50][1] = 1; sudoku[51][1] = 6;
- sudoku[34][1] = 7; sudoku[35][1] = 1; sudoku[36][1] = 6; sudoku[43][1] = 2;
- sudoku[56][1] = 3; sudoku[73][1] = 5; sudoku[75][1] = 6;
- sudoku[59][1] = 7; sudoku[68][1] = 3; sudoku[76][1] = 1; sudoku[77][1] = 4;
- sudoku[61][1] = 6; sudoku[63][1] = 1; sudoku[79][1] = 8; sudoku[81][1] = 7;
- // Set the Solved Flag for each
- sudoku[1][0] = 1; sudoku[3][0] = 1; sudoku[19][0] = 1; sudoku[21][0] = 1;
- sudoku[5][0] = 1; sudoku[6][0] = 1; sudoku[14][0] = 1; sudoku[23][0] = 1;
- sudoku[7][0] = 1; sudoku[9][0] = 1; sudoku[26][0] = 1;
- sudoku[39][0] = 1; sudoku[46][0] = 1; sudoku[47][0] = 1; sudoku[48][0] = 1;
- sudoku[31][0] = 1; sudoku[32][0] = 1; sudoku[50][0] = 1; sudoku[51][0] = 1;
- sudoku[34][0] = 1; sudoku[35][0] = 1; sudoku[36][0] = 1; sudoku[43][0] = 1;
- sudoku[56][0] = 1; sudoku[73][0] = 1; sudoku[75][0] = 1;
- sudoku[59][0] = 1; sudoku[68][0] = 1; sudoku[76][0] = 1; sudoku[77][0] = 1;
- sudoku[61][0] = 1; sudoku[63][0] = 1; sudoku[79][0] = 1; sudoku[81][0] = 1;
- } else
- if (puzzlenum == 2 ){
- // Load Numbers
- sudoku[1][1] = 4; sudoku[10][1] = 2; sudoku[19][1] = 1;
- sudoku[5][1] = 2; sudoku[15][1] = 4; sudoku[24][1] = 5;
- sudoku[25][1] = 2; sudoku[17][1] = 8; sudoku[18][1] = 6;
- sudoku[29][1] = 3; sudoku[30][1] = 2; sudoku[37][1] = 9; sudoku[39][1] = 5; sudoku[46][1] = 7; sudoku[47][1] = 6;
- sudoku[31][1] = 6; sudoku[40][1] = 4; sudoku[41][1] = 8; sudoku[42][1] = 3; sudoku[51][1] = 2;
- sudoku[35][1] = 4; sudoku[36][1] = 1; sudoku[43][1] = 6; sudoku[45][1] = 2; sudoku[52][1] = 3; sudoku[53][1] = 5;
- sudoku[57][1] = 1; sudoku[64][1] = 3; sudoku[65][1] = 8;
- sudoku[58][1] = 7; sudoku[67][1] = 5; sudoku[77][1] = 9;
- sudoku[63][1] = 9; sudoku[72][1] = 7; sudoku[81][1] = 5;
- // Set the Solved Flag for each
- sudoku[1][0] = 1; sudoku[10][0] = 1; sudoku[19][0] = 1;
- sudoku[5][0] = 1; sudoku[15][0] = 1; sudoku[24][0] = 1;
- sudoku[25][0] = 1; sudoku[17][0] = 1; sudoku[18][0] = 1;
- sudoku[29][0] = 1; sudoku[30][0] = 1; sudoku[37][0] = 1; sudoku[39][0] = 1; sudoku[46][0] = 1; sudoku[47][0] = 1;
- sudoku[31][0] = 1; sudoku[40][0] = 1; sudoku[41][0] = 1; sudoku[42][0] = 1; sudoku[51][0] = 1;
- sudoku[35][0] = 1; sudoku[36][0] = 1; sudoku[43][0] = 1; sudoku[45][0] = 1; sudoku[52][0] = 1; sudoku[53][0] = 1;
- sudoku[57][0] = 1; sudoku[64][0] = 1; sudoku[65][0] = 1;
- sudoku[58][0] = 1; sudoku[67][0] = 1; sudoku[77][0] = 1;
- sudoku[63][0] = 1; sudoku[72][0] = 1; sudoku[81][0] = 1;
- } else
- if (puzzlenum == 3 ){
- // Load Numbers
- sudoku[12][1] = 8; sudoku[19][1] = 4;
- sudoku[5][1] = 2; sudoku[13][1] = 9; sudoku[14][1] = 4; sudoku[22][1] = 7; sudoku[24][1] = 8;
- sudoku[7][1] = 8; sudoku[9][1] = 7; sudoku[25][1] = 2; sudoku[27][1] = 9;
- sudoku[28][1] = 1; sudoku[29][1] = 2; sudoku[38][1] = 4; sudoku[39][1] = 3; sudoku[30][1] = 7;
- sudoku[31][1] = 5; sudoku[41][1] = 8; sudoku[51][1] = 7;
- sudoku[43][1] = 5; sudoku[44][1] = 7; sudoku[52][1] = 9; sudoku[53][1] = 2; sudoku[54][1] = 4;
- sudoku[55][1] = 8; sudoku[57][1] = 9; sudoku[73][1] = 6; sudoku[75][1] = 4;
- sudoku[58][1] = 1; sudoku[60][1] = 2; sudoku[68][1] = 6; sudoku[69][1] = 9; sudoku[77][1] = 3;
- sudoku[70][1] = 1; sudoku[63][1] = 3;
- // Set the Solved Flag for each
- sudoku[12][0] = 1; sudoku[19][0] = 1;
- sudoku[5][0] = 1; sudoku[13][0] = 1; sudoku[14][0] = 1; sudoku[22][0] = 1; sudoku[24][0] = 1;
- sudoku[7][0] = 1; sudoku[9][0] = 1; sudoku[25][0] = 1; sudoku[27][0] = 1;
- sudoku[28][0] = 1; sudoku[29][0] = 1; sudoku[38][0] = 1; sudoku[39][0] = 1; sudoku[30][0] = 1;
- sudoku[31][0] = 1; sudoku[41][0] = 1; sudoku[51][0] = 1;
- sudoku[43][0] = 1; sudoku[44][0] = 1; sudoku[52][0] = 1; sudoku[53][0] = 1; sudoku[54][0] = 1;
- sudoku[55][0] = 1; sudoku[57][0] = 1; sudoku[73][0] = 1; sudoku[75][0] = 1;
- sudoku[58][0] = 1; sudoku[60][0] = 1; sudoku[68][0] = 1; sudoku[69][0] = 1; sudoku[77][0] = 1;
- sudoku[70][0] = 1; sudoku[63][0] = 1;
- } else
- if (puzzlenum == 4 ){
- // Load Numbers
- sudoku[3][1] = 6; sudoku[12][1] = 2;
- sudoku[5][1] = 7; sudoku[6][1] = 9; sudoku[13][1] = 1;
- sudoku[16][1] = 6; sudoku[17][1] = 5; sudoku[18][1] = 4; sudoku[25][1] = 7; sudoku[26][1] = 1;
- sudoku[29][1] = 6; sudoku[30][1] = 5; sudoku[37][1] = 8; sudoku[46][1] = 1; sudoku[48][1] = 3;
- sudoku[33][1] = 4; sudoku[40][1] = 7; sudoku[41][1] = 2; sudoku[42][1] = 5; sudoku[49][1] = 8;
- sudoku[34][1] = 9; sudoku[36][1] = 8; sudoku[45][1] = 3; sudoku[52][1] = 4; sudoku[53][1] = 7;
- sudoku[56][1] = 3; sudoku[57][1] = 7; sudoku[64][1] = 6; sudoku[65][1] = 4;sudoku[66][1] = 1;
- sudoku[76][1] = 6; sudoku[77][1] = 4; sudoku[69][1] = 3;
- sudoku[70][1] = 8; sudoku[79][1] = 5;
- // Set the Solved Flag for each
- sudoku[3][0] = 1; sudoku[12][0] = 1;
- sudoku[5][0] = 1; sudoku[6][0] = 1; sudoku[13][0] = 1;
- sudoku[16][0] = 1; sudoku[17][0] = 1; sudoku[18][0] = 1; sudoku[25][0] = 1; sudoku[26][0] = 1;
- sudoku[29][0] = 1; sudoku[30][0] = 1; sudoku[37][0] = 1; sudoku[46][0] = 1; sudoku[48][0] = 1;
- sudoku[33][0] = 1; sudoku[40][0] = 1; sudoku[41][0] = 1; sudoku[42][0] = 1; sudoku[49][0] = 1;
- sudoku[34][0] = 1; sudoku[36][0] = 1; sudoku[45][0] = 1; sudoku[52][0] = 1; sudoku[53][0] = 1;
- sudoku[56][0] = 1; sudoku[57][0] = 1; sudoku[64][0] = 1; sudoku[65][0] = 1;sudoku[66][0] = 1;
- sudoku[76][0] = 1; sudoku[77][0] = 1; sudoku[69][0] = 1;
- sudoku[70][0] = 1; sudoku[79][0] = 1;
- } else
- if (puzzlenum == 5 ){
- // Load Numbers
- sudoku[2][1] = 3; sudoku[3][1] = 2; sudoku[12][1] = 6; sudoku[21][1] = 9;
- sudoku[4][1] = 9; sudoku[5][1] = 8; sudoku[22][1] = 2;
- sudoku[17][1] = 3; sudoku[27][1] = 7;
- sudoku[30][1] = 7; sudoku[47][1] = 9;
- sudoku[31][1] = 1; sudoku[40][1] = 3; sudoku[42][1] = 5; sudoku[51][1] = 4;
- sudoku[35][1] = 5; sudoku[52][1] = 6;
- sudoku[55][1] = 2; sudoku[65][1] = 6;
- sudoku[60][1] = 9; sudoku[77][1] = 5; sudoku[78][1] = 3;
- sudoku[61][1] = 3; sudoku[70][1] = 7; sudoku[79][1] = 2; sudoku[80][1] = 6;
- // Set the Solved Flag for each
- sudoku[2][0] = 1; sudoku[3][0] = 1; sudoku[12][0] = 1; sudoku[21][0] = 1;
- sudoku[4][0] = 1; sudoku[5][0] = 1; sudoku[22][0] = 1;
- sudoku[17][0] = 1; sudoku[27][0] = 1;
- sudoku[30][0] = 1; sudoku[47][0] = 1;
- sudoku[31][0] = 1; sudoku[40][0] = 1; sudoku[42][0] = 1; sudoku[51][0] = 1;
- sudoku[35][0] = 1; sudoku[52][0] = 1;
- sudoku[55][0] = 1; sudoku[65][0] = 1;
- sudoku[60][0] = 1; sudoku[77][0] = 1; sudoku[78][0] = 1;
- sudoku[61][0] = 1; sudoku[70][0] = 1; sudoku[79][0] = 1; sudoku[80][0] = 1;
- }
- }
- void refreshdisplay() { //Refresh the display once a value has changed
- tft.setTextSize(2);
- for (byte a = 1; a < 82; a++) {
- //Test solve or set condition
- if (sudoku[a][1] != 0) {
- //First Clear Location
- tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);
- if (sudoku[a][0] != 0) { // Do not draw 0 just leave blank square
- if (sudoku[a][0] == 1) {
- tft.setTextColor(WHITE);
- } else if (sudoku[a][0] == 2) {
- tft.setTextColor(GREEN); // Set this colour if not a genuine set clue
- }
- tft.setCursor( sudoku[a][3], sudoku[a][2]);
- tft.println(sudoku[a][1]);
- }
- }
- }
- }
- void drawscreen(){
- // tft.fillScreen(BLACK);
- // Setup Screen
- GREEN = 0x07E0;
- tft.fillRect(1, 1, 239, 239, BLACK);
- tft.drawRect(0, 0, BOXSIZE, BOXSIZE, WHITE);
- tft.drawRect(0+BOXSIZE, 0, BOXSIZE, BOXSIZE, WHITE);
- tft.drawRect(0+BOXSIZE+BOXSIZE, 0, BOXSIZE, BOXSIZE, WHITE);
- tft.drawRect(0, BOXSIZE, BOXSIZE, BOXSIZE, WHITE);
- tft.drawRect(0+BOXSIZE, BOXSIZE, BOXSIZE, BOXSIZE, WHITE);
- tft.drawRect(0+BOXSIZE+BOXSIZE, BOXSIZE, BOXSIZE, BOXSIZE, WHITE);
- tft.drawRect(0, BOXSIZE*2, BOXSIZE, BOXSIZE, WHITE);
- tft.drawRect(0+BOXSIZE, BOXSIZE*2, BOXSIZE, BOXSIZE, WHITE);
- tft.drawRect(0+BOXSIZE+BOXSIZE, BOXSIZE*2, BOXSIZE, BOXSIZE, WHITE);
- }
- void resetmatrix(){ // Initialize the sudoku matrix by setting all locations to zero and loading in the coordinates for each touch location
- byte hole = 1;
- for (byte a = 0; a < 9; a++) {
- for (byte b = 0; b < 9; b++) {
- sudoku[hole][0] = 0; // Solve Flag
- sudoku[hole][1] = 0; // Display Value
- sudoku[hole][2] = colcoord[a]; // Matrix Column coordinate
- sudoku[hole][3] = rowcoord[b]; // Matrix Row coordinate
- sudoku[hole][4] = 1; // V1
- sudoku[hole][5] = 2; // V2
- sudoku[hole][6] = 3; // V3
- sudoku[hole][7] = 4; // V4
- sudoku[hole][8] = 5; // V5
- sudoku[hole][9] = 6; // V6
- sudoku[hole][10] = 7; // V7
- sudoku[hole][11] = 8; // V8
- sudoku[hole][12] = 9; // V9
- hole++;
- }
- }
- }
- void drawbuttons() {
- // Setup Buttons
- GREEN = 0x07E0;
- //Button 1
- tft.drawCircle(280, 30, 24, GREEN);
- tft.fillCircle(280, 30, 20, GREEN);
- tft.setTextColor(BLACK); tft.setTextSize(1);
- tft.setCursor(268, 27); tft.println("HOME");
- //Button 2
- tft.drawCircle(280, 90, 24, YELLOW);
- tft.fillCircle(280, 90, 20, YELLOW);
- tft.setTextColor(BLACK); tft.setTextSize(1);
- tft.setCursor(268, 87); tft.println("PLAY");
- //Button 3
- tft.drawCircle(280, 150, 24, MAGENTA);
- tft.fillCircle(280, 150, 20, MAGENTA);
- tft.setTextColor(BLACK); tft.setTextSize(1);
- tft.setCursor(268, 147); tft.println("HELP");
- //Button 4
- tft.drawCircle(280, 210, 24, BLUE);
- tft.fillCircle(280, 210, 20, BLUE);
- tft.setTextColor(BLACK); tft.setTextSize(1);
- tft.setCursor(266, 207); tft.println("SOLVE");
- }
- void solvealigndata(){ // Once a location is marked as solved then all data in that location nees to be set to Zero
- for (byte a = 1; a < 82; a++) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // If location solved then zero out all data in array except correct value
- /*
- Serial.print(a); Serial.print(" ");
- Serial.print(sudoku[a][1]); Serial.print(" ");
- Serial.print(3+sudoku[a][1]); Serial.print(" ");
- Serial.print(sudoku[a][4]);
- Serial.print(sudoku[a][5]);
- Serial.print(sudoku[a][6]);
- Serial.print(sudoku[a][7]);
- Serial.print(sudoku[a][8]);
- Serial.print(sudoku[a][9]);
- Serial.print(sudoku[a][10]);
- Serial.print(sudoku[a][11]);
- Serial.println(sudoku[a][12]);
- */
- sudoku[a][4] = 0; // V1
- sudoku[a][5] = 0; // V2
- sudoku[a][6] = 0; // V3
- sudoku[a][7] = 0; // V4
- sudoku[a][8] = 0; // V5
- sudoku[a][9] = 0; // V6
- sudoku[a][10] = 0; // V7
- sudoku[a][11] = 0; // V8
- sudoku[a][12] = 0; // V9
- // Now poke the answer into the correct location
- sudoku[a][(sudoku[a][1]+3)] = sudoku[a][1]; // Load the solved value into the array
- /*
- Serial.print(a); Serial.print(" ");
- Serial.print(sudoku[a][1]); Serial.print(" ");
- Serial.print(3+sudoku[a][1]); Serial.print(" ");
- Serial.print(sudoku[a][4]);
- Serial.print(sudoku[a][5]);
- Serial.print(sudoku[a][6]);
- Serial.print(sudoku[a][7]);
- Serial.print(sudoku[a][8]);
- Serial.print(sudoku[a][9]);
- Serial.print(sudoku[a][10]);
- Serial.print(sudoku[a][11]);
- Serial.println(sudoku[a][12]);
- */
- }
- }
- }
- void reversesolve(){ // subroutine to reverse engineer solved locations in the matrix and label themas solved
- byte tempcount = 0;
- for (byte a = 1; a < 82; a++) { // Cycle through all locations
- /*
- Serial.print(a); Serial.print(" ");
- Serial.print(sudoku[a][0]); Serial.print(" ");
- // Serial.print(3+sudoku[a][1]); Serial.print(" ");
- Serial.print(sudoku[a][4]);
- Serial.print(sudoku[a][5]);
- Serial.print(sudoku[a][6]);
- Serial.print(sudoku[a][7]);
- Serial.print(sudoku[a][8]);
- Serial.print(sudoku[a][9]);
- Serial.print(sudoku[a][10]);
- Serial.print(sudoku[a][11]);
- Serial.println(sudoku[a][12]);
- */
- if (sudoku[a][0] == 0) { // Ignore location if already solved
- // Read each and count the number that have been elimated
- tempcount = 0;
- for (byte b = 4; b < 13; b++) {
- if (sudoku[a][b] == 0) {// If equal to 0 then count
- tempcount++;
- }
- }
- if (tempcount == 8){ // If only one valid result then find again then mark location as solved
- for (byte c = 4; c < 13; c++) { // Read each and identify the only solution
- if (sudoku[a][c] > 0) {
- sudoku[a][0] = 1; // Set Solved Location Flag
- sudoku[a][1] = sudoku[a][c]; // Set value
- }
- }
- }
- }
- /*
- Serial.print(a); Serial.print(" ");
- Serial.print(sudoku[a][0]); Serial.print(" ");
- Serial.print(tempcount); Serial.print(" ");
- Serial.print(sudoku[a][4]);
- Serial.print(sudoku[a][5]);
- Serial.print(sudoku[a][6]);
- Serial.print(sudoku[a][7]);
- Serial.print(sudoku[a][8]);
- Serial.print(sudoku[a][9]);
- Serial.print(sudoku[a][10]);
- Serial.print(sudoku[a][11]);
- Serial.println(sudoku[a][12]);
- */
- }
- }
- void reversesolvecolor(){ // subroutine to reverse engineer solved locations in the matrix and label themas solved
- byte tempcount = 0;
- for (byte a = 1; a < 82; a++) { // Cycle through all locations
- /*
- Serial.print(a); Serial.print(" ");
- Serial.print(sudoku[a][0]); Serial.print(" ");
- // Serial.print(3+sudoku[a][1]); Serial.print(" ");
- Serial.print(sudoku[a][4]);
- Serial.print(sudoku[a][5]);
- Serial.print(sudoku[a][6]);
- Serial.print(sudoku[a][7]);
- Serial.print(sudoku[a][8]);
- Serial.print(sudoku[a][9]);
- Serial.print(sudoku[a][10]);
- Serial.print(sudoku[a][11]);
- Serial.println(sudoku[a][12]);
- */
- if (sudoku[a][0] == 0) { // Ignore location if already solved
- // Read each and count the number that have been elimated
- tempcount = 0;
- for (byte b = 4; b < 13; b++) {
- if (sudoku[a][b] == 0) {// If equal to 0 then count
- tempcount++;
- }
- }
- if (tempcount == 8){ // If only one valid result then find again then mark location as solved
- for (byte c = 4; c < 13; c++) { // Read each and identify the only solution
- if (sudoku[a][c] > 0) {
- sudoku[a][0] = 2; // Set Solved Location Flag
- sudoku[a][1] = sudoku[a][c]; // Set value
- }
- }
- }
- }
- /*
- Serial.print(a); Serial.print(" ");
- Serial.print(sudoku[a][0]); Serial.print(" ");
- Serial.print(tempcount); Serial.print(" ");
- Serial.print(sudoku[a][4]);
- Serial.print(sudoku[a][5]);
- Serial.print(sudoku[a][6]);
- Serial.print(sudoku[a][7]);
- Serial.print(sudoku[a][8]);
- Serial.print(sudoku[a][9]);
- Serial.print(sudoku[a][10]);
- Serial.print(sudoku[a][11]);
- Serial.println(sudoku[a][12]);
- */
- }
- }
- void solvehorizontal(){ // Take Solved locations and apply horizontal rule
- // Cycle through all locations and using solved flag remove all associate horizontal possibilities
- /*
- for (byte d = 1; d < 82; d++) { // Cycle through all locations
- Serial.print(d); Serial.print(" ");
- Serial.print(sudoku[d][0]); Serial.print(" ");
- Serial.print(sudoku[d][4]);
- Serial.print(sudoku[d][5]);
- Serial.print(sudoku[d][6]);
- Serial.print(sudoku[d][7]);
- Serial.print(sudoku[d][8]);
- Serial.print(sudoku[d][9]);
- Serial.print(sudoku[d][10]);
- Serial.print(sudoku[d][11]);
- Serial.println(sudoku[d][12]);
- }
- */
- // ROW 1 ************************
- // Step through each of ROW locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 1; a < 10; a++) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 1; r < 10; r++) {
- if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
- sudoku[r][sudoku[a][1]+3] = 0;
- }
- }
- }
- }
- // ROW 2 ************************
- // Step through each of ROW locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 10; a < 19; a++) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 10; r < 19; r++) {
- if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
- sudoku[r][sudoku[a][1]+3] = 0;
- }
- }
- }
- }
- // ROW 3 ************************
- // Step through each of ROW locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 19; a < 28; a++) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 19; r < 28; r++) {
- if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
- sudoku[r][sudoku[a][1]+3] = 0;
- }
- }
- }
- }
- // ROW 4 ************************
- // Step through each of ROW locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 28; a < 37; a++) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 28; r < 37; r++) {
- if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
- sudoku[r][sudoku[a][1]+3] = 0;
- }
- }
- }
- }
- // ROW 5 ************************
- // Step through each of ROW locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 37; a < 46; a++) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 37; r < 46; r++) {
- if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
- sudoku[r][sudoku[a][1]+3] = 0;
- }
- }
- }
- }
- // ROW 6 ************************
- // Step through each of ROW locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 46; a < 55; a++) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 46; r < 55; r++) {
- if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
- sudoku[r][sudoku[a][1]+3] = 0;
- }
- }
- }
- }
- // ROW 7 ************************
- // Step through each of ROW locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 55; a < 64; a++) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 55; r < 64; r++) {
- if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
- sudoku[r][sudoku[a][1]+3] = 0;
- }
- }
- }
- }
- // ROW 8 ************************
- // Step through each of ROW locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 64; a < 73; a++) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 64; r < 73; r++) {
- if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
- sudoku[r][sudoku[a][1]+3] = 0;
- }
- }
- }
- }
- // ROW 9 ************************
- // Step through each of ROW locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 73; a < 82; a++) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 73; r < 82; r++) {
- if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
- sudoku[r][sudoku[a][1]+3] = 0;
- }
- }
- }
- }
- /*
- for (byte e = 1; e < 82; e++) { // Cycle through all locations
- Serial.print(e); Serial.print(" ");
- Serial.print(sudoku[e][0]); Serial.print(" ");
- Serial.print(sudoku[e][4]);
- Serial.print(sudoku[e][5]);
- Serial.print(sudoku[e][6]);
- Serial.print(sudoku[e][7]);
- Serial.print(sudoku[e][8]);
- Serial.print(sudoku[e][9]);
- Serial.print(sudoku[e][10]);
- Serial.print(sudoku[e][11]);
- Serial.println(sudoku[e][12]);
- }
- */
- }
- void solvevertical(){ // Take Solved locations and apply horizontal rule
- // Cycle through all locations and using solved flag remove all associate vertical possibilities
- /*
- for (byte d = 1; d < 82; d++) { // Cycle through all locations
- Serial.print(d); Serial.print(" ");
- Serial.print(sudoku[d][0]); Serial.print(" ");
- Serial.print(sudoku[d][4]);
- Serial.print(sudoku[d][5]);
- Serial.print(sudoku[d][6]);
- Serial.print(sudoku[d][7]);
- Serial.print(sudoku[d][8]);
- Serial.print(sudoku[d][9]);
- Serial.print(sudoku[d][10]);
- Serial.print(sudoku[d][11]);
- Serial.println(sudoku[d][12]);
- }
- */
- // COL 1 ************************
- // Step through each of Col locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 1; a < 74; a=a+9) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 1; r < 74; r=r+9) {
- if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
- sudoku[r][sudoku[a][1]+3] = 0;
- }
- }
- }
- }
- // COL 2 ************************
- // Step through each of COL locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 2; a < 75; a=a+9) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 2; r < 75; r=r+9) {
- if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
- sudoku[r][sudoku[a][1]+3] = 0;
- }
- }
- }
- }
- // COL 3 ************************
- // Step through each of COL locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 3; a < 76; a=a+9) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 3; r < 76; r=r+9) {
- if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
- sudoku[r][sudoku[a][1]+3] = 0;
- }
- }
- }
- }
- // COL 4 ************************
- // Step through each of COL locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 4; a < 77; a=a+9) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 4; r < 77; r=r+9) {
- if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
- sudoku[r][sudoku[a][1]+3] = 0;
- }
- }
- }
- }
- // COL 5 ************************
- // Step through each of COL locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 5; a < 78; a=a+9) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 5; r < 78; r=r+9) {
- if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
- sudoku[r][sudoku[a][1]+3] = 0;
- }
- }
- }
- }
- // COL 6 ************************
- // Step through each of COL locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 6; a < 79; a=a+9) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 6; r < 79; r=r+9) {
- if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
- sudoku[r][sudoku[a][1]+3] = 0;
- }
- }
- }
- }
- // COL 7 ************************
- // Step through each of COL locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 7; a < 80; a=a+9) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 7; r < 80; r=r+9) {
- if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
- sudoku[r][sudoku[a][1]+3] = 0;
- }
- }
- }
- }
- // COL 8 ************************
- // Step through each of COL locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 8; a < 81; a=a+9) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 8; r < 81; r=r+9) {
- if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
- sudoku[r][sudoku[a][1]+3] = 0;
- }
- }
- }
- }
- // COL 9 ************************
- // Step through each of COL locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 9; a < 82; a=a+9) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 9; r < 83; r=r+9) {
- if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
- sudoku[r][sudoku[a][1]+3] = 0;
- }
- }
- }
- }
- /*
- for (byte e = 1; e < 82; e++) { // Cycle through all locations
- Serial.print(e); Serial.print(" ");
- Serial.print(sudoku[e][0]); Serial.print(" ");
- Serial.print(sudoku[e][4]);
- Serial.print(sudoku[e][5]);
- Serial.print(sudoku[e][6]);
- Serial.print(sudoku[e][7]);
- Serial.print(sudoku[e][8]);
- Serial.print(sudoku[e][9]);
- Serial.print(sudoku[e][10]);
- Serial.print(sudoku[e][11]);
- Serial.println(sudoku[e][12]);
- }
- */
- }
- void solvepanel(){ // Take Solved locations and apply horizontal rule
- // Cycle through all locations and using solved flag remove all associate panel possibilities
- /*
- for (byte d = 1; d < 82; d++) { // Cycle through all locations
- Serial.print(d); Serial.print(" ");
- Serial.print(sudoku[d][0]); Serial.print(" ");
- Serial.print(sudoku[d][4]);
- Serial.print(sudoku[d][5]);
- Serial.print(sudoku[d][6]);
- Serial.print(sudoku[d][7]);
- Serial.print(sudoku[d][8]);
- Serial.print(sudoku[d][9]);
- Serial.print(sudoku[d][10]);
- Serial.print(sudoku[d][11]);
- Serial.println(sudoku[d][12]);
- }
- */
- // PANEL Algorythm ************************
- // Step through each of locations and delete duplicates of the Solved location using the panel formulae. Ignore the current location you are solving for
- for (byte a = 1; a < 82; a++) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 1; r < 82; r++) { // Step through all locations
- if ((sudoku[a][13] == sudoku[r][13]) && (a!=r)) { // Identify the locations on the Same Panel
- if ((sudoku[a][13] == sudoku[r][13]) && (a!=r)) {
- sudoku[r][sudoku[a][1]+3] = 0;
- }
- }
- }
- }
- }
- /*
- for (byte e = 1; e < 82; e++) { // Cycle through all locations
- Serial.print(e); Serial.print(" ");
- Serial.print(sudoku[e][0]); Serial.print(" ");
- Serial.print(sudoku[e][4]);
- Serial.print(sudoku[e][5]);
- Serial.print(sudoku[e][6]);
- Serial.print(sudoku[e][7]);
- Serial.print(sudoku[e][8]);
- Serial.print(sudoku[e][9]);
- Serial.print(sudoku[e][10]);
- Serial.print(sudoku[e][11]);
- Serial.println(sudoku[e][12]);
- */
- }
- void loadpaneldata(){ // Load specifc Panel identification Data into the Array for each of the 81 locations
- // Load Numbers
- // Panel 1
- sudoku[1][13] = 1; sudoku[2][13] = 1; sudoku[3][13] = 1;
- sudoku[10][13] = 1; sudoku[11][13] = 1; sudoku[12][13] = 1;
- sudoku[19][13] = 1; sudoku[20][13] = 1; sudoku[21][13] = 1;
- // Panel 2
- sudoku[4][13] = 2; sudoku[5][13] = 2; sudoku[6][13] = 2;
- sudoku[13][13] = 2; sudoku[14][13] = 2; sudoku[15][13] = 2;
- sudoku[22][13] = 2; sudoku[23][13] = 2; sudoku[24][13] = 2;
- // Panel 3
- sudoku[7][13] = 3; sudoku[8][13] = 3; sudoku[9][13] = 3;
- sudoku[16][13] = 3; sudoku[17][13] = 3; sudoku[18][13] = 3;
- sudoku[25][13] = 3; sudoku[26][13] = 3; sudoku[27][13] = 3;
- // Panel 4
- sudoku[28][13] = 4; sudoku[29][13] = 4; sudoku[30][13] = 4;
- sudoku[37][13] = 4; sudoku[38][13] = 4; sudoku[39][13] = 4;
- sudoku[46][13] = 4; sudoku[47][13] = 4; sudoku[48][13] = 4;
- // Panel 5
- sudoku[31][13] = 5; sudoku[32][13] = 5; sudoku[33][13] = 5;
- sudoku[40][13] = 5; sudoku[41][13] = 5; sudoku[42][13] = 5;
- sudoku[49][13] = 5; sudoku[50][13] = 5; sudoku[51][13] = 5;
- // Panel 6
- sudoku[34][13] = 6; sudoku[35][13] = 6; sudoku[36][13] = 6;
- sudoku[43][13] = 6; sudoku[44][13] = 6; sudoku[45][13] = 6;
- sudoku[52][13] = 6; sudoku[53][13] = 6; sudoku[54][13] = 6;
- // Panel 7
- sudoku[55][13] = 7; sudoku[56][13] = 7; sudoku[57][13] = 7;
- sudoku[64][13] = 7; sudoku[65][13] = 7; sudoku[66][13] = 7;
- sudoku[73][13] = 7; sudoku[74][13] = 7; sudoku[75][13] = 7;
- // Panel 8
- sudoku[58][13] = 8; sudoku[59][13] = 8; sudoku[60][13] = 8;
- sudoku[67][13] = 8; sudoku[68][13] = 8; sudoku[69][13] = 8;
- sudoku[76][13] = 8; sudoku[77][13] = 8; sudoku[78][13] = 8;
- // Panel 9
- sudoku[61][13] = 9; sudoku[62][13] = 9; sudoku[63][13] = 9;
- sudoku[70][13] = 9; sudoku[71][13] = 9; sudoku[72][13] = 9;
- sudoku[79][13] = 9; sudoku[80][13] = 9; sudoku[81][13] = 9;
- }
- // Used to identify and highlight errors in a current matrix - use solve method however instead of solving outcome just highlight conflicts in red
- void helpbutton(){
- // Horizontal *********************
- // ROW 1 ************************
- // Step through each of ROW locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 1; a < 10; a++) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 1; r < 10; r++) {
- if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED
- // Refresh only the location concerned with new value and show colour coded
- //First Clear Location
- tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);
- tft.setTextSize(2);
- tft.setTextColor(RED);
- tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
- }
- }
- }
- }
- // ROW 2 ************************
- // Step through each of ROW locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 10; a < 19; a++) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 10; r < 19; r++) {
- if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED
- // Refresh only the location concerned with new value and show colour coded
- //First Clear Location
- tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);
- tft.setTextSize(2);
- tft.setTextColor(RED);
- tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
- }
- }
- }
- }
- // ROW 3 ************************
- // Step through each of ROW locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 19; a < 28; a++) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 19; r < 28; r++) {
- if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED
- // Refresh only the location concerned with new value and show colour coded
- //First Clear Location
- tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);
- tft.setTextSize(2);
- tft.setTextColor(RED);
- tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
- }
- }
- }
- }
- // ROW 4 ************************
- // Step through each of ROW locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 28; a < 37; a++) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 28; r < 37; r++) {
- if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED
- // Refresh only the location concerned with new value and show colour coded
- //First Clear Location
- tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);
- tft.setTextSize(2);
- tft.setTextColor(RED);
- tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
- }
- }
- }
- }
- // ROW 5 ************************
- // Step through each of ROW locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 37; a < 46; a++) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 37; r < 46; r++) {
- if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED
- // Refresh only the location concerned with new value and show colour coded
- //First Clear Location
- tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);
- tft.setTextSize(2);
- tft.setTextColor(RED);
- tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
- }
- }
- }
- }
- // ROW 6 ************************
- // Step through each of ROW locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 46; a < 55; a++) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 46; r < 55; r++) {
- if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED
- // Refresh only the location concerned with new value and show colour coded
- //First Clear Location
- tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);
- tft.setTextSize(2);
- tft.setTextColor(RED);
- tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
- }
- }
- }
- }
- // ROW 7 ************************
- // Step through each of ROW locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 55; a < 64; a++) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 55; r < 64; r++) {
- if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED
- // Refresh only the location concerned with new value and show colour coded
- //First Clear Location
- tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);
- tft.setTextSize(2);
- tft.setTextColor(RED);
- tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
- }
- }
- }
- }
- // ROW 8 ************************
- // Step through each of ROW locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 64; a < 73; a++) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 64; r < 73; r++) {
- if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED
- // Refresh only the location concerned with new value and show colour coded
- //First Clear Location
- tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);
- tft.setTextSize(2);
- tft.setTextColor(RED);
- tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
- }
- }
- }
- }
- // ROW 9 ************************
- // Step through each of ROW locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 73; a < 82; a++) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 73; r < 82; r++) {
- if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED
- // Refresh only the location concerned with new value and show colour coded
- //First Clear Location
- tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);
- tft.setTextSize(2);
- tft.setTextColor(RED);
- tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
- }
- }
- }
- }
- // Vertical ****************
- // COL 1 ************************
- // Step through each of Col locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 1; a < 74; a=a+9) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 1; r < 74; r=r+9) {
- if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED
- // Refresh only the location concerned with new value and show colour coded
- //First Clear Location
- tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);
- tft.setTextSize(2);
- tft.setTextColor(RED);
- tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
- }
- }
- }
- }
- // COL 2 ************************
- // Step through each of COL locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 2; a < 75; a=a+9) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 2; r < 75; r=r+9) {
- if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED
- // Refresh only the location concerned with new value and show colour coded
- //First Clear Location
- tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);
- tft.setTextSize(2);
- tft.setTextColor(RED);
- tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
- }
- }
- }
- }
- // COL 3 ************************
- // Step through each of COL locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 3; a < 76; a=a+9) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 3; r < 76; r=r+9) {
- if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED
- // Refresh only the location concerned with new value and show colour coded
- //First Clear Location
- tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);
- tft.setTextSize(2);
- tft.setTextColor(RED);
- tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
- }
- }
- }
- }
- // COL 4 ************************
- // Step through each of COL locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 4; a < 77; a=a+9) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 4; r < 77; r=r+9) {
- if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED
- // Refresh only the location concerned with new value and show colour coded
- //First Clear Location
- tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);
- tft.setTextSize(2);
- tft.setTextColor(RED);
- tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
- }
- }
- }
- }
- // COL 5 ************************
- // Step through each of COL locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 5; a < 78; a=a+9) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 5; r < 78; r=r+9) {
- if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED
- // Refresh only the location concerned with new value and show colour coded
- //First Clear Location
- tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);
- tft.setTextSize(2);
- tft.setTextColor(RED);
- tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
- }
- }
- }
- }
- // COL 6 ************************
- // Step through each of COL locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 6; a < 79; a=a+9) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 6; r < 79; r=r+9) {
- if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED
- // Refresh only the location concerned with new value and show colour coded
- //First Clear Location
- tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);
- tft.setTextSize(2);
- tft.setTextColor(RED);
- tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
- }
- }
- }
- }
- // COL 7 ************************
- // Step through each of COL locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 7; a < 80; a=a+9) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 7; r < 80; r=r+9) {
- if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED
- // Refresh only the location concerned with new value and show colour coded
- //First Clear Location
- tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);
- tft.setTextSize(2);
- tft.setTextColor(RED);
- tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
- }
- }
- }
- }
- // COL 8 ************************
- // Step through each of COL locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 8; a < 81; a=a+9) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 8; r < 81; r=r+9) {
- if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED
- // Refresh only the location concerned with new value and show colour coded
- //First Clear Location
- tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);
- tft.setTextSize(2);
- tft.setTextColor(RED);
- tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
- }
- }
- }
- }
- // COL 9 ************************
- // Step through each of COL locations and delete duplicates of the Solved location. Ignore the current location you are solving for
- for (byte a = 9; a < 82; a=a+9) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 9; r < 83; r=r+9) {
- if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED
- // Refresh only the location concerned with new value and show colour coded
- //First Clear Location
- tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);
- tft.setTextSize(2);
- tft.setTextColor(RED);
- tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
- }
- }
- }
- }
- // Panels *******************
- // PANEL Algorythm ************************
- // Step through each of locations and delete duplicates of the Solved location using the Oanel formulae. Ignore the current location you are solving for
- for (byte a = 1; a < 82; a++) { // Cycle through all locations
- if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
- for (byte r = 1; r < 82; r++) { // Step through all locations
- if ((sudoku[a][13] == sudoku[r][13]) && (a!=r)) { // Identify the locations on the Same Panel
- if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED
- // Refresh only the location concerned with new value and show colour coded
- //First Clear Location
- tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);
- tft.setTextSize(2);
- tft.setTextColor(RED);
- tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
- }
- }
- }
- }
- }
- // Horizontal conflict help function - Step through data and identify manually changed locations as conflicts in RED. Leave items set at WHITE as WHITE
- // Vertical conflict help function - Step through data and identify manually changed locations as conflicts in RED. Leave items set at WHITE as WHITE
- // Panel conflict help function - Step through data and identify manually changed locations as conflicts in RED. Leave items set at WHITE as WHITE
- }
- void uniquecandidate() { // Each panel, row and column on a Sudoku board must contain every number between 1 and 9.
- // Therefore, if a number, say 4, can only be put in a single cell within a block/column/row, then that number is guaranteed to fit there.
- /*
- for (byte d = 1; d < 82; d++) { // Cycle through all locations
- Serial.print(d); Serial.print(" ");
- Serial.print(sudoku[d][0]); Serial.print(" ");
- Serial.print(sudoku[d][1]); Serial.print(" ");
- Serial.print(sudoku[d][4]);
- Serial.print(sudoku[d][5]);
- Serial.print(sudoku[d][6]);
- Serial.print(sudoku[d][7]);
- Serial.print(sudoku[d][8]);
- Serial.print(sudoku[d][9]);
- Serial.print(sudoku[d][10]);
- Serial.print(sudoku[d][11]);
- Serial.println(sudoku[d][12]);
- }
- */
- byte tempcount = 0;
- for (byte p = 1; p < 10; p++) { // Cycle through all panels 1 to 9
- for (byte v = 1; v < 10; v++) { // Step through all possible unique location values in each panel
- for (byte r = 1; r < 82; r++) { // Step through all locations
- if (sudoku[r][13] == p) { //Only operate on those locations that are in this panel
- if (sudoku[r][v+3] == v) {// Count this if value is what we are looking for
- tempcount++;
- }
- }
- }
- // Check if unique
- if ( tempcount == 1) { // This is a unique value so reset the location with this being a solved location
- // Repeat process to locate unique location
- for (byte r = 1; r < 82; r++) { // Step through all locations and then mark as solved
- if (sudoku[r][13] == p) { //Only operate on those locations that are in this panel
- if (sudoku[r][v+3] == v) {// Count this if value is what we are looking for
- // Now poke the answer into the correct location
- if (sudoku[r][0] == 0) { // Change to solved but remain green
- sudoku[r][0] = 2;
- }
- sudoku[r][1] = v;
- }
- }
- }
- }
- // Reset temp counter
- tempcount = 0;
- }
- }
- /*
- for (byte d = 1; d < 82; d++) { // Cycle through all locations
- Serial.print(d); Serial.print(" ");
- Serial.print(sudoku[d][0]); Serial.print(" ");
- Serial.print(sudoku[d][1]); Serial.print(" ");
- Serial.print(sudoku[d][4]);
- Serial.print(sudoku[d][5]);
- Serial.print(sudoku[d][6]);
- Serial.print(sudoku[d][7]);
- Serial.print(sudoku[d][8]);
- Serial.print(sudoku[d][9]);
- Serial.print(sudoku[d][10]);
- Serial.print(sudoku[d][11]);
- Serial.println(sudoku[d][12]);
- }
- */
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement