int iSelect = -1; int jSelect = -1; int iExamine = 0; int jExamine = 0; int solveState = 0; boolean solvedOne = false; int highlight = 0; int[][] savedGame = new int[0][0]; PFont myFont; sBox[][] myBox; boolean isPaused = false; boolean solvePause = false; void setup() { size(400,400); myFont = loadFont("arial.vlw"); textFont(myFont,11); myBox = new sBox[9][9]; for(int i=0;i < 9;i++) for(int j=0; j<9; j++) myBox[i][j] = new sBox(i,j); //framerate(10); } void draw() { stroke(0); fill(255); strokeWeight(1); for(int i=0;i<9;i++) for(int j=0;j<9;j++) { rect(20+j*40,20+i*40,40,40); } strokeWeight(3); noFill(); rect(20,20,360,360); line(140,20,140,380); line(260,20,260,380); line(20,140,380,140); line(20,260,380,260); if (iSelect !=-1) { //highlight box stroke(#00FF00); //fill(#0000FF); if(highlight == 1) rect(20,20+iSelect*40,360,40); else if(highlight==2) rect(20+jSelect*40,20,40,360); else if(highlight == 3) rect(int(jSelect/3.0)*120+20,int(iSelect/3.0)*120+20,120,120); noFill(); //selector box stroke(#FF0000); rect(20+jSelect*40,20+iSelect*40,40,40); stroke(0); } for(int i=0;i < 9;i++) for(int j=0; j<9; j++) myBox[i][j].display(); //SOLVE STATE 0 //------------- if (solveState == 0) { //Draw examination box stroke(#0000FF); noFill(); rect(20+jExamine*40,20+iExamine*40,40,40); //PROCESS OF ELIMINATION DETECTOR if (myBox[iExamine][jExamine].num == -1 && myBox[iExamine][jExamine].numPossibilities() == 1) { int y = 0; for(int i=0;i<9;i++) if(myBox[iExamine][jExamine].numPossible[i]) { y = i; myBox[iExamine][jExamine].numPossible[i] = false; solvedOne = solvedOne || true; } myBox[iExamine][jExamine].setNum(y+1); myBox[iExamine][jExamine].compSolved = true; killOthers(iExamine,jExamine,y+1); } for(int x=0;x<9;x++) //ROW EXISTENTIAL TEST if((numInRow(iExamine,x) == 1 && myBox[iExamine][jExamine].numPossible[x]) || //COLUMN EXISTENTIAL TEST (numInCol(jExamine,x) == 1 && myBox[iExamine][jExamine].numPossible[x]) || //REGION EXISTENTIAL TEST (numInReg(iExamine,jExamine,x) == 1 && myBox[iExamine][jExamine].numPossible[x])) { myBox[iExamine][jExamine].setNum(x+1); myBox[iExamine][jExamine].compSolved = true; killOthers(iExamine,jExamine,x+1); solvedOne = solvedOne || true; } //iterate examiners if(!solvePause) { if(jExamine < 8) jExamine++; else if (iExamine <8 && jExamine == 8) { iExamine++; jExamine = 0; } else if (iExamine == 8 && jExamine == 8) { if(!solvedOne) solveState++; solvedOne = false; iExamine = 0; jExamine = 0; } } } //SOLVE STATE 1 //------------- else if (solveState == 1) { stroke(#00FF00); noFill(); if(iExamine < 9) rect(20,20+iExamine*40,360,40); else if(iExamine == 9) rect(20+jExamine*40,20,40,360); //CHECK ROWS if (iExamine < 9) { boolean regOFirst, regOSecond, regOThird; for(int i=0;i<9;i++) { regOFirst = myBox[iExamine][0].numPossible[i] || myBox[iExamine][1].numPossible[i] || myBox[iExamine][2].numPossible[i]; regOSecond = myBox[iExamine][3].numPossible[i] || myBox[iExamine][4].numPossible[i] || myBox[iExamine][5].numPossible[i]; regOThird = myBox[iExamine][6].numPossible[i] || myBox[iExamine][7].numPossible[i] || myBox[iExamine][8].numPossible[i]; if (regOFirst && !regOSecond && !regOThird) // i is in ALL of the first three, but NOT in ANY of the second or third three { for(int j=0;j<3;j++) for(int k=0;k<3;k++) if(iExamine-iExamine%3+j != iExamine) myBox[iExamine-iExamine%3+j][0+k].ruleOut(i+1); } else if (!regOFirst && regOSecond && !regOThird) { for(int j=0;j<3;j++) for(int k=0;k<3;k++) if(iExamine-iExamine%3+j != iExamine) myBox[iExamine-iExamine%3+j][3+k].ruleOut(i+1); } else if (!regOFirst && !regOSecond && regOThird) { for(int j=0;j<3;j++) for(int k=0;k<3;k++) if(iExamine-iExamine%3+j != iExamine) myBox[iExamine-iExamine%3+j][6+k].ruleOut(i+1); } } } else { boolean regOFirst, regOSecond, regOThird; for(int i=0;i<9;i++) { regOFirst = myBox[0][jExamine].numPossible[i] || myBox[1][jExamine].numPossible[i] || myBox[2][jExamine].numPossible[i]; regOSecond = myBox[3][jExamine].numPossible[i] || myBox[4][jExamine].numPossible[i] || myBox[5][jExamine].numPossible[i]; regOThird = myBox[6][jExamine].numPossible[i] || myBox[7][jExamine].numPossible[i] || myBox[8][jExamine].numPossible[i]; if (regOFirst && !regOSecond && !regOThird) { // i is in ALL of the first three, but NOT in ANY of the second or third three for(int j=0;j<3;j++) for(int k=0;k<3;k++) if(jExamine-jExamine%3+k != jExamine) myBox[0+j][jExamine-jExamine%3+k].ruleOut(i+1); } else if (!regOFirst && regOSecond && !regOThird) { for(int j=0;j<3;j++) for(int k=0;k<3;k++) if(jExamine-jExamine%3+k != jExamine) myBox[3+j][jExamine-jExamine%3+k].ruleOut(i+1); } else if (!regOFirst && !regOSecond && regOThird) { for(int j=0;j<3;j++) for(int k=0;k<3;k++) if(jExamine-jExamine%3+k != jExamine) myBox[6+j][jExamine-jExamine%3+k].ruleOut(i+1); } } } if (!solvePause) { if (iExamine < 9) iExamine++; else if (jExamine < 8) jExamine++; else { solveState = 2; iExamine = 0; jExamine = 0; } } } else if (solveState == 2) { //Draw examination box stroke(#FF0000); noFill(); rect(20+jExamine*40,20+iExamine*40,40,40); //ROW TWIN DETECTOR if (myBox[iExamine][jExamine].numPossibilities() == 2) for(int i=0;i<9;i++) { if (myBox[iExamine][i].numPossibilities() == 2 && i != jExamine) { int[] firstA = myBox[iExamine][jExamine].getPossibilities(); int[] secondA = myBox[iExamine][i].getPossibilities(); if(firstA[0] == secondA[0] && firstA[1] == secondA[1]) { for(int x=0;x<9;x++) { if(x!=i && x!=jExamine) { myBox[iExamine][x].ruleOut(firstA[0]+1); myBox[iExamine][x].ruleOut(firstA[1]+1); } } } } //COL TWIN DETECTOR else if (myBox[i][jExamine].numPossibilities() == 2 && i != iExamine) { int[] firstA = myBox[iExamine][jExamine].getPossibilities(); int[] secondA = myBox[i][jExamine].getPossibilities(); if(firstA[0] == secondA[0] && firstA[1] == secondA[1]) { for(int x=0;x<9;x++) { if(x!=i && x!=iExamine) { myBox[x][jExamine].ruleOut(firstA[0]+1); myBox[x][jExamine].ruleOut(firstA[1]+1); } } } } } //iterate examiners if(!solvePause) { if(jExamine < 8) jExamine++; else if (iExamine <8 && jExamine == 8) { iExamine++; jExamine = 0; } else if (iExamine == 8 && jExamine == 8) { if(!solvedOne) solveState=0; solvedOne = false; iExamine = 0; jExamine = 0; } } } } void mouseReleased() { if(mouseX > 20 && mouseX < 380 && mouseY > 20 && mouseY < 380) { jSelect = floor((mouseX-20.0)/40.0); iSelect = floor((mouseY-20.0)/40.0); } else { jSelect = -1; iSelect = -1; } //println("Row: " + iSelect + " - Col: " + jSelect); } void keyPressed() { //INPUT NUMBER TO SELECTED BOX int numPress = int(str(key)); if (iSelect != -1 && numPress < 10 && numPress > 0 && myBox[iSelect][jSelect].num ==-1) { myBox[iSelect][jSelect].setNum(numPress); killOthers(iSelect,jSelect,numPress); } //MISTAKE DELETER if(key == 'd' && myBox[iSelect][jSelect].num != -1) { myBox[iSelect][jSelect].num = -1; for(int i=0; i<9; i++) for (int j=0; j<9; j++) if (myBox[i][j].num == -1) { for (int x=0; x<9;x++) myBox[i][j].numPossible[x] = true; } else if(myBox[i][j].compSolved) { myBox[i][j].num = -1; myBox[iSelect][jSelect].compSolved = false; for (int x=0; x<9;x++) myBox[i][j].numPossible[x] = true; } for(int i=0; i<9; i++) for (int j=0; j<9; j++) if (myBox[i][j].num != -1) killOthers(i,j,myBox[i][j].num); /* for(int i=0; i<9; i++) { myBox[iSelect][jSelect].numPossible[i] = true; if (myBox[iSelect][i].num == -1) myBox[iSelect][i].numPossible[myBox[iSelect][jSelect].num-1] = true; if (myBox[i][jSelect].num == -1) myBox[i][jSelect].numPossible[myBox[iSelect][jSelect].num-1] = true; } // same 3x3 box int iBase = iSelect - iSelect%3; int jBase = jSelect - jSelect%3; for(int i=0;i<3;i++) for(int j=0;j<3;j++) if (myBox[iBase+i][jBase + j].num == -1) myBox[iBase+i][jBase + j].numPossible[myBox[iSelect][jSelect].num-1] = true; myBox[iSelect][jSelect].num = -1; */ } //MOVE SELECTOR BOX if (key==CODED && iSelect != -1) { if (keyCode == UP && iSelect > 0) iSelect--; else if (keyCode == DOWN && iSelect < 8) iSelect++; else if (keyCode == LEFT && jSelect > 0) jSelect--; else if (keyCode == RIGHT && jSelect < 8) jSelect++; } if (key == 'n') { myBox = new sBox[9][9]; for(int i=0;i < 9;i++) for(int j=0; j<9; j++) myBox[i][j] = new sBox(i,j); } else if (key == 'h') { if (highlight == 3) highlight = 0; else highlight++; } //SAVE else if (key == 's') { savedGame = new int[9][9]; for(int i=0;i<9;i++) for(int j=0;j<9;j++) savedGame[i][j] = myBox[i][j].num; } else if (key == 'r') { if(savedGame.length !=0) { for(int i=0; i<9; i++) for (int j=0; j<9; j++) for (int x=0; x<9;x++) { myBox[i][j].numPossible[x] = true; myBox[i][j].num = -1; } for(int i=0; i<9; i++) for (int j=0; j<9; j++) if(savedGame[i][j] !=-1) { myBox[i][j].setNum(savedGame[i][j]); killOthers(i,j,myBox[i][j].num); } } } else if (key == 'p') { if(isPaused) loop(); else noLoop(); isPaused = !isPaused; } else if (key == 'q') { solvePause = !solvePause; } }