My projects library #4! Gallery Megathread

#43 Sudoku UI V0

Solved


(Mid game)

Code
//sudoku | dictionary - grid - 9x9 | cell - 3x3 | slot - 1x1
int grid[][] = new int[9][9];
boolean locked[][] = new boolean[9][9];
boolean editing = false, editLocked=false, showMoves=false, showCovered=true;
int num = 9, moves = 0, sel =1;
float scl=64;
float scl2=128, p2x = 646, p2y = 115;
float scl3=96, p3x = 646, p3y = 19;
float scl4X=96,scl4Y=24, p4x=934,p4y=499;
String loadString = "873410900065028070020703000540000210208007490690080000480000500700031609010009807";
void setup() {
  size(1100, 576);
  textAlign(3, 3);
  textSize(scl*0.6);
  if(loadString.length()==81) loadBlueprint(loadString);
  
}
void draw() {
  background(0);
  if(showCovered) for(int i = 0; i < num; i++) for(int j = 0; j < num; j++) if(grid[i][j]==sel && sel!=0) showCovered(i,j);
  noFill(); 
  //stroke(255, 20);
  noStroke();
  textSize(scl*0.6);
  for (int i = 0; i < num; i++) for (int j = 0; j < num; j++) { //drawing the main grid
    fill(0,0,255,50);
    if(locked[i][j]) square(i*scl,j*scl,scl);
    fill(  ((grid[i][j]==sel)? color(255,0,55) : color(255) )   ); //all slots that match the selected number will be red-ish
    if (grid[i][j]!=0)text(grid[i][j], (i+0.5)*scl, (j+0.5)*scl);
  }
  stroke(255,40);
  for (int i = 1; i < 9; i++) line( i*scl, 0, i*scl, height); //drawing the stronger 3 lines
  for (int i = 1; i < 9; i++) line( 0, i*scl, height, i*scl);
  stroke(255);
  for (int i = 1; i < 4; i++) line( 3*i*scl, 0, 3*i*scl, height); //drawing the stronger 3 lines
  for (int i = 1; i < 3; i++) line( 0, 3*i*scl, height, 3*i*scl);
  //fill(255);
  textSize(scl2*0.6);
  noFill();
  for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) { //drawing the select button area
    square(p2x+scl2*i, p2y+scl2*j, scl2);
    fill( ((sel==i+j*3+1)? color(255) : color(255, 150)));
    text(i+j*3+1, p2x+scl2*(i+0.5), p2y+scl2*(j+0.5));
    noFill();
  }
  textSize(scl3*0.65); 
  for (int i = 0; i < 4; i+=((i==1)? 2 : 1)) { //displaying the 3 upper, smaller buttons
    noFill();
    square(p3x+i*scl3, p3y, scl3);
    fill( ( (i==0 && sel==0)? color(255) : ((i==1)? color(255, 150) : (i==3 && editing)? color(255) : color(255, 150))));
    text(   ( (i==0)? "x" :  ((i==1)? "○" : "LK")   ), p3x+(i+0.5)*scl3, p3y+scl3*0.4);
  }
  if(editing) { //displaying the SHOW MOVES/EDIT LOCKED/SHOW COVERED buttons
    textSize(scl4Y*0.5);
    for(int i = 0; i < 3; i++) {
      noFill();
      rect(p4x,p4y+i*scl4Y,scl4X,scl4Y);
      fill( (( i==0&&editLocked || i==1&&showMoves || i==2&&showCovered )? color(255) : color(255,150) ) );
      text( ((i==0)? "EDIT LOCKED" : ((i==1)? "SHOW MOVES" : "SHOW COVERED")),p4x+0.5*scl4X,p4y+(i+0.5)*scl4Y);
    }
  }
  
  fill(255);
  textSize(scl*0.6);
  if(showMoves==true) text("MOVES: "+moves, 838, 530);
}

void showCovered(int x, int y) {
  fill(0,200,40,20);
  noStroke();
  rect(0,y*scl,scl*num,scl);
  rect(x*scl,0,scl,scl*num);
  square( floor(x/3)*3*scl, floor(y/3)*3*scl, scl*3);
}

void mousePressed() {

  if (mouseButton==LEFT) {
    if (mouseX>p2x&&mouseY>p2y&&mouseX<p2x+3*scl2&&mouseY<p2y+3*scl2) { //number selection menu
      float mmx = mouseX-p2x, mmy = mouseY-p2y;
      sel = (int)(mmx/scl2+1)+ (int)(mmy/scl2)*3;
    }
    if (mouseX<scl*num) {//main grid - getting the mouse position and filling the slot
      int mx = constrain(floor(mouseX/scl),0,9), my = constrain(floor(mouseY/scl),0,9);
      if ((setSlot(mx, my, sel)==0)) grid[mx][my] = 0; //if the slot already has the number you selected, it will clear the slot
      if(locked[mx][my]==true && grid[mx][my] != 0) sel = grid[mx][my]; //if user clicks on a locked slot, selection will shift
    }
    if (mouseX>p3x&&mouseY>p3y&&mouseX<p3x+4*scl3&&mouseY<p3y+scl3) { //The top 4 buttons (id = 3)
      int mx = floor((mouseX-p3x)/scl3);
      if (mx==0) sel = 0;
      if (mx==1) for (int i = 0; i < num; i++) for (int j = 0; j < num; j++) if (grid[i][j]!=0&&locked[i][j]==false) grid[i][j]=0;
      if (mx==3) editing = !editing;
    }
    if(mouseX>p4x&&mouseY>p4y&&mouseX<p4x+scl4X&&mouseY<p4y+scl4Y*3) {
      int my = floor((mouseY-p4y)/scl4Y);
      if(my==0) editLocked = !editLocked;
      if(my==1) showMoves = !showMoves;
      if(my==2) showCovered = !showCovered;
    }
  } else if(mouseButton==RIGHT) {
    if (mouseX<scl*num && editing == true && editLocked) {//main grid - edit locked slots
      int mx = floor(mouseX/scl), my = floor(mouseY/scl);
      locked[mx][my] = !locked[mx][my];
    }
  }
}
void keyPressed() {
  if (keyCode>47&&keyCode<58) { //numbers 0-9
    int mx = floor(mouseX/scl), my = floor(mouseY/scl), nnum = keyCode-48;
    if(sel==nnum) if ((setSlot(mx, my, sel)==0)) grid[mx][my] = 0; //first time pressing the number will set the number as sel, second will input it
    sel=keyCode-48;
  }
}
int setSlot(int x, int y, int value) { //0 - slot matches the selection - will empty | 1 - success | 2 - slot is locked
  if (grid[x][y]==value) {
    println("slot is already filled with the same number!");
    return 0;
  }
  if (locked[x][y]==false||editing==true) {
    println("changing the slot!");
    moves++;
    grid[x][y] = value;
  } else { 
    println("FAILED-the slot is locked");
    return 2;
  }
  return 1;
}
void loadBlueprint(String blueprint) {
  if(blueprint.length()==81) {
    for(int i = 0; i < 81; i++) {
      int x = i%num, y = floor(i/num), number = int(blueprint.charAt(i)-48);
      grid[x][y]=number;
      locked[x][y]=(number!=0);
    }
  }
}
/* TODO: 
 add a feature to save up to 3 numbers per slot, so you can have help while saving it
 add a feature that shows the quantity of certain numbers next to number selector
*/

This is my 10th attempt at this. There were a lot of issues beforehand. I had to actually start playing sudoku myself for a week (both online and irl) to find out what neat features I should add. I am extremely proud of the result!

Features:

  • sudoku program
  • can edit board mid-game
  • can edit locked slots (enable while in LK mode and click EDIT LOCKED)
  • can show moves (can toggle in the LK menu)
  • can use green-guide feature - guide on placing numbers (look image 2 where there is a black slot in bottom left corner, that is the place to put number 2)
  • can load a board (format is selfexplanitory)
  • all of the numbers that are selected will become red-ish
  • locked slots cannot be edited without LK mode
  • locked slots are colored blue
  • can use mouse/keyboard as input/number selection
  • can clear the slot by pressing on it again with the same number selected
  • can press x button to enable clear-mode (clear slots instead of placing them with mouse)
  • can press O button to clear all non-locked slots
  • can press LK button to toggle LK mode (LK - Lock)
  • while in LK mode, a toggle menu will appear
  • while in LK mode press right-mouse-button to toggle locked slots

Issues:

  • there is a bug where you can delete a locked slot, not 100% sure about how to avoid it

Futurue versions will have:

  • several random boards of varying difficulty
  • can save up to 3 numbers per slot, to keep track of potential numbers
  • a feature that tells you the quantity of each number (so you know if they are full)
  • roboto (google) font
  • window to input a blueprint string
  • window to show you current blueprint
  • a way to check for errors on completion

If you find any other issues, or have any suggestions for future versions, do tell. Any and all opinions are welcome here. I know that the color pallette isn’t the most good looking, but I am no artist.

Enjoy!