Advertisement
Seelenkind

Arduino Sudoku Game

Apr 10th, 2020
556
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Arduino 91.14 KB | None | 0 0
  1.  // Sudoku Solver By TechKiwiGadgets May 2019
  2.  
  3. /*
  4. * V1 - Final Product Version for First Instructables Release based off dev version 101
  5. *       -  Solve now includes help test at end of solve to highlight any errors in red
  6. *       -  Includes 5th Hard puzzle as a challenge!
  7. *      
  8. *      
  9. *      
  10. *      
  11. *      
  12. *      
  13. *      
  14. *      
  15. *      
  16. * ARRAY POSITIONS & KEY VARIABLES BELOW *************************************************************
  17. // Array with following locations: {0 ,      1 ,    2   3    4, 5, 6, 7, 8, 9,10,11,12,    13 }
  18. // Array with following Structure: {Solved, value , X , Y , V1,V2,V3,V4,V5,V6,V7,V8,V9 panel# }
  19.  
  20. colcoord[9] = { 10, 34, 58, 90, 114, 138, 170, 194, 218 };
  21. rowcoord[9] = { 8, 33, 58, 88, 113, 138, 170, 194, 218 };
  22.  
  23. int location = 1;
  24.  
  25. const int sudoku[81][12];
  26.  
  27.  */
  28.  
  29. #include <Adafruit_GFX.h>    // Core graphics library
  30. #include <Adafruit_TFTLCD.h> // Hardware-specific library
  31. #include <TouchScreen.h>
  32.  
  33.  
  34. #define YP A3  // must be an analog pin, use "An" notation!
  35. #define XM A2  // must be an analog pin, use "An" notation!
  36. #define YM 9   // can be a digital pin
  37. #define XP 8  // can be a digital pin
  38.  
  39. // Revised Touch Callibration numbers
  40. #define TS_MINX 130
  41. #define TS_MINY 88
  42. #define TS_MAXX 915
  43. //#define TS_MAXY 927
  44. #define TS_MAXY 880
  45.  
  46. // For better pressure precision, we need to know the resistance
  47. // between X+ and X- Use any multimeter to read it
  48. // For the one we're using, its 300 ohms across the X plate
  49. TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
  50.  
  51. #define LCD_CS A3
  52. #define LCD_CD A2
  53. #define LCD_WR A1
  54. #define LCD_RD A0
  55. // optional
  56. #define LCD_RESET A4
  57.  
  58. // Assign human-readable names to some common 16-bit color values:
  59. // I had to reverse these colors for my screen
  60. int BLACK =  0x0000;
  61. int RED  =  0x001F;
  62. int BLUE = 0xF800;
  63. int GREEN  = 0x07E0;
  64. int YELLOW = 0x07FF;
  65. int MAGENTA = 0xF81F;
  66. int CYAN = 0xFFE0;
  67. int WHITE = 0xFFFF;
  68.  
  69.  
  70. Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
  71.  
  72. #define BOX 78  // Block to clear screen
  73. #define BOXSIZE 80
  74. #define BUTTON 20
  75.  
  76. boolean debounce = false; // Used to debounce touch screen input
  77.  
  78. // Array with following Structure: {value , X , Y , Solved }
  79.  
  80. const byte colcoord[9] = { 10, 34, 58, 90, 114, 138, 170, 194, 218 };
  81. const byte rowcoord[9] = { 8, 33, 58, 88, 113, 138, 170, 194, 218 };
  82.  
  83. byte location = 1;
  84.  
  85. byte puzzlenum = 1; // These identifier for 5 puzzles stored in memory
  86.  
  87. byte sudoku[82][14];
  88.  
  89. byte touchlocation = 0; // Used to track the array value that the stylis is closest to in the Sudoku 9x9 framework
  90.  
  91. int delay1 = 400;  // Pause input into screen
  92.  
  93. byte tempreading = 0;
  94.  
  95. void setup(void) {
  96. //  Serial.begin(9600);
  97. //  Serial.println(F("Paint!"));
  98.  
  99.   tft.reset();
  100.  
  101.   uint16_t identifier = tft.readID();
  102.   identifier=0x9325;
  103.  
  104.   tft.begin(identifier);
  105.   tft.setRotation(1);
  106.   tft.fillScreen(BLACK);
  107.  
  108. // **** Splash Screen
  109.  
  110.  
  111.         tft.drawRoundRect(0, 0, 320, 240, 20, BLUE);
  112.         tft.drawRoundRect(1, 1, 318, 238, 20, BLUE);
  113.  
  114.         byte g = 70;
  115.  
  116.         tft.drawCircle(46, g, 25, GREEN);        
  117.         tft.fillCircle(46, g, 20, GREEN);  
  118.         tft.setTextColor(BLACK);  tft.setTextSize(3);
  119.         tft.setCursor(39, g-10);   tft.println("S");
  120.  
  121.         tft.drawCircle(91, g+30, 25, BLUE);
  122.         tft.fillCircle(91, g+30, 20, BLUE);  
  123.         tft.setTextColor(BLACK);  tft.setTextSize(3);
  124.         tft.setCursor(84, g+20);   tft.println("U");
  125.  
  126.         tft.drawCircle(137, g, 25, YELLOW);  
  127.         tft.fillCircle(137, g, 20, YELLOW);  
  128.         tft.setTextColor(BLACK);  tft.setTextSize(3);
  129.         tft.setCursor(130, g-10);   tft.println("D");
  130.  
  131.         tft.drawCircle(183, g+30, 25, RED);  
  132.         tft.fillCircle(183, g+30, 20, RED);  
  133.         tft.setTextColor(BLACK);  tft.setTextSize(3);
  134.         tft.setCursor(176, g+20);   tft.println("O");
  135.  
  136.         tft.drawCircle(229, g, 25, GREEN);  
  137.         tft.fillCircle(229, g, 20, GREEN);  
  138.         tft.setTextColor(BLACK);  tft.setTextSize(3);
  139.         tft.setCursor(222, g-10);   tft.println("K");
  140.  
  141.         tft.drawCircle(274, g+30, 25, YELLOW);
  142.         tft.fillCircle(274, g+30, 20, YELLOW);  
  143.         tft.setTextColor(BLACK);  tft.setTextSize(3);
  144.         tft.setCursor(267, g+20);   tft.println("U");
  145.  
  146.         tft.setTextColor(WHITE);  tft.setTextSize(2);
  147.         tft.setCursor(25, 170);   tft.println("Play, Create, Solve");
  148.  
  149.         tft.setTextColor(GREEN);  tft.setTextSize(1);
  150.         tft.setCursor(25, 200);   tft.println("By TechKiwiGadgets 2019");
  151.  
  152.  
  153.  
  154.   delay(4000);
  155.  
  156.   tft.fillScreen(BLACK);
  157.  
  158.   drawscreen(); // Clearscreen and setup Sudoku matrix
  159.   resetmatrix(); // Initialize the sudoku matrix by setting all locations to zero and loading in the coordinates for each touch location
  160.   loadpaneldata(); // Load specifc Panel identification Data into the Array for each of the 81 locations
  161.   solvealigndata();  // Sanitize test puzzle data with correct data format
  162.      
  163. // Test Display by showing all values in the puzzle - White are Solved , Blue are others
  164.  
  165.   tft.setTextSize(2);
  166.  
  167.   for (byte a = 1; a < 82; a++) {      
  168.  
  169.     //Test solve or set condition
  170.     if  (sudoku[a][1] != 0) {  
  171.          if (sudoku[a][0] != 0) {
  172.                 tft.setTextColor(WHITE);
  173.             } else {
  174.                 tft.setTextColor(GREEN); // Set this colour if not a genuine set clue
  175.             }      
  176.           tft.setCursor( sudoku[a][3], sudoku[a][2]);  
  177.           tft.println(sudoku[a][1]);
  178.      }
  179.   }
  180.  
  181.  
  182. drawbuttons();
  183.  
  184.   pinMode(13, OUTPUT);
  185.  
  186.   //  testText();
  187.  
  188.  
  189.  
  190.  
  191. }
  192.  
  193. #define MINPRESSURE 5
  194. #define MAXPRESSURE 1000
  195.  
  196.  
  197.  
  198. //  tft.begin(identifier);
  199.  
  200. void loop()
  201. {
  202.  
  203. // Read the Touch Screen Locations
  204.   digitalWrite(13, HIGH);
  205.   TSPoint p = ts.getPoint();
  206.   digitalWrite(13, LOW);
  207.  
  208.   // if sharing pins, you'll need to fix the directions of the touchscreen pins
  209.   pinMode(XM, OUTPUT);
  210.   pinMode(YP, OUTPUT);
  211.  
  212.  
  213.   // we have some minimum pressure we consider 'valid'
  214.   // pressure of 0 means no pressing!
  215.  
  216.   if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
  217.  
  218. /*
  219.           Serial.print("X = "); Serial.print(p.x);
  220.           Serial.print("\tY = "); Serial.print(p.y);
  221.           Serial.print("\tPressure = "); Serial.println(p.z);
  222.  
  223.  */
  224.       // scale from 0->1023 to tft.width
  225.       p.x = map(p.x, TS_MINX, TS_MAXX, 0, 240);
  226.       p.y = map(p.y, TS_MINY, TS_MAXY, 0, 320); // Original Code
  227.  
  228.  /*
  229.           Serial.print("X = "); Serial.print(p.x);
  230.           Serial.print("\tY = "); Serial.print(p.y);
  231.           Serial.print("\tPressure = "); Serial.println(p.z);
  232.   */
  233.  
  234.       // Calculate the position of the screen touch based on the input values of p.x and p.y
  235.  
  236.       if ((p.x > 0) && (p.x < 27)) {           // Coloumn 1
  237.      
  238.               if ((p.y > 0) && (p.y < 27)) {           // Row 1
  239.                   touchlocation = 1;
  240.               }
  241.               if ((p.y > 28) && (p.y < 53)) {          // Row 2
  242.                    touchlocation = 2;              
  243.               }
  244.                if ((p.y > 54) && (p.y < 80)) {        // Row 3
  245.                    touchlocation = 3;              
  246.               }    
  247.                if ((p.y > 81) && (p.y < 107)) {        // Row 4
  248.                   touchlocation = 4;                
  249.               }  
  250.                if ((p.y > 108) && (p.y < 133)) {        // Row 5
  251.                   touchlocation = 5;                
  252.               }  
  253.                if ((p.y > 134) && (p.y < 160)) {        // Row 6
  254.                    touchlocation = 6;                  
  255.               }
  256.                if ((p.y > 161) && (p.y < 187)) {        // Row 7
  257.                    touchlocation = 7;                  
  258.               }
  259.                if ((p.y > 188) && (p.y < 213)) {        // Row 8
  260.                   touchlocation = 8;                  
  261.               }  
  262.                if ((p.y > 214) && (p.y < 240)) {        // Row 9
  263.                   touchlocation = 9;                  
  264.               }  
  265.       } else
  266.       if ((p.x > 28) && (p.x < 53)) {          // Coloumn 2
  267.  
  268.               if ((p.y > 0) && (p.y < 27)) {           // Row 1
  269.                   touchlocation = 10;
  270.               }
  271.               if ((p.y > 28) && (p.y < 53)) {          // Row 2
  272.                    touchlocation = 11;              
  273.               }
  274.                if ((p.y > 54) && (p.y < 80)) {        // Row 3
  275.                    touchlocation = 12;              
  276.               }    
  277.                if ((p.y > 81) && (p.y < 107)) {        // Row 4
  278.                   touchlocation = 13;                
  279.               }  
  280.                if ((p.y > 108) && (p.y < 133)) {        // Row 5
  281.                   touchlocation = 14;                
  282.               }  
  283.                if ((p.y > 134) && (p.y < 160)) {        // Row 6
  284.                    touchlocation = 15;                  
  285.               }
  286.                if ((p.y > 161) && (p.y < 187)) {        // Row 7
  287.                    touchlocation = 16;                  
  288.               }
  289.                if ((p.y > 188) && (p.y < 213)) {        // Row 8
  290.                   touchlocation = 17;                  
  291.               }  
  292.                if ((p.y > 214) && (p.y < 240)) {        // Row 9
  293.                   touchlocation = 18;                  
  294.               }  
  295.  
  296.  
  297.        
  298.       } else
  299.        if ((p.x > 54) && (p.x < 80)) {        // Coloumn 3
  300.        
  301.               if ((p.y > 0) && (p.y < 27)) {           // Row 1
  302.                   touchlocation = 19;
  303.               }
  304.               if ((p.y > 28) && (p.y < 53)) {          // Row 2
  305.                    touchlocation = 20;              
  306.               }
  307.                if ((p.y > 54) && (p.y < 80)) {        // Row 3
  308.                    touchlocation = 21;              
  309.               }    
  310.                if ((p.y > 81) && (p.y < 107)) {        // Row 4
  311.                   touchlocation = 22;                
  312.               }  
  313.                if ((p.y > 108) && (p.y < 133)) {        // Row 5
  314.                   touchlocation = 23;                
  315.               }  
  316.                if ((p.y > 134) && (p.y < 160)) {        // Row 6
  317.                    touchlocation = 24;                  
  318.               }
  319.                if ((p.y > 161) && (p.y < 187)) {        // Row 7
  320.                    touchlocation = 25;                  
  321.               }
  322.                if ((p.y > 188) && (p.y < 213)) {        // Row 8
  323.                   touchlocation = 26;                  
  324.               }  
  325.                if ((p.y > 214) && (p.y < 240)) {        // Row 9
  326.                   touchlocation = 27;                  
  327.               }  
  328.  
  329.      
  330.       } else    
  331.        if ((p.x > 81) && (p.x < 107)) {        // Coloumn 4
  332.  
  333.               if ((p.y > 0) && (p.y < 27)) {           // Row 1
  334.                   touchlocation = 28;
  335.               }
  336.               if ((p.y > 28) && (p.y < 53)) {          // Row 2
  337.                    touchlocation = 29;              
  338.               }
  339.                if ((p.y > 54) && (p.y < 80)) {        // Row 3
  340.                    touchlocation = 30;              
  341.               }    
  342.                if ((p.y > 81) && (p.y < 107)) {        // Row 4
  343.                   touchlocation = 31;                
  344.               }  
  345.                if ((p.y > 108) && (p.y < 133)) {        // Row 5
  346.                   touchlocation = 32;                
  347.               }  
  348.                if ((p.y > 134) && (p.y < 160)) {        // Row 6
  349.                    touchlocation = 33;                  
  350.               }
  351.                if ((p.y > 161) && (p.y < 187)) {        // Row 7
  352.                    touchlocation = 34;                  
  353.               }
  354.                if ((p.y > 188) && (p.y < 213)) {        // Row 8
  355.                   touchlocation = 35;                  
  356.               }  
  357.                if ((p.y > 214) && (p.y < 240)) {        // Row 9
  358.                   touchlocation = 36;                  
  359.               }  
  360.        
  361.       }  else
  362.        if ((p.x > 108) && (p.x < 133)) {        // Coloumn 5
  363.  
  364.               if ((p.y > 0) && (p.y < 27)) {           // Row 1
  365.                   touchlocation = 37;
  366.               }
  367.               if ((p.y > 28) && (p.y < 53)) {          // Row 2
  368.                    touchlocation = 38;              
  369.               }
  370.                if ((p.y > 54) && (p.y < 80)) {        // Row 3
  371.                    touchlocation = 39;              
  372.               }    
  373.                if ((p.y > 81) && (p.y < 107)) {        // Row 4
  374.                   touchlocation = 40;                
  375.               }  
  376.                if ((p.y > 108) && (p.y < 133)) {        // Row 5
  377.                   touchlocation = 41;                
  378.               }  
  379.                if ((p.y > 134) && (p.y < 160)) {        // Row 6
  380.                    touchlocation = 42;                  
  381.               }
  382.                if ((p.y > 161) && (p.y < 187)) {        // Row 7
  383.                    touchlocation = 43;                  
  384.               }
  385.                if ((p.y > 188) && (p.y < 213)) {        // Row 8
  386.                   touchlocation = 44;                  
  387.               }  
  388.                if ((p.y > 214) && (p.y < 240)) {        // Row 9
  389.                   touchlocation = 45;                  
  390.               }  
  391.      
  392.       }  else
  393.        if ((p.x > 134) && (p.x < 160)) {        // Coloumn 6
  394.  
  395.               if ((p.y > 0) && (p.y < 27)) {           // Row 1
  396.                   touchlocation = 46;
  397.               }
  398.               if ((p.y > 28) && (p.y < 53)) {          // Row 2
  399.                    touchlocation = 47;              
  400.               }
  401.                if ((p.y > 54) && (p.y < 80)) {        // Row 3
  402.                    touchlocation = 48;              
  403.               }    
  404.                if ((p.y > 81) && (p.y < 107)) {        // Row 4
  405.                   touchlocation = 49;                
  406.               }  
  407.                if ((p.y > 108) && (p.y < 133)) {        // Row 5
  408.                   touchlocation = 50;                
  409.               }  
  410.                if ((p.y > 134) && (p.y < 160)) {        // Row 6
  411.                    touchlocation = 51;                  
  412.               }
  413.                if ((p.y > 161) && (p.y < 187)) {        // Row 7
  414.                    touchlocation = 52;                  
  415.               }
  416.                if ((p.y > 188) && (p.y < 213)) {        // Row 8
  417.                   touchlocation = 53;                  
  418.               }  
  419.                if ((p.y > 214) && (p.y < 240)) {        // Row 9
  420.                   touchlocation = 54;                  
  421.               }  
  422.  
  423.  
  424.        
  425.       } else
  426.        if ((p.x > 161) && (p.x < 187)) {        // Coloumn 7
  427.  
  428.               if ((p.y > 0) && (p.y < 27)) {           // Row 1
  429.                   touchlocation = 55;
  430.               }
  431.               if ((p.y > 28) && (p.y < 53)) {          // Row 2
  432.                    touchlocation = 56;              
  433.               }
  434.                if ((p.y > 54) && (p.y < 80)) {        // Row 3
  435.                    touchlocation = 57;              
  436.               }    
  437.                if ((p.y > 81) && (p.y < 107)) {        // Row 4
  438.                   touchlocation = 58;                
  439.               }  
  440.                if ((p.y > 108) && (p.y < 133)) {        // Row 5
  441.                   touchlocation = 59;                
  442.               }  
  443.                if ((p.y > 134) && (p.y < 160)) {        // Row 6
  444.                    touchlocation = 60;                  
  445.               }
  446.                if ((p.y > 161) && (p.y < 187)) {        // Row 7
  447.                    touchlocation = 61;                  
  448.               }
  449.                if ((p.y > 188) && (p.y < 213)) {        // Row 8
  450.                   touchlocation = 62;                  
  451.               }  
  452.                if ((p.y > 214) && (p.y < 240)) {        // Row 9
  453.                   touchlocation = 63;                  
  454.               }  
  455.  
  456.        
  457.       } else
  458.        if ((p.x > 188) && (p.x < 213)) {        // Coloumn 8
  459.  
  460.               if ((p.y > 0) && (p.y < 27)) {           // Row 1
  461.                   touchlocation = 64;
  462.               }
  463.               if ((p.y > 28) && (p.y < 53)) {          // Row 2
  464.                    touchlocation = 65;              
  465.               }
  466.                if ((p.y > 54) && (p.y < 80)) {        // Row 3
  467.                    touchlocation = 66;              
  468.               }    
  469.                if ((p.y > 81) && (p.y < 107)) {        // Row 4
  470.                   touchlocation = 67;                
  471.               }  
  472.                if ((p.y > 108) && (p.y < 133)) {        // Row 5
  473.                   touchlocation = 68;                
  474.               }  
  475.                if ((p.y > 134) && (p.y < 160)) {        // Row 6
  476.                    touchlocation = 69;                  
  477.               }
  478.                if ((p.y > 161) && (p.y < 187)) {        // Row 7
  479.                    touchlocation = 70;                  
  480.               }
  481.                if ((p.y > 188) && (p.y < 213)) {        // Row 8
  482.                   touchlocation = 71;                  
  483.               }  
  484.                if ((p.y > 214) && (p.y < 240)) {        // Row 9
  485.                   touchlocation = 72;                  
  486.               }          
  487.       }  else
  488.        if ((p.x > 214) && (p.x < 240)) {        // Coloumn 9
  489.  
  490.               if ((p.y > 0) && (p.y < 27)) {           // Row 1
  491.                   touchlocation = 73;
  492.               }
  493.               if ((p.y > 28) && (p.y < 53)) {          // Row 2
  494.                    touchlocation = 74;              
  495.               }
  496.                if ((p.y > 54) && (p.y < 80)) {        // Row 3
  497.                    touchlocation = 75;              
  498.               }    
  499.                if ((p.y > 81) && (p.y < 107)) {        // Row 4
  500.                   touchlocation = 76;                
  501.               }  
  502.                if ((p.y > 108) && (p.y < 133)) {        // Row 5
  503.                   touchlocation = 77;                
  504.               }  
  505.                if ((p.y > 134) && (p.y < 160)) {        // Row 6
  506.                    touchlocation = 78;                  
  507.               }
  508.                if ((p.y > 161) && (p.y < 187)) {        // Row 7
  509.                    touchlocation = 79;                  
  510.               }
  511.                if ((p.y > 188) && (p.y < 213)) {        // Row 8
  512.                   touchlocation = 80;                  
  513.               }  
  514.                if ((p.y > 214) && (p.y < 240)) {        // Row 9
  515.                   touchlocation = 81;                  
  516.               }      
  517.  
  518.       }
  519.  
  520.       // debounce function to remove issue with first touch screen reading being spurious
  521.       if (debounce == false) {
  522.         touchlocation = 0;
  523.         debounce = true;
  524.         }
  525.  
  526. // This code only applies to stylis activity within the Sudokumatrix
  527. if ( ((p.x < 235)&&(p.y < 230))&& (touchlocation != 0)) {
  528.  
  529.  
  530.    
  531.  //   tft.fillRect(250, 80, 15, 10, BLACK);
  532.  
  533. /*
  534.       Serial.print("Y = "); Serial.print(p.x);
  535.       Serial.print("\tX = "); Serial.print(p.y);
  536.       Serial.print("\tLocation = "); Serial.println(touchlocation);  
  537. */
  538.  
  539. // Calculate the incremental changes to the data array
  540. // Array Structure: {value , X , Y , Solved }
  541.  
  542. // Only increment if has not been solved, Debounce by checking if this is the second time the same range is selected
  543.     if ((tempreading == touchlocation)&&(sudoku[touchlocation][0]==0)||(tempreading == touchlocation)&&(sudoku[touchlocation][0]==2)) {
  544.         sudoku[touchlocation][1]++;
  545.         if (sudoku[touchlocation][1] > 9) {
  546.           sudoku[touchlocation][1] = 0;
  547.         }
  548.         // Test to see if changing an item can be classified as solved
  549.         if (sudoku[touchlocation][1]!=0) {  
  550.             sudoku[touchlocation][0]=2;      // Set to Solved if a manually changed number however flag as manual change with va,ue of 2
  551.         } else {
  552.             sudoku[touchlocation][0]=0;      // Set to Not Solved if 0  
  553.         }
  554.     // Finally reset all of the data values in this location that have been manually changed to unsolved
  555.         for (byte u = 1; u < 82; u++) {    
  556.          // If preprogrammed from a game then leave values otherwise reset data to baseline
  557.          if (sudoku[u][0]!=1){
  558.               for (byte q = 4; q < 13; q++) {  
  559.                   sudoku[u][q]=q-3;
  560.               }
  561.          }
  562.         }
  563.     }
  564.  
  565. //     tft.setTextColor(WHITE);  tft.setTextSize(1);
  566. //      tft.setCursor(250, 80);   tft.println(touchlocation);  
  567.  
  568.  
  569.  
  570.    // Refresh only the location concerned with new value and show colour coded
  571.         //First Clear Location
  572.         tft.fillRect(sudoku[touchlocation][3], sudoku[touchlocation][2], 15, 15, BLACK);      
  573.         tft.setTextSize(2);
  574.  
  575.          if (sudoku[touchlocation][0] != 0) { // Do not draw 0 just leave blank square
  576.              if (sudoku[touchlocation][0] == 1) {
  577.                     tft.setTextColor(WHITE);
  578.                 } else if (sudoku[touchlocation][0] == 2) {
  579.                     tft.setTextColor(GREEN); // Set this colour if not a genuine set clue
  580.                 }      
  581.               tft.setCursor( sudoku[touchlocation][3], sudoku[touchlocation][2]);  
  582.               tft.println(sudoku[touchlocation][1]);
  583.          }
  584.          
  585.     if (tempreading == touchlocation) {
  586.         delay(delay1);
  587.         }
  588.    
  589.    
  590.     tempreading = touchlocation; // take a first sample then repeat and compare to debounce  
  591.  
  592.  
  593.     }
  594.  
  595.     // Inside touch sensor reading if statement
  596.  
  597.     // HOME Button Pressed ************************************************  
  598.         if ( ((p.y > 255)&&(p.y < 300))&& ((p.x > 10)&&(p.x < 40))) {
  599.  
  600.  
  601.         tft.fillCircle(280, 30, 20, WHITE);  
  602.         tft.setTextColor(BLACK);  tft.setTextSize(1);
  603.         tft.setCursor(268, 27);   tft.println("HOME");  
  604.  
  605.         delay(delay1/2);
  606.    
  607.         drawscreen(); // Clearscreen and setup Sudoku matrix
  608.         resetmatrix(); // Initialize the sudoku matrix by setting all locations to zero:
  609.         refreshdisplay();
  610.         drawbuttons();      
  611.       }
  612.  
  613.       // PLAY Button Pressed ************************************************  
  614.         if ( ((p.y > 255)&&(p.y < 300))&& ((p.x > 80)&&(p.x < 110))) {
  615.  
  616.  
  617.         //PLAY Button pressed
  618.         //Button 2
  619.         tft.fillCircle(280, 90, 20, WHITE);  
  620.         tft.setTextColor(BLACK);  tft.setTextSize(1);
  621.         tft.setCursor(268, 87);   tft.println("PLAY");  
  622.    
  623.  
  624.        
  625.         delay(delay1/2);      
  626.        
  627.         drawscreen(); // Clearscreen and setup Sudoku matrix
  628.         resetmatrix(); // Initialize the sudoku matrix by setting all locations to zero:
  629.  
  630.         loadtestpuzzle1(); // Loads test puzzle into the location array
  631.  
  632.  
  633.  
  634.         solvealigndata();  // Sanitize test puzzle data with correct data format
  635.  
  636.  
  637.         refreshdisplay(); // Only display testpuzzle data locations that are
  638.         drawbuttons(); // Redraw buttons togive push button effect
  639.          tft.setCursor(277, 97);   tft.println(puzzlenum);  
  640.  
  641.         // Manage Puzzle Number
  642.         puzzlenum++; // increment puzzle number
  643.         if (puzzlenum > 5) {
  644.           puzzlenum = 1;
  645.           }
  646.      
  647.       }
  648.      
  649.      // HELP Button Pressed ************************************************  
  650.         if ( ((p.y > 255)&&(p.y < 300))&& ((p.x > 140)&&(p.x < 160))) {
  651.  
  652.         //Button 3
  653.         tft.fillCircle(280, 150, 20, WHITE);  
  654.         tft.setTextColor(BLACK);  tft.setTextSize(1);
  655.         tft.setCursor(268, 147);   tft.println("HELP");  
  656.  
  657.  
  658.        
  659.         delay(delay1/2);
  660.  
  661.  //       drawscreen(); // Clearscreen and setup Sudoku matrix
  662.  //       solvehorizontal(); // Solve horiontal rule
  663.  //       solvevertical(); // Solve vertical rule
  664.  //       solvepanel(); // Solve Panel rule
  665.          
  666.           helpbutton(); // Run algorythm and test for incorrect locations then highlight in red
  667.        
  668.  //       reversesolve();
  669.         delay(800);// Display the changes before reverting to original colors
  670.  
  671.                
  672.         refreshdisplay(); // Only display testpuzzle data locations that are
  673.         drawbuttons(); // Redraw buttons togive push button effect
  674.         }
  675.  
  676.      // SOLVE Button Pressed ************************************************  
  677.         if ( ((p.y > 255)&&(p.y < 300))&& ((p.x > 200)&&(p.x < 220))) {
  678.  
  679.    
  680.         //SOLVE Button Pressed
  681.  
  682.          //Button 4
  683.         tft.fillCircle(280, 210, 20, WHITE);  
  684.         tft.setTextColor(BLACK);  tft.setTextSize(1);
  685.         tft.setCursor(266, 207);   tft.println("SOLVE");  
  686.  
  687.  
  688.        
  689.         delay(delay1/2);
  690.  
  691.  
  692.         solvepanel(); // Solve Panel rule
  693.         solvehorizontal(); // Solve horiontal rule
  694.         solvevertical(); // Solve vertical rule
  695.  
  696.         reversesolvecolor();  
  697.  
  698.  
  699.         uniquecandidate(); // Test
  700.         solvealigndata();
  701.         reversesolvecolor();
  702.  
  703.  
  704.         solvehorizontal(); // Solve horiontal rule
  705.         solvevertical(); // Solve vertical rule
  706.         solvepanel(); // Solve Panel rule
  707.         reversesolvecolor();
  708.  
  709.         solvehorizontal(); // Solve horiontal rule
  710.         solvevertical(); // Solve vertical rule
  711.         solvepanel(); // Solve Panel rule
  712.         reversesolvecolor();
  713.  
  714.  
  715.         solvehorizontal(); // Solve horiontal rule
  716.         solvevertical(); // Solve vertical rule
  717.         solvepanel(); // Solve Panel rule
  718.         reversesolvecolor();
  719.  
  720.  
  721.         solvehorizontal(); // Solve horiontal rule
  722.         solvevertical(); // Solve vertical rule
  723.         solvepanel(); // Solve Panel rule
  724.         reversesolvecolor();
  725.  
  726.  
  727.         solvehorizontal(); // Solve horiontal rule
  728.         solvevertical(); // Solve vertical rule
  729.         solvepanel(); // Solve Panel rule
  730.         reversesolvecolor();
  731.  
  732.  
  733.         solvehorizontal(); // Solve horiontal rule
  734.         solvevertical(); // Solve vertical rule
  735.         solvepanel(); // Solve Panel rule
  736.         reversesolvecolor();
  737.  
  738.  
  739.         solvehorizontal(); // Solve horiontal rule
  740.         solvevertical(); // Solve vertical rule
  741.         solvepanel(); // Solve Panel rule
  742.         reversesolvecolor();
  743.  
  744.  
  745.         solvehorizontal(); // Solve horiontal rule
  746.         solvevertical(); // Solve vertical rule
  747.         solvepanel(); // Solve Panel rule
  748.         reversesolvecolor();
  749.  
  750.  
  751.         solvehorizontal(); // Solve horiontal rule
  752.         solvevertical(); // Solve vertical rule
  753.         solvepanel(); // Solve Panel rule
  754.         reversesolvecolor();
  755.  
  756.  
  757.         solvehorizontal(); // Solve horiontal rule
  758.         solvevertical(); // Solve vertical rule
  759.         solvepanel(); // Solve Panel rule
  760.         reversesolvecolor();
  761.  
  762.         solvepanel(); // Solve Panel rule
  763.         solvehorizontal(); // Solve horiontal rule
  764.         solvevertical(); // Solve vertical rule
  765.  
  766.         reversesolvecolor();
  767.  
  768.         uniquecandidate(); // Test
  769.         solvealigndata();
  770.         reversesolvecolor();
  771.  
  772.         solvepanel(); // Solve Panel rule
  773.         solvehorizontal(); // Solve horiontal rule
  774.         solvevertical(); // Solve vertical rule
  775.  
  776.         reversesolvecolor();
  777.  
  778.         uniquecandidate(); // Test
  779.         solvealigndata();
  780.         reversesolvecolor();
  781.  
  782.         solvepanel(); // Solve Panel rule
  783.         solvehorizontal(); // Solve horiontal rule
  784.         solvevertical(); // Solve vertical rule
  785.  
  786.         reversesolvecolor();
  787.  
  788.         uniquecandidate(); // Test
  789.         solvealigndata();
  790.         reversesolvecolor();
  791.  
  792.  
  793.        
  794.         drawscreen(); // Clearscreen and setup Sudoku matrix
  795.                
  796.         refreshdisplay(); // Only display testpuzzle data locations that are
  797.         helpbutton(); // Run algorythm and test for incorrect locations then highlight in red
  798.         drawbuttons(); // Redraw buttons togive push button effect
  799.         }
  800.  
  801.  
  802.  
  803. /*
  804.       Serial.print("Y = "); Serial.print(p.x);
  805.       Serial.print("\tX = "); Serial.println(p.y);
  806. */    
  807.           p.z = 0;// Force the sensor value below threshold to avoid ghost values  
  808.   }
  809.  
  810. }
  811.  
  812.  
  813.  
  814.  
  815.  
  816.  
  817.  
  818.  
  819.  
  820.  
  821.  
  822. void loadtestpuzzle1(){
  823.  
  824. // Test Puzzle example 1 loaded into array
  825.  
  826.  if (puzzlenum == 1 ){
  827.      
  828.       // Load Numbers
  829.       sudoku[1][1] = 2; sudoku[3][1] = 9; sudoku[19][1] = 3; sudoku[21][1] = 5;
  830.      
  831.       sudoku[5][1] = 6; sudoku[6][1] = 3; sudoku[14][1] = 2; sudoku[23][1] = 9;
  832.  
  833.       sudoku[7][1] = 4; sudoku[9][1] = 8; sudoku[26][1] = 7;
  834.  
  835.       sudoku[39][1] = 1; sudoku[46][1] = 9; sudoku[47][1] = 7; sudoku[48][1] = 2;
  836.  
  837.       sudoku[31][1] = 9; sudoku[32][1] = 8; sudoku[50][1] = 1; sudoku[51][1] = 6;
  838.  
  839.       sudoku[34][1] = 7; sudoku[35][1] = 1; sudoku[36][1] = 6; sudoku[43][1] = 2;
  840.  
  841.       sudoku[56][1] = 3; sudoku[73][1] = 5; sudoku[75][1] = 6;
  842.  
  843.       sudoku[59][1] = 7; sudoku[68][1] = 3; sudoku[76][1] = 1; sudoku[77][1] = 4;
  844.      
  845.       sudoku[61][1] = 6; sudoku[63][1] = 1; sudoku[79][1] = 8; sudoku[81][1] = 7;
  846.  
  847.       // Set the Solved Flag for each
  848.       sudoku[1][0] = 1; sudoku[3][0] = 1; sudoku[19][0] = 1; sudoku[21][0] = 1;
  849.      
  850.       sudoku[5][0] = 1; sudoku[6][0] = 1; sudoku[14][0] = 1; sudoku[23][0] = 1;
  851.  
  852.       sudoku[7][0] = 1; sudoku[9][0] = 1; sudoku[26][0] = 1;
  853.  
  854.       sudoku[39][0] = 1; sudoku[46][0] = 1; sudoku[47][0] = 1; sudoku[48][0] = 1;
  855.  
  856.       sudoku[31][0] = 1; sudoku[32][0] = 1; sudoku[50][0] = 1; sudoku[51][0] = 1;
  857.  
  858.       sudoku[34][0] = 1; sudoku[35][0] = 1; sudoku[36][0] = 1; sudoku[43][0] = 1;
  859.  
  860.       sudoku[56][0] = 1; sudoku[73][0] = 1; sudoku[75][0] = 1;
  861.  
  862.       sudoku[59][0] = 1; sudoku[68][0] = 1; sudoku[76][0] = 1; sudoku[77][0] = 1;
  863.      
  864.       sudoku[61][0] = 1; sudoku[63][0] = 1; sudoku[79][0] = 1; sudoku[81][0] = 1;
  865.  
  866.  } else
  867.  
  868.  if (puzzlenum == 2 ){
  869.      
  870.       // Load Numbers
  871.       sudoku[1][1] = 4; sudoku[10][1] = 2; sudoku[19][1] = 1;
  872.      
  873.       sudoku[5][1] = 2; sudoku[15][1] = 4; sudoku[24][1] = 5;
  874.  
  875.       sudoku[25][1] = 2; sudoku[17][1] = 8; sudoku[18][1] = 6;
  876.      
  877.  
  878.       sudoku[29][1] = 3; sudoku[30][1] = 2; sudoku[37][1] = 9; sudoku[39][1] = 5; sudoku[46][1] = 7; sudoku[47][1] = 6;
  879.  
  880.       sudoku[31][1] = 6; sudoku[40][1] = 4; sudoku[41][1] = 8; sudoku[42][1] = 3; sudoku[51][1] = 2;
  881.  
  882.       sudoku[35][1] = 4; sudoku[36][1] = 1; sudoku[43][1] = 6; sudoku[45][1] = 2; sudoku[52][1] = 3; sudoku[53][1] = 5;
  883.      
  884.  
  885.       sudoku[57][1] = 1; sudoku[64][1] = 3;  sudoku[65][1] = 8;
  886.  
  887.       sudoku[58][1] = 7; sudoku[67][1] = 5; sudoku[77][1] = 9;
  888.      
  889.       sudoku[63][1] = 9; sudoku[72][1] = 7; sudoku[81][1] = 5;
  890.      
  891.  
  892.       // Set the Solved Flag for each
  893.       sudoku[1][0] = 1; sudoku[10][0] = 1; sudoku[19][0] = 1;
  894.      
  895.       sudoku[5][0] = 1; sudoku[15][0] = 1; sudoku[24][0] = 1;
  896.  
  897.       sudoku[25][0] = 1; sudoku[17][0] = 1; sudoku[18][0] = 1;
  898.      
  899.  
  900.       sudoku[29][0] = 1; sudoku[30][0] = 1; sudoku[37][0] = 1; sudoku[39][0] = 1; sudoku[46][0] = 1; sudoku[47][0] = 1;
  901.  
  902.       sudoku[31][0] = 1; sudoku[40][0] = 1; sudoku[41][0] = 1; sudoku[42][0] = 1; sudoku[51][0] = 1;
  903.  
  904.       sudoku[35][0] = 1; sudoku[36][0] = 1; sudoku[43][0] = 1; sudoku[45][0] = 1; sudoku[52][0] = 1; sudoku[53][0] = 1;
  905.      
  906.  
  907.       sudoku[57][0] = 1; sudoku[64][0] = 1;  sudoku[65][0] = 1;
  908.  
  909.       sudoku[58][0] = 1; sudoku[67][0] = 1; sudoku[77][0] = 1;
  910.      
  911.       sudoku[63][0] = 1; sudoku[72][0] = 1; sudoku[81][0] = 1;
  912.  
  913.  } else
  914.  
  915.  if (puzzlenum == 3 ){
  916.      
  917.       // Load Numbers
  918.       sudoku[12][1] = 8; sudoku[19][1] = 4;
  919.      
  920.       sudoku[5][1] = 2; sudoku[13][1] = 9; sudoku[14][1] = 4; sudoku[22][1] = 7; sudoku[24][1] = 8;
  921.  
  922.       sudoku[7][1] = 8; sudoku[9][1] = 7; sudoku[25][1] = 2; sudoku[27][1] = 9;
  923.      
  924.  
  925.       sudoku[28][1] = 1; sudoku[29][1] = 2; sudoku[38][1] = 4; sudoku[39][1] = 3; sudoku[30][1] = 7;
  926.  
  927.       sudoku[31][1] = 5; sudoku[41][1] = 8; sudoku[51][1] = 7;
  928.  
  929.       sudoku[43][1] = 5; sudoku[44][1] = 7; sudoku[52][1] = 9; sudoku[53][1] = 2; sudoku[54][1] = 4;
  930.      
  931.  
  932.       sudoku[55][1] = 8; sudoku[57][1] = 9; sudoku[73][1] = 6; sudoku[75][1] = 4;
  933.  
  934.       sudoku[58][1] = 1; sudoku[60][1] = 2; sudoku[68][1] = 6; sudoku[69][1] = 9; sudoku[77][1] = 3;
  935.      
  936.       sudoku[70][1] = 1; sudoku[63][1] = 3;
  937.      
  938.  
  939.       // Set the Solved Flag for each
  940.       sudoku[12][0] = 1; sudoku[19][0] = 1;
  941.      
  942.       sudoku[5][0] = 1; sudoku[13][0] = 1; sudoku[14][0] = 1; sudoku[22][0] = 1; sudoku[24][0] = 1;
  943.  
  944.       sudoku[7][0] = 1; sudoku[9][0] = 1; sudoku[25][0] = 1; sudoku[27][0] = 1;
  945.      
  946.  
  947.       sudoku[28][0] = 1; sudoku[29][0] = 1; sudoku[38][0] = 1; sudoku[39][0] = 1;  sudoku[30][0] = 1;
  948.  
  949.       sudoku[31][0] = 1; sudoku[41][0] = 1; sudoku[51][0] = 1;
  950.  
  951.       sudoku[43][0] = 1; sudoku[44][0] = 1; sudoku[52][0] = 1; sudoku[53][0] = 1; sudoku[54][0] = 1;
  952.      
  953.  
  954.       sudoku[55][0] = 1; sudoku[57][0] = 1; sudoku[73][0] = 1; sudoku[75][0] = 1;
  955.  
  956.       sudoku[58][0] = 1; sudoku[60][0] = 1; sudoku[68][0] = 1; sudoku[69][0] = 1; sudoku[77][0] = 1;
  957.      
  958.       sudoku[70][0] = 1; sudoku[63][0] = 1;
  959.  
  960.  } else
  961.  
  962.  if (puzzlenum == 4 ){
  963.      
  964.       // Load Numbers
  965.       sudoku[3][1] = 6; sudoku[12][1] = 2;
  966.      
  967.       sudoku[5][1] = 7; sudoku[6][1] = 9; sudoku[13][1] = 1;
  968.  
  969.       sudoku[16][1] = 6; sudoku[17][1] = 5; sudoku[18][1] = 4; sudoku[25][1] = 7; sudoku[26][1] = 1;
  970.      
  971.  
  972.       sudoku[29][1] = 6; sudoku[30][1] = 5; sudoku[37][1] = 8; sudoku[46][1] = 1; sudoku[48][1] = 3;
  973.  
  974.       sudoku[33][1] = 4; sudoku[40][1] = 7; sudoku[41][1] = 2;  sudoku[42][1] = 5; sudoku[49][1] = 8;
  975.  
  976.       sudoku[34][1] = 9; sudoku[36][1] = 8; sudoku[45][1] = 3; sudoku[52][1] = 4; sudoku[53][1] = 7;
  977.      
  978.  
  979.       sudoku[56][1] = 3; sudoku[57][1] = 7; sudoku[64][1] = 6; sudoku[65][1] = 4;sudoku[66][1] = 1;
  980.  
  981.       sudoku[76][1] = 6; sudoku[77][1] = 4; sudoku[69][1] = 3;
  982.      
  983.       sudoku[70][1] = 8; sudoku[79][1] = 5;
  984.      
  985.  
  986.       // Set the Solved Flag for each
  987.       sudoku[3][0] = 1; sudoku[12][0] = 1;
  988.      
  989.       sudoku[5][0] = 1; sudoku[6][0] = 1; sudoku[13][0] = 1;
  990.  
  991.       sudoku[16][0] = 1; sudoku[17][0] = 1; sudoku[18][0] = 1; sudoku[25][0] = 1; sudoku[26][0] = 1;
  992.      
  993.  
  994.       sudoku[29][0] = 1; sudoku[30][0] = 1; sudoku[37][0] = 1; sudoku[46][0] = 1; sudoku[48][0] = 1;
  995.  
  996.       sudoku[33][0] = 1; sudoku[40][0] = 1; sudoku[41][0] = 1;  sudoku[42][0] = 1; sudoku[49][0] = 1;
  997.  
  998.       sudoku[34][0] = 1; sudoku[36][0] = 1; sudoku[45][0] = 1; sudoku[52][0] = 1; sudoku[53][0] = 1;
  999.      
  1000.  
  1001.       sudoku[56][0] = 1; sudoku[57][0] = 1; sudoku[64][0] = 1; sudoku[65][0] = 1;sudoku[66][0] = 1;
  1002.  
  1003.       sudoku[76][0] = 1; sudoku[77][0] = 1; sudoku[69][0] = 1;
  1004.      
  1005.       sudoku[70][0] = 1; sudoku[79][0] = 1;
  1006.  
  1007.  } else
  1008.  
  1009.  if (puzzlenum == 5 ){
  1010.      
  1011.       // Load Numbers
  1012.       sudoku[2][1] = 3; sudoku[3][1] = 2; sudoku[12][1] = 6; sudoku[21][1] = 9;
  1013.      
  1014.       sudoku[4][1] = 9; sudoku[5][1] = 8; sudoku[22][1] = 2;
  1015.  
  1016.       sudoku[17][1] = 3; sudoku[27][1] = 7;
  1017.      
  1018.  
  1019.       sudoku[30][1] = 7; sudoku[47][1] = 9;
  1020.  
  1021.       sudoku[31][1] = 1; sudoku[40][1] = 3; sudoku[42][1] = 5; sudoku[51][1] = 4;
  1022.  
  1023.       sudoku[35][1] = 5; sudoku[52][1] = 6;
  1024.      
  1025.  
  1026.       sudoku[55][1] = 2; sudoku[65][1] = 6;
  1027.  
  1028.       sudoku[60][1] = 9; sudoku[77][1] = 5; sudoku[78][1] = 3;
  1029.      
  1030.       sudoku[61][1] = 3; sudoku[70][1] = 7; sudoku[79][1] = 2; sudoku[80][1] = 6;
  1031.      
  1032.  
  1033.       // Set the Solved Flag for each
  1034.       sudoku[2][0] = 1; sudoku[3][0] = 1; sudoku[12][0] = 1; sudoku[21][0] = 1;
  1035.      
  1036.       sudoku[4][0] = 1; sudoku[5][0] = 1; sudoku[22][0] = 1;
  1037.  
  1038.       sudoku[17][0] = 1; sudoku[27][0] = 1;
  1039.      
  1040.  
  1041.       sudoku[30][0] = 1; sudoku[47][0] = 1;
  1042.  
  1043.       sudoku[31][0] = 1; sudoku[40][0] = 1; sudoku[42][0] = 1; sudoku[51][0] = 1;
  1044.  
  1045.       sudoku[35][0] = 1; sudoku[52][0] = 1;
  1046.      
  1047.  
  1048.       sudoku[55][0] = 1; sudoku[65][0] = 1;
  1049.  
  1050.       sudoku[60][0] = 1; sudoku[77][0] = 1; sudoku[78][0] = 1;
  1051.      
  1052.       sudoku[61][0] = 1; sudoku[70][0] = 1; sudoku[79][0] = 1; sudoku[80][0] = 1;
  1053.  
  1054.  }
  1055.  
  1056. }
  1057.  
  1058.  
  1059. void refreshdisplay() { //Refresh the display once a value has changed
  1060.  
  1061.     tft.setTextSize(2);
  1062.  
  1063.   for (byte a = 1; a < 82; a++) {      
  1064.  
  1065.     //Test solve or set condition
  1066.     if  (sudoku[a][1] != 0) {  
  1067.  
  1068.         //First Clear Location
  1069.         tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);      
  1070.  
  1071.          if (sudoku[a][0] != 0) { // Do not draw 0 just leave blank square
  1072.              if (sudoku[a][0] == 1) {
  1073.                     tft.setTextColor(WHITE);
  1074.                 } else if (sudoku[a][0] == 2) {
  1075.                     tft.setTextColor(GREEN); // Set this colour if not a genuine set clue
  1076.                 }      
  1077.               tft.setCursor( sudoku[a][3], sudoku[a][2]);  
  1078.               tft.println(sudoku[a][1]);
  1079.          }
  1080.          
  1081.          
  1082.          
  1083.      }
  1084.   }
  1085.  
  1086. }
  1087.  
  1088.  
  1089. void drawscreen(){
  1090.  
  1091. //    tft.fillScreen(BLACK);
  1092.  
  1093. // Setup Screen
  1094.  
  1095. GREEN  = 0x07E0;
  1096.  
  1097.  
  1098.   tft.fillRect(1, 1, 239, 239, BLACK);
  1099.  
  1100.   tft.drawRect(0, 0, BOXSIZE, BOXSIZE, WHITE);
  1101.   tft.drawRect(0+BOXSIZE, 0, BOXSIZE, BOXSIZE, WHITE);
  1102.   tft.drawRect(0+BOXSIZE+BOXSIZE, 0, BOXSIZE, BOXSIZE, WHITE);  
  1103.  
  1104.   tft.drawRect(0, BOXSIZE, BOXSIZE, BOXSIZE, WHITE);
  1105.   tft.drawRect(0+BOXSIZE, BOXSIZE, BOXSIZE, BOXSIZE, WHITE);
  1106.   tft.drawRect(0+BOXSIZE+BOXSIZE, BOXSIZE, BOXSIZE, BOXSIZE, WHITE);
  1107.  
  1108.   tft.drawRect(0, BOXSIZE*2, BOXSIZE, BOXSIZE, WHITE);
  1109.   tft.drawRect(0+BOXSIZE, BOXSIZE*2, BOXSIZE, BOXSIZE, WHITE);
  1110.   tft.drawRect(0+BOXSIZE+BOXSIZE, BOXSIZE*2, BOXSIZE, BOXSIZE, WHITE);  
  1111.  
  1112. }
  1113.  
  1114.  
  1115. void resetmatrix(){  // Initialize the sudoku matrix by setting all locations to zero and loading in the coordinates for each touch location
  1116. byte hole = 1;
  1117.   for (byte a = 0; a < 9; a++) {
  1118.     for (byte b = 0; b < 9; b++) {
  1119.       sudoku[hole][0] = 0; // Solve Flag
  1120.       sudoku[hole][1] = 0; // Display Value
  1121.       sudoku[hole][2] = colcoord[a]; // Matrix Column coordinate
  1122.       sudoku[hole][3] = rowcoord[b]; // Matrix Row coordinate
  1123.       sudoku[hole][4] = 1; // V1
  1124.       sudoku[hole][5] = 2; // V2
  1125.       sudoku[hole][6] = 3; // V3    
  1126.       sudoku[hole][7] = 4; // V4    
  1127.       sudoku[hole][8] = 5; // V5    
  1128.       sudoku[hole][9] = 6; // V6
  1129.       sudoku[hole][10] = 7; // V7
  1130.       sudoku[hole][11] = 8; // V8    
  1131.       sudoku[hole][12] = 9; // V9        
  1132.       hole++;
  1133.     }
  1134.   }
  1135. }
  1136.  
  1137.  
  1138. void drawbuttons() {
  1139.   // Setup Buttons
  1140.   GREEN  = 0x07E0;
  1141.  
  1142.   //Button 1
  1143.   tft.drawCircle(280, 30, 24, GREEN);
  1144.   tft.fillCircle(280, 30, 20, GREEN);  
  1145.   tft.setTextColor(BLACK);  tft.setTextSize(1);
  1146.   tft.setCursor(268, 27);   tft.println("HOME");  
  1147.  
  1148.   //Button 2
  1149.   tft.drawCircle(280, 90, 24, YELLOW);
  1150.   tft.fillCircle(280, 90, 20, YELLOW);  
  1151.   tft.setTextColor(BLACK);  tft.setTextSize(1);
  1152.   tft.setCursor(268, 87);   tft.println("PLAY");  
  1153.  
  1154.   //Button 3
  1155.   tft.drawCircle(280, 150, 24, MAGENTA);
  1156.   tft.fillCircle(280, 150, 20, MAGENTA);  
  1157.   tft.setTextColor(BLACK);  tft.setTextSize(1);
  1158.   tft.setCursor(268, 147);   tft.println("HELP");  
  1159.  
  1160.  
  1161.    //Button 4
  1162.   tft.drawCircle(280, 210, 24, BLUE);
  1163.   tft.fillCircle(280, 210, 20, BLUE);  
  1164.   tft.setTextColor(BLACK);  tft.setTextSize(1);
  1165.   tft.setCursor(266, 207);   tft.println("SOLVE");  
  1166.  
  1167.  
  1168.  
  1169.  
  1170. }
  1171.  
  1172. void solvealigndata(){ // Once a location is marked as solved then all data in that location nees to be set to Zero
  1173.  
  1174.   for (byte a = 1; a < 82; a++) { // Cycle through all locations
  1175.  
  1176.     if (sudoku[a][0] > 0) { // If location solved then zero out all data in array except correct value
  1177.  
  1178.       /*
  1179.      Serial.print(a);      Serial.print(" ");
  1180.  
  1181.      Serial.print(sudoku[a][1]);      Serial.print(" ");
  1182.  
  1183.      Serial.print(3+sudoku[a][1]);       Serial.print(" ");
  1184.  
  1185.      Serial.print(sudoku[a][4]);
  1186.      
  1187.      Serial.print(sudoku[a][5]);
  1188.  
  1189.      Serial.print(sudoku[a][6]);
  1190.  
  1191.      Serial.print(sudoku[a][7]);
  1192.  
  1193.      Serial.print(sudoku[a][8]);
  1194.  
  1195.      Serial.print(sudoku[a][9]);
  1196.  
  1197.      Serial.print(sudoku[a][10]);
  1198.  
  1199.      Serial.print(sudoku[a][11]);
  1200.  
  1201.      Serial.println(sudoku[a][12]);
  1202.  
  1203.       */
  1204.      
  1205.       sudoku[a][4] = 0; // V1
  1206.       sudoku[a][5] = 0; // V2
  1207.       sudoku[a][6] = 0; // V3    
  1208.       sudoku[a][7] = 0; // V4    
  1209.       sudoku[a][8] = 0; // V5    
  1210.       sudoku[a][9] = 0; // V6
  1211.       sudoku[a][10] = 0; // V7
  1212.       sudoku[a][11] = 0; // V8    
  1213.       sudoku[a][12] = 0; // V9
  1214.  
  1215.       // Now poke the answer into the correct location
  1216.       sudoku[a][(sudoku[a][1]+3)] = sudoku[a][1]; // Load the solved value into the array
  1217.  
  1218.  /*    
  1219.      Serial.print(a);      Serial.print(" ");
  1220.  
  1221.      Serial.print(sudoku[a][1]);      Serial.print(" ");
  1222.  
  1223.      Serial.print(3+sudoku[a][1]);       Serial.print(" ");
  1224.  
  1225.      Serial.print(sudoku[a][4]);
  1226.  
  1227.      Serial.print(sudoku[a][5]);
  1228.  
  1229.      Serial.print(sudoku[a][6]);
  1230.  
  1231.      Serial.print(sudoku[a][7]);
  1232.  
  1233.      Serial.print(sudoku[a][8]);
  1234.  
  1235.      Serial.print(sudoku[a][9]);
  1236.  
  1237.      Serial.print(sudoku[a][10]);
  1238.  
  1239.      Serial.print(sudoku[a][11]);
  1240.  
  1241.      Serial.println(sudoku[a][12]);
  1242.  
  1243. */
  1244.  
  1245.                  
  1246.     }    
  1247.   }
  1248.  
  1249.  
  1250. }
  1251.  
  1252. void reversesolve(){ // subroutine to reverse engineer solved locations in the matrix and label themas solved
  1253. byte tempcount = 0;
  1254.   for (byte a = 1; a < 82; a++) { // Cycle through all locations
  1255.  
  1256. /*        
  1257.      Serial.print(a);      Serial.print(" ");
  1258.  
  1259.      Serial.print(sudoku[a][0]);      Serial.print(" ");
  1260.  
  1261. //     Serial.print(3+sudoku[a][1]);       Serial.print(" ");
  1262.  
  1263.      Serial.print(sudoku[a][4]);
  1264.      
  1265.      Serial.print(sudoku[a][5]);
  1266.  
  1267.      Serial.print(sudoku[a][6]);
  1268.  
  1269.      Serial.print(sudoku[a][7]);
  1270.  
  1271.      Serial.print(sudoku[a][8]);
  1272.  
  1273.      Serial.print(sudoku[a][9]);
  1274.  
  1275.      Serial.print(sudoku[a][10]);
  1276.  
  1277.      Serial.print(sudoku[a][11]);
  1278.  
  1279.      Serial.println(sudoku[a][12]);
  1280.  
  1281.  */    
  1282.  
  1283.      if (sudoku[a][0] == 0) { // Ignore location if already solved
  1284.  
  1285.         // Read each and count the number that have been elimated    
  1286.         tempcount = 0;
  1287.         for (byte b = 4; b < 13; b++) {
  1288.             if (sudoku[a][b] == 0) {// If equal to 0 then count
  1289.               tempcount++;
  1290.             }
  1291.         }
  1292.  
  1293.         if (tempcount == 8){ // If only one valid result then find again then mark location as solved
  1294.             for (byte c = 4; c < 13; c++) { // Read each and identify the only solution  
  1295.               if (sudoku[a][c] > 0) {
  1296.                 sudoku[a][0] = 1;  // Set Solved Location Flag
  1297.                 sudoku[a][1] = sudoku[a][c];  // Set value
  1298.               }
  1299.             }    
  1300.         }                
  1301.     }    
  1302.        
  1303. /*
  1304.      Serial.print(a);      Serial.print(" ");
  1305.  
  1306.      Serial.print(sudoku[a][0]);      Serial.print(" ");
  1307.  
  1308.      Serial.print(tempcount);       Serial.print(" ");
  1309.  
  1310.      Serial.print(sudoku[a][4]);
  1311.  
  1312.      Serial.print(sudoku[a][5]);
  1313.  
  1314.      Serial.print(sudoku[a][6]);
  1315.  
  1316.      Serial.print(sudoku[a][7]);
  1317.  
  1318.      Serial.print(sudoku[a][8]);
  1319.  
  1320.      Serial.print(sudoku[a][9]);
  1321.  
  1322.      Serial.print(sudoku[a][10]);
  1323.  
  1324.      Serial.print(sudoku[a][11]);
  1325.  
  1326.      Serial.println(sudoku[a][12]);
  1327.  
  1328. */
  1329.   }
  1330. }
  1331.  
  1332. void reversesolvecolor(){ // subroutine to reverse engineer solved locations in the matrix and label themas solved
  1333. byte tempcount = 0;
  1334.   for (byte a = 1; a < 82; a++) { // Cycle through all locations
  1335.  
  1336. /*        
  1337.      Serial.print(a);      Serial.print(" ");
  1338.  
  1339.      Serial.print(sudoku[a][0]);      Serial.print(" ");
  1340.  
  1341. //     Serial.print(3+sudoku[a][1]);       Serial.print(" ");
  1342.  
  1343.      Serial.print(sudoku[a][4]);
  1344.      
  1345.      Serial.print(sudoku[a][5]);
  1346.  
  1347.      Serial.print(sudoku[a][6]);
  1348.  
  1349.      Serial.print(sudoku[a][7]);
  1350.  
  1351.      Serial.print(sudoku[a][8]);
  1352.  
  1353.      Serial.print(sudoku[a][9]);
  1354.  
  1355.      Serial.print(sudoku[a][10]);
  1356.  
  1357.      Serial.print(sudoku[a][11]);
  1358.  
  1359.      Serial.println(sudoku[a][12]);
  1360.  
  1361.  */    
  1362.  
  1363.      if (sudoku[a][0] == 0) { // Ignore location if already solved
  1364.  
  1365.         // Read each and count the number that have been elimated    
  1366.         tempcount = 0;
  1367.         for (byte b = 4; b < 13; b++) {
  1368.             if (sudoku[a][b] == 0) {// If equal to 0 then count
  1369.               tempcount++;
  1370.             }
  1371.         }
  1372.  
  1373.         if (tempcount == 8){ // If only one valid result then find again then mark location as solved
  1374.             for (byte c = 4; c < 13; c++) { // Read each and identify the only solution  
  1375.               if (sudoku[a][c] > 0) {
  1376.                 sudoku[a][0] = 2;  // Set Solved Location Flag
  1377.                 sudoku[a][1] = sudoku[a][c];  // Set value
  1378.               }
  1379.             }    
  1380.         }                
  1381.     }    
  1382.        
  1383. /*
  1384.      Serial.print(a);      Serial.print(" ");
  1385.  
  1386.      Serial.print(sudoku[a][0]);      Serial.print(" ");
  1387.  
  1388.      Serial.print(tempcount);       Serial.print(" ");
  1389.  
  1390.      Serial.print(sudoku[a][4]);
  1391.  
  1392.      Serial.print(sudoku[a][5]);
  1393.  
  1394.      Serial.print(sudoku[a][6]);
  1395.  
  1396.      Serial.print(sudoku[a][7]);
  1397.  
  1398.      Serial.print(sudoku[a][8]);
  1399.  
  1400.      Serial.print(sudoku[a][9]);
  1401.  
  1402.      Serial.print(sudoku[a][10]);
  1403.  
  1404.      Serial.print(sudoku[a][11]);
  1405.  
  1406.      Serial.println(sudoku[a][12]);
  1407.  
  1408. */
  1409.   }
  1410. }
  1411.  
  1412.  
  1413.  
  1414.  
  1415. void solvehorizontal(){ // Take Solved locations and apply horizontal rule
  1416. // Cycle through all locations and using solved flag remove all associate horizontal possibilities  
  1417.  
  1418.  
  1419. /*
  1420. for (byte d = 1; d < 82; d++) { // Cycle through all locations
  1421.      Serial.print(d);      Serial.print(" ");
  1422.  
  1423.      Serial.print(sudoku[d][0]);      Serial.print(" ");
  1424.  
  1425.      Serial.print(sudoku[d][4]);
  1426.  
  1427.      Serial.print(sudoku[d][5]);
  1428.  
  1429.      Serial.print(sudoku[d][6]);
  1430.  
  1431.      Serial.print(sudoku[d][7]);
  1432.  
  1433.      Serial.print(sudoku[d][8]);
  1434.  
  1435.      Serial.print(sudoku[d][9]);
  1436.  
  1437.      Serial.print(sudoku[d][10]);
  1438.  
  1439.      Serial.print(sudoku[d][11]);
  1440.  
  1441.      Serial.println(sudoku[d][12]);
  1442. }
  1443. */
  1444.           // ROW 1 ************************  
  1445.           // Step through each of ROW  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  1446.           for (byte a = 1; a < 10; a++) { // Cycle through all locations
  1447.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  1448.                   for (byte r = 1; r < 10; r++) {          
  1449.                       if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
  1450.                         sudoku[r][sudoku[a][1]+3] = 0;
  1451.                        }
  1452.                   }          
  1453.               }
  1454.           }  
  1455.  
  1456.          
  1457.           // ROW 2 ************************  
  1458.           // Step through each of ROW  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  1459.           for (byte a = 10; a < 19; a++) { // Cycle through all locations
  1460.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  1461.                   for (byte r = 10; r < 19; r++) {          
  1462.                       if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
  1463.                         sudoku[r][sudoku[a][1]+3] = 0;
  1464.                        }
  1465.                   }          
  1466.               }
  1467.           }
  1468.  
  1469.            // ROW 3 ************************  
  1470.           // Step through each of ROW  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  1471.           for (byte a = 19; a < 28; a++) { // Cycle through all locations
  1472.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  1473.                   for (byte r = 19; r < 28; r++) {          
  1474.                       if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
  1475.                         sudoku[r][sudoku[a][1]+3] = 0;
  1476.                        }
  1477.                   }          
  1478.               }
  1479.           }  
  1480.  
  1481.          
  1482.           // ROW 4 ************************  
  1483.           // Step through each of ROW  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  1484.           for (byte a = 28; a < 37; a++) { // Cycle through all locations
  1485.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  1486.                   for (byte r = 28; r < 37; r++) {          
  1487.                       if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
  1488.                         sudoku[r][sudoku[a][1]+3] = 0;
  1489.                        }
  1490.                   }          
  1491.               }
  1492.           }
  1493.            // ROW 5 ************************  
  1494.           // Step through each of ROW  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  1495.           for (byte a = 37; a < 46; a++) { // Cycle through all locations
  1496.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  1497.                   for (byte r = 37; r < 46; r++) {          
  1498.                       if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
  1499.                         sudoku[r][sudoku[a][1]+3] = 0;
  1500.                        }
  1501.                   }          
  1502.               }
  1503.           }  
  1504.  
  1505.          
  1506.           // ROW 6 ************************  
  1507.           // Step through each of ROW  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  1508.           for (byte a = 46; a < 55; a++) { // Cycle through all locations
  1509.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  1510.                   for (byte r = 46; r < 55; r++) {          
  1511.                       if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
  1512.                         sudoku[r][sudoku[a][1]+3] = 0;
  1513.                        }
  1514.                   }          
  1515.               }
  1516.           }
  1517.            // ROW 7 ************************  
  1518.           // Step through each of ROW  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  1519.           for (byte a = 55; a < 64; a++) { // Cycle through all locations
  1520.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  1521.                   for (byte r = 55; r < 64; r++) {          
  1522.                       if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
  1523.                         sudoku[r][sudoku[a][1]+3] = 0;
  1524.                        }
  1525.                   }          
  1526.               }
  1527.           }  
  1528.  
  1529.          
  1530.           // ROW 8 ************************  
  1531.           // Step through each of ROW  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  1532.           for (byte a = 64; a < 73; a++) { // Cycle through all locations
  1533.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  1534.                   for (byte r = 64; r < 73; r++) {          
  1535.                       if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
  1536.                         sudoku[r][sudoku[a][1]+3] = 0;
  1537.                        }
  1538.                   }          
  1539.               }
  1540.           }
  1541.  
  1542.           // ROW 9 ************************  
  1543.           // Step through each of ROW  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  1544.           for (byte a = 73; a < 82; a++) { // Cycle through all locations
  1545.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  1546.                   for (byte r = 73; r < 82; r++) {          
  1547.                       if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
  1548.                         sudoku[r][sudoku[a][1]+3] = 0;
  1549.                        }
  1550.                   }          
  1551.               }
  1552.           }
  1553.  
  1554.  /*
  1555.      for (byte e = 1; e < 82; e++) { // Cycle through all locations
  1556.      Serial.print(e);      Serial.print(" ");
  1557.  
  1558.      Serial.print(sudoku[e][0]);      Serial.print(" ");
  1559.  
  1560.      Serial.print(sudoku[e][4]);
  1561.  
  1562.      Serial.print(sudoku[e][5]);
  1563.  
  1564.      Serial.print(sudoku[e][6]);
  1565.  
  1566.      Serial.print(sudoku[e][7]);
  1567.  
  1568.      Serial.print(sudoku[e][8]);
  1569.  
  1570.      Serial.print(sudoku[e][9]);
  1571.  
  1572.      Serial.print(sudoku[e][10]);
  1573.  
  1574.      Serial.print(sudoku[e][11]);
  1575.  
  1576.      Serial.println(sudoku[e][12]);        
  1577.  
  1578.     }                
  1579. */
  1580. }
  1581.  
  1582.  
  1583.     void solvevertical(){ // Take Solved locations and apply horizontal rule
  1584. // Cycle through all locations and using solved flag remove all associate vertical possibilities  
  1585.  
  1586. /*
  1587. for (byte d = 1; d < 82; d++) { // Cycle through all locations
  1588.      Serial.print(d);      Serial.print(" ");
  1589.  
  1590.      Serial.print(sudoku[d][0]);      Serial.print(" ");
  1591.  
  1592.      Serial.print(sudoku[d][4]);
  1593.  
  1594.      Serial.print(sudoku[d][5]);
  1595.  
  1596.      Serial.print(sudoku[d][6]);
  1597.  
  1598.      Serial.print(sudoku[d][7]);
  1599.  
  1600.      Serial.print(sudoku[d][8]);
  1601.  
  1602.      Serial.print(sudoku[d][9]);
  1603.  
  1604.      Serial.print(sudoku[d][10]);
  1605.  
  1606.      Serial.print(sudoku[d][11]);
  1607.  
  1608.      Serial.println(sudoku[d][12]);
  1609. }
  1610. */
  1611.           // COL 1 ************************  
  1612.           // Step through each of Col  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  1613.           for (byte a = 1; a < 74; a=a+9) { // Cycle through all locations
  1614.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  1615.                   for (byte r = 1; r < 74; r=r+9) {          
  1616.                       if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
  1617.                         sudoku[r][sudoku[a][1]+3] = 0;
  1618.                        }
  1619.                   }          
  1620.               }
  1621.           }  
  1622.  
  1623.          
  1624.           // COL 2 ************************  
  1625.           // Step through each of COL  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  1626.           for (byte a = 2; a < 75; a=a+9) { // Cycle through all locations
  1627.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  1628.                   for (byte r = 2; r < 75; r=r+9) {          
  1629.                       if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
  1630.                         sudoku[r][sudoku[a][1]+3] = 0;
  1631.                        }
  1632.                   }          
  1633.               }
  1634.           }
  1635.  
  1636.            // COL 3 ************************  
  1637.           // Step through each of COL  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  1638.           for (byte a = 3; a < 76; a=a+9) { // Cycle through all locations
  1639.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  1640.                   for (byte r = 3; r < 76; r=r+9) {          
  1641.                       if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
  1642.                         sudoku[r][sudoku[a][1]+3] = 0;
  1643.                        }
  1644.                   }          
  1645.               }
  1646.           }  
  1647.  
  1648.          
  1649.           // COL 4 ************************  
  1650.           // Step through each of COL  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  1651.           for (byte a = 4; a < 77; a=a+9) { // Cycle through all locations
  1652.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  1653.                   for (byte r = 4; r < 77; r=r+9) {          
  1654.                       if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
  1655.                         sudoku[r][sudoku[a][1]+3] = 0;
  1656.                        }
  1657.                   }          
  1658.               }
  1659.           }
  1660.            // COL 5 ************************  
  1661.           // Step through each of COL  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  1662.           for (byte a = 5; a < 78; a=a+9) { // Cycle through all locations
  1663.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  1664.                   for (byte r = 5; r < 78; r=r+9) {          
  1665.                       if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
  1666.                         sudoku[r][sudoku[a][1]+3] = 0;
  1667.                        }
  1668.                   }          
  1669.               }
  1670.           }  
  1671.  
  1672.          
  1673.           // COL 6 ************************  
  1674.           // Step through each of COL  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  1675.           for (byte a = 6; a < 79; a=a+9) { // Cycle through all locations
  1676.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  1677.                   for (byte r = 6; r < 79; r=r+9) {          
  1678.                       if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
  1679.                         sudoku[r][sudoku[a][1]+3] = 0;
  1680.                        }
  1681.                   }          
  1682.               }
  1683.           }
  1684.            // COL 7 ************************  
  1685.           // Step through each of COL  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  1686.           for (byte a = 7; a < 80; a=a+9) { // Cycle through all locations
  1687.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  1688.                   for (byte r = 7; r < 80; r=r+9) {          
  1689.                       if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
  1690.                         sudoku[r][sudoku[a][1]+3] = 0;
  1691.                        }
  1692.                   }          
  1693.               }
  1694.           }  
  1695.  
  1696.          
  1697.           // COL 8 ************************  
  1698.           // Step through each of COL  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  1699.           for (byte a = 8; a < 81; a=a+9) { // Cycle through all locations
  1700.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  1701.                   for (byte r = 8; r < 81; r=r+9) {          
  1702.                       if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
  1703.                         sudoku[r][sudoku[a][1]+3] = 0;
  1704.                        }
  1705.                   }          
  1706.               }
  1707.           }
  1708.  
  1709.           // COL 9 ************************  
  1710.           // Step through each of COL  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  1711.           for (byte a = 9; a < 82; a=a+9) { // Cycle through all locations
  1712.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  1713.                   for (byte r = 9; r < 83; r=r+9) {          
  1714.                       if ((sudoku[r][sudoku[a][1]+3] == sudoku[a][1] )&& (a!=r)) {
  1715.                         sudoku[r][sudoku[a][1]+3] = 0;
  1716.                        }
  1717.                   }          
  1718.               }
  1719.           }
  1720.  
  1721.  /*
  1722.      for (byte e = 1; e < 82; e++) { // Cycle through all locations
  1723.      Serial.print(e);      Serial.print(" ");
  1724.  
  1725.      Serial.print(sudoku[e][0]);      Serial.print(" ");
  1726.  
  1727.      Serial.print(sudoku[e][4]);
  1728.  
  1729.      Serial.print(sudoku[e][5]);
  1730.  
  1731.      Serial.print(sudoku[e][6]);
  1732.  
  1733.      Serial.print(sudoku[e][7]);
  1734.  
  1735.      Serial.print(sudoku[e][8]);
  1736.  
  1737.      Serial.print(sudoku[e][9]);
  1738.  
  1739.      Serial.print(sudoku[e][10]);
  1740.  
  1741.      Serial.print(sudoku[e][11]);
  1742.  
  1743.      Serial.println(sudoku[e][12]);        
  1744.  
  1745.     }                
  1746. */
  1747. }    
  1748.  
  1749.  
  1750. void solvepanel(){ // Take Solved locations and apply horizontal rule
  1751. // Cycle through all locations and using solved flag remove all associate panel possibilities  
  1752.  
  1753. /*
  1754.  
  1755. for (byte d = 1; d < 82; d++) { // Cycle through all locations
  1756.      Serial.print(d);      Serial.print(" ");
  1757.  
  1758.      Serial.print(sudoku[d][0]);      Serial.print(" ");
  1759.      Serial.print(sudoku[d][4]);
  1760.      Serial.print(sudoku[d][5]);
  1761.      Serial.print(sudoku[d][6]);
  1762.      Serial.print(sudoku[d][7]);
  1763.      Serial.print(sudoku[d][8]);
  1764.      Serial.print(sudoku[d][9]);
  1765.      Serial.print(sudoku[d][10]);
  1766.      Serial.print(sudoku[d][11]);
  1767.      Serial.println(sudoku[d][12]);
  1768.      }
  1769.  
  1770. */
  1771.  
  1772.  
  1773.  
  1774.           // PANEL Algorythm ************************  
  1775.           // Step through each of locations and delete duplicates of the Solved location using the panel formulae. Ignore the current location you are solving for
  1776.           for (byte a = 1; a < 82; a++) { // Cycle through all locations
  1777.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry                
  1778.                    for (byte r = 1; r < 82; r++) { // Step through all locations          
  1779.                        if ((sudoku[a][13] == sudoku[r][13]) && (a!=r)) { // Identify the locations on the Same Panel                          
  1780.                           if ((sudoku[a][13] == sudoku[r][13]) && (a!=r)) {
  1781.                                sudoku[r][sudoku[a][1]+3] = 0;                            
  1782.                           }
  1783.  
  1784.                       }  
  1785.                   }          
  1786.               }
  1787.           }  
  1788.  
  1789.     /*      
  1790.  
  1791.  
  1792.      for (byte e = 1; e < 82; e++) { // Cycle through all locations
  1793.      Serial.print(e);      Serial.print(" ");
  1794.      Serial.print(sudoku[e][0]);      Serial.print(" ");
  1795.      Serial.print(sudoku[e][4]);
  1796.      Serial.print(sudoku[e][5]);
  1797.      Serial.print(sudoku[e][6]);
  1798.      Serial.print(sudoku[e][7]);
  1799.      Serial.print(sudoku[e][8]);
  1800.      Serial.print(sudoku[e][9]);
  1801.      Serial.print(sudoku[e][10]);
  1802.      Serial.print(sudoku[e][11]);
  1803.      Serial.println(sudoku[e][12]);        
  1804.     */                
  1805.  
  1806. }
  1807.  
  1808.  
  1809.  
  1810. void loadpaneldata(){  // Load specifc Panel identification Data into the Array for each of the 81 locations
  1811.  
  1812.  
  1813.  
  1814.       // Load Numbers
  1815.       // Panel 1
  1816.       sudoku[1][13] = 1; sudoku[2][13] = 1; sudoku[3][13] = 1;
  1817.       sudoku[10][13] = 1; sudoku[11][13] = 1; sudoku[12][13] = 1;
  1818.       sudoku[19][13] = 1; sudoku[20][13] = 1; sudoku[21][13] = 1;
  1819.       // Panel 2
  1820.       sudoku[4][13] = 2; sudoku[5][13] = 2; sudoku[6][13] = 2;
  1821.       sudoku[13][13] = 2; sudoku[14][13] = 2; sudoku[15][13] = 2;
  1822.       sudoku[22][13] = 2; sudoku[23][13] = 2; sudoku[24][13] = 2;
  1823.       // Panel 3
  1824.       sudoku[7][13] = 3; sudoku[8][13] = 3; sudoku[9][13] = 3;
  1825.       sudoku[16][13] = 3; sudoku[17][13] = 3; sudoku[18][13] = 3;
  1826.       sudoku[25][13] = 3; sudoku[26][13] = 3; sudoku[27][13] = 3;      
  1827.       // Panel 4
  1828.       sudoku[28][13] = 4; sudoku[29][13] = 4; sudoku[30][13] = 4;
  1829.       sudoku[37][13] = 4; sudoku[38][13] = 4; sudoku[39][13] = 4;
  1830.       sudoku[46][13] = 4; sudoku[47][13] = 4; sudoku[48][13] = 4;
  1831.       // Panel 5
  1832.       sudoku[31][13] = 5; sudoku[32][13] = 5; sudoku[33][13] = 5;
  1833.       sudoku[40][13] = 5; sudoku[41][13] = 5; sudoku[42][13] = 5;
  1834.       sudoku[49][13] = 5; sudoku[50][13] = 5; sudoku[51][13] = 5;
  1835.       // Panel 6
  1836.       sudoku[34][13] = 6; sudoku[35][13] = 6; sudoku[36][13] = 6;
  1837.       sudoku[43][13] = 6; sudoku[44][13] = 6; sudoku[45][13] = 6;
  1838.       sudoku[52][13] = 6; sudoku[53][13] = 6; sudoku[54][13] = 6;
  1839.       // Panel 7
  1840.       sudoku[55][13] = 7; sudoku[56][13] = 7; sudoku[57][13] = 7;
  1841.       sudoku[64][13] = 7; sudoku[65][13] = 7; sudoku[66][13] = 7;
  1842.       sudoku[73][13] = 7; sudoku[74][13] = 7; sudoku[75][13] = 7;
  1843.       // Panel 8
  1844.       sudoku[58][13] = 8; sudoku[59][13] = 8; sudoku[60][13] = 8;
  1845.       sudoku[67][13] = 8; sudoku[68][13] = 8; sudoku[69][13] = 8;
  1846.       sudoku[76][13] = 8; sudoku[77][13] = 8; sudoku[78][13] = 8;      
  1847.       // Panel 9
  1848.       sudoku[61][13] = 9; sudoku[62][13] = 9; sudoku[63][13] = 9;
  1849.       sudoku[70][13] = 9; sudoku[71][13] = 9; sudoku[72][13] = 9;
  1850.       sudoku[79][13] = 9; sudoku[80][13] = 9; sudoku[81][13] = 9;
  1851.  
  1852. }    
  1853.  
  1854. // Used to identify and highlight errors in a current matrix - use solve method however instead of solving outcome just highlight conflicts in red
  1855. void helpbutton(){
  1856.  
  1857.  
  1858. // Horizontal *********************
  1859.           // ROW 1 ************************  
  1860.           // Step through each of ROW  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  1861.           for (byte a = 1; a < 10; a++) { // Cycle through all locations
  1862.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  1863.                   for (byte r = 1; r < 10; r++) {          
  1864.                       if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED                        
  1865.                            // Refresh only the location concerned with new value and show colour coded
  1866.                                 //First Clear Location
  1867.                                 tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);      
  1868.                                 tft.setTextSize(2);
  1869.                                 tft.setTextColor(RED);    
  1870.                                 tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
  1871.                                  }                      
  1872.                        }
  1873.                   }          
  1874.               }  
  1875.  
  1876.          
  1877.           // ROW 2 ************************  
  1878.           // Step through each of ROW  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  1879.           for (byte a = 10; a < 19; a++) { // Cycle through all locations
  1880.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  1881.                   for (byte r = 10; r < 19; r++) {          
  1882.                       if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED                        
  1883.                            // Refresh only the location concerned with new value and show colour coded
  1884.                                 //First Clear Location
  1885.                                 tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);      
  1886.                                 tft.setTextSize(2);
  1887.                                 tft.setTextColor(RED);    
  1888.                                 tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
  1889.                                  }                      
  1890.                        }          
  1891.               }
  1892.           }
  1893.  
  1894.            // ROW 3 ************************  
  1895.           // Step through each of ROW  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  1896.           for (byte a = 19; a < 28; a++) { // Cycle through all locations
  1897.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  1898.                   for (byte r = 19; r < 28; r++) {          
  1899.                       if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED                        
  1900.                            // Refresh only the location concerned with new value and show colour coded
  1901.                                 //First Clear Location
  1902.                                 tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);      
  1903.                                 tft.setTextSize(2);
  1904.                                 tft.setTextColor(RED);    
  1905.                                 tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
  1906.                                  }                      
  1907.                        }          
  1908.               }
  1909.           }  
  1910.  
  1911.          
  1912.           // ROW 4 ************************  
  1913.           // Step through each of ROW  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  1914.           for (byte a = 28; a < 37; a++) { // Cycle through all locations
  1915.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  1916.                   for (byte r = 28; r < 37; r++) {          
  1917.                       if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED                        
  1918.                            // Refresh only the location concerned with new value and show colour coded
  1919.                                 //First Clear Location
  1920.                                 tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);      
  1921.                                 tft.setTextSize(2);
  1922.                                 tft.setTextColor(RED);    
  1923.                                 tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
  1924.                                  }                      
  1925.                        }          
  1926.               }
  1927.           }
  1928.            // ROW 5 ************************  
  1929.           // Step through each of ROW  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  1930.           for (byte a = 37; a < 46; a++) { // Cycle through all locations
  1931.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  1932.                   for (byte r = 37; r < 46; r++) {          
  1933.                       if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED                        
  1934.                            // Refresh only the location concerned with new value and show colour coded
  1935.                                 //First Clear Location
  1936.                                 tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);      
  1937.                                 tft.setTextSize(2);
  1938.                                 tft.setTextColor(RED);    
  1939.                                 tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
  1940.                                  }                      
  1941.                        }          
  1942.               }
  1943.           }  
  1944.  
  1945.          
  1946.           // ROW 6 ************************  
  1947.           // Step through each of ROW  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  1948.           for (byte a = 46; a < 55; a++) { // Cycle through all locations
  1949.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  1950.                   for (byte r = 46; r < 55; r++) {          
  1951.                       if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED                        
  1952.                            // Refresh only the location concerned with new value and show colour coded
  1953.                                 //First Clear Location
  1954.                                 tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);      
  1955.                                 tft.setTextSize(2);
  1956.                                 tft.setTextColor(RED);    
  1957.                                 tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
  1958.                                  }                      
  1959.                        }          
  1960.               }
  1961.           }
  1962.            // ROW 7 ************************  
  1963.           // Step through each of ROW  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  1964.           for (byte a = 55; a < 64; a++) { // Cycle through all locations
  1965.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  1966.                   for (byte r = 55; r < 64; r++) {          
  1967.                       if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED                        
  1968.                            // Refresh only the location concerned with new value and show colour coded
  1969.                                 //First Clear Location
  1970.                                 tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);      
  1971.                                 tft.setTextSize(2);
  1972.                                 tft.setTextColor(RED);    
  1973.                                 tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
  1974.                                  }                      
  1975.                        }          
  1976.               }
  1977.           }  
  1978.  
  1979.          
  1980.           // ROW 8 ************************  
  1981.           // Step through each of ROW  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  1982.           for (byte a = 64; a < 73; a++) { // Cycle through all locations
  1983.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  1984.                   for (byte r = 64; r < 73; r++) {          
  1985.                       if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED                        
  1986.                            // Refresh only the location concerned with new value and show colour coded
  1987.                                 //First Clear Location
  1988.                                 tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);      
  1989.                                 tft.setTextSize(2);
  1990.                                 tft.setTextColor(RED);    
  1991.                                 tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
  1992.                                  }                      
  1993.                        }          
  1994.               }
  1995.           }
  1996.  
  1997.           // ROW 9 ************************  
  1998.           // Step through each of ROW  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  1999.           for (byte a = 73; a < 82; a++) { // Cycle through all locations
  2000.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  2001.                   for (byte r = 73; r < 82; r++) {          
  2002.                       if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED                        
  2003.                            // Refresh only the location concerned with new value and show colour coded
  2004.                                 //First Clear Location
  2005.                                 tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);      
  2006.                                 tft.setTextSize(2);
  2007.                                 tft.setTextColor(RED);    
  2008.                                 tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
  2009.                                  }                      
  2010.                        }          
  2011.               }
  2012.           }
  2013.  
  2014. // Vertical ****************
  2015.           // COL 1 ************************  
  2016.           // Step through each of Col  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  2017.           for (byte a = 1; a < 74; a=a+9) { // Cycle through all locations
  2018.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  2019.                   for (byte r = 1; r < 74; r=r+9) {          
  2020.                       if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED                        
  2021.                            // Refresh only the location concerned with new value and show colour coded
  2022.                                 //First Clear Location
  2023.                                 tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);      
  2024.                                 tft.setTextSize(2);
  2025.                                 tft.setTextColor(RED);    
  2026.                                 tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
  2027.                                  }                      
  2028.                        }          
  2029.               }
  2030.           }  
  2031.  
  2032.          
  2033.           // COL 2 ************************  
  2034.           // Step through each of COL  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  2035.           for (byte a = 2; a < 75; a=a+9) { // Cycle through all locations
  2036.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  2037.                   for (byte r = 2; r < 75; r=r+9) {          
  2038.                       if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED                        
  2039.                            // Refresh only the location concerned with new value and show colour coded
  2040.                                 //First Clear Location
  2041.                                 tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);      
  2042.                                 tft.setTextSize(2);
  2043.                                 tft.setTextColor(RED);    
  2044.                                 tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
  2045.                                  }                      
  2046.                        }          
  2047.               }
  2048.           }
  2049.  
  2050.            // COL 3 ************************  
  2051.           // Step through each of COL  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  2052.           for (byte a = 3; a < 76; a=a+9) { // Cycle through all locations
  2053.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  2054.                   for (byte r = 3; r < 76; r=r+9) {          
  2055.                       if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED                        
  2056.                            // Refresh only the location concerned with new value and show colour coded
  2057.                                 //First Clear Location
  2058.                                 tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);      
  2059.                                 tft.setTextSize(2);
  2060.                                 tft.setTextColor(RED);    
  2061.                                 tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
  2062.                                  }                      
  2063.                        }          
  2064.               }
  2065.           }  
  2066.  
  2067.          
  2068.           // COL 4 ************************  
  2069.           // Step through each of COL  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  2070.           for (byte a = 4; a < 77; a=a+9) { // Cycle through all locations
  2071.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  2072.                   for (byte r = 4; r < 77; r=r+9) {          
  2073.                       if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED                        
  2074.                            // Refresh only the location concerned with new value and show colour coded
  2075.                                 //First Clear Location
  2076.                                 tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);      
  2077.                                 tft.setTextSize(2);
  2078.                                 tft.setTextColor(RED);    
  2079.                                 tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
  2080.                                  }                      
  2081.                        }          
  2082.               }
  2083.           }
  2084.            // COL 5 ************************  
  2085.           // Step through each of COL  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  2086.           for (byte a = 5; a < 78; a=a+9) { // Cycle through all locations
  2087.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  2088.                   for (byte r = 5; r < 78; r=r+9) {          
  2089.                       if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED                        
  2090.                            // Refresh only the location concerned with new value and show colour coded
  2091.                                 //First Clear Location
  2092.                                 tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);      
  2093.                                 tft.setTextSize(2);
  2094.                                 tft.setTextColor(RED);    
  2095.                                 tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
  2096.                                  }                      
  2097.                        }          
  2098.               }
  2099.           }  
  2100.  
  2101.          
  2102.           // COL 6 ************************  
  2103.           // Step through each of COL  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  2104.           for (byte a = 6; a < 79; a=a+9) { // Cycle through all locations
  2105.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  2106.                   for (byte r = 6; r < 79; r=r+9) {          
  2107.                       if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED                        
  2108.                            // Refresh only the location concerned with new value and show colour coded
  2109.                                 //First Clear Location
  2110.                                 tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);      
  2111.                                 tft.setTextSize(2);
  2112.                                 tft.setTextColor(RED);    
  2113.                                 tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
  2114.                                  }
  2115.                   }          
  2116.               }
  2117.           }
  2118.            // COL 7 ************************  
  2119.           // Step through each of COL  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  2120.           for (byte a = 7; a < 80; a=a+9) { // Cycle through all locations
  2121.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  2122.                   for (byte r = 7; r < 80; r=r+9) {          
  2123.                       if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED                        
  2124.                            // Refresh only the location concerned with new value and show colour coded
  2125.                                 //First Clear Location
  2126.                                 tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);      
  2127.                                 tft.setTextSize(2);
  2128.                                 tft.setTextColor(RED);    
  2129.                                 tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
  2130.                                  }
  2131.                   }          
  2132.               }
  2133.           }  
  2134.  
  2135.          
  2136.           // COL 8 ************************  
  2137.           // Step through each of COL  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  2138.           for (byte a = 8; a < 81; a=a+9) { // Cycle through all locations
  2139.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  2140.                   for (byte r = 8; r < 81; r=r+9) {          
  2141.                       if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED                        
  2142.                            // Refresh only the location concerned with new value and show colour coded
  2143.                                 //First Clear Location
  2144.                                 tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);      
  2145.                                 tft.setTextSize(2);
  2146.                                 tft.setTextColor(RED);    
  2147.                                 tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
  2148.                                  }
  2149.                   }          
  2150.               }
  2151.           }
  2152.  
  2153.           // COL 9 ************************  
  2154.           // Step through each of COL  locations and delete duplicates of the Solved location. Ignore the current location you are solving for
  2155.           for (byte a = 9; a < 82; a=a+9) { // Cycle through all locations
  2156.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry
  2157.                   for (byte r = 9; r < 83; r=r+9) {          
  2158.                       if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED                        
  2159.                            // Refresh only the location concerned with new value and show colour coded
  2160.                                 //First Clear Location
  2161.                                 tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);      
  2162.                                 tft.setTextSize(2);
  2163.                                 tft.setTextColor(RED);    
  2164.                                 tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
  2165.                                  }
  2166.                   }          
  2167.               }
  2168.           }
  2169. // Panels *******************
  2170.  
  2171.           // PANEL Algorythm ************************  
  2172.           // Step through each of locations and delete duplicates of the Solved location using the Oanel formulae. Ignore the current location you are solving for
  2173.           for (byte a = 1; a < 82; a++) { // Cycle through all locations
  2174.               if (sudoku[a][0] > 0) { // Identify the locations that are already solved and delete any occurences that are already in scope of enquiry                
  2175.                    for (byte r = 1; r < 82; r++) { // Step through all locations          
  2176.                        if ((sudoku[a][13] == sudoku[r][13]) && (a!=r)) { // Identify the locations on the Same Panel                          
  2177.                       if ((sudoku[a][1] == sudoku[r][1] ) && (a!=r)) { // Current location is not a master value and it is duplicate then color RED                        
  2178.                            // Refresh only the location concerned with new value and show colour coded
  2179.                                 //First Clear Location
  2180.                                 tft.fillRect(sudoku[a][3], sudoku[a][2], 15, 15, BLACK);      
  2181.                                 tft.setTextSize(2);
  2182.                                 tft.setTextColor(RED);    
  2183.                                 tft.setCursor( sudoku[a][3], sudoku[a][2]); tft.println(sudoku[a][1]);
  2184.                                  }
  2185.  
  2186.                       }  
  2187.                   }          
  2188.               }
  2189.           }  
  2190.  
  2191.  
  2192. // Horizontal conflict help function - Step through data and identify manually changed locations as conflicts in RED. Leave items set at WHITE as WHITE
  2193.  
  2194. // Vertical conflict help function - Step through data and identify manually changed locations as conflicts in RED. Leave items set at WHITE as WHITE
  2195.  
  2196. // Panel conflict help function - Step through data and identify manually changed locations as conflicts in RED. Leave items set at WHITE as WHITE
  2197.    
  2198.  
  2199. }
  2200.  
  2201.  
  2202. void uniquecandidate() { // Each panel, row and column on a Sudoku board must contain every number between 1 and 9.
  2203.                          // 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.
  2204.  
  2205. /*
  2206.  
  2207. for (byte d = 1; d < 82; d++) { // Cycle through all locations
  2208.      Serial.print(d);      Serial.print(" ");
  2209.  
  2210.      Serial.print(sudoku[d][0]);      Serial.print(" ");
  2211.      Serial.print(sudoku[d][1]);      Serial.print(" ");
  2212.      Serial.print(sudoku[d][4]);
  2213.      Serial.print(sudoku[d][5]);
  2214.      Serial.print(sudoku[d][6]);
  2215.      Serial.print(sudoku[d][7]);
  2216.      Serial.print(sudoku[d][8]);
  2217.      Serial.print(sudoku[d][9]);
  2218.      Serial.print(sudoku[d][10]);
  2219.      Serial.print(sudoku[d][11]);
  2220.      Serial.println(sudoku[d][12]);
  2221.      }
  2222.  
  2223. */
  2224.  
  2225. byte tempcount = 0;
  2226.  
  2227.   for (byte p = 1; p < 10; p++) { // Cycle through all panels 1 to 9
  2228.  
  2229.       for (byte v = 1; v < 10; v++) { // Step through all possible unique location values in each panel                
  2230.  
  2231.  
  2232.           for (byte r = 1; r < 82; r++) { // Step through all locations  
  2233.    
  2234.                   if (sudoku[r][13] == p) {  //Only operate on those locations that are in this panel
  2235.    
  2236.                       if (sudoku[r][v+3] == v) {// Count this if value is what we are looking for
  2237.                         tempcount++;
  2238.                       }              
  2239.                   }                      
  2240.           }
  2241.           // Check if unique
  2242.           if ( tempcount == 1) { // This is a unique value so reset the location with this being a solved location
  2243.               // Repeat process to locate unique location
  2244.               for (byte r = 1; r < 82; r++) { // Step through all locations and then mark as solved
  2245.  
  2246.                   if (sudoku[r][13] == p) {  //Only operate on those locations that are in this panel
  2247.                       if (sudoku[r][v+3] == v) {// Count this if value is what we are looking for
  2248.                        
  2249.                             // Now poke the answer into the correct location
  2250.                             if (sudoku[r][0] == 0) { // Change to solved but remain green
  2251.                               sudoku[r][0] = 2;
  2252.                             }
  2253.                             sudoku[r][1] = v;
  2254.                       }              
  2255.                   }          
  2256.               }      
  2257.           }
  2258.           // Reset temp counter
  2259.           tempcount = 0;
  2260.       }
  2261.   }  
  2262. /*
  2263. for (byte d = 1; d < 82; d++) { // Cycle through all locations
  2264.      Serial.print(d);      Serial.print(" ");
  2265.  
  2266.      Serial.print(sudoku[d][0]);      Serial.print(" ");
  2267.      Serial.print(sudoku[d][1]);      Serial.print(" ");
  2268.      Serial.print(sudoku[d][4]);
  2269.      Serial.print(sudoku[d][5]);
  2270.      Serial.print(sudoku[d][6]);
  2271.      Serial.print(sudoku[d][7]);
  2272.      Serial.print(sudoku[d][8]);
  2273.      Serial.print(sudoku[d][9]);
  2274.      Serial.print(sudoku[d][10]);
  2275.      Serial.print(sudoku[d][11]);
  2276.      Serial.println(sudoku[d][12]);
  2277.      }
  2278. */                        
  2279.  
  2280. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement