My projects library #4! Gallery Megathread

Here are some of my projects! I hope you get some ideas/inspiration from it : P

There are 3 previous megathreads with 40 projects in total!

If you have any questions regarding the projects, use the #[project number] while referencing them!
Any suggestions/ideas are very welcome! Enjoy!

#41 - Quasi console V0
image

Code
import javax.swing.JOptionPane;
String pLines = "Welcome to quasi console!\n ";
void setup() {
  surface.setLocation(-width*2,-height*2);
  surface.setVisible(false);
  String strInp = JOptionPane.showInputDialog(null,pLines );
  pLines+="\n"+strInp;
}
void draw() {
  String strInp = JOptionPane.showInputDialog(null,pLines );
  pLines+="\n"+strInp;
  if(strInp.equals("stopConsole")) exit();
}
2 Likes

#42 - Quasi console V01
Changelog:

  • commands require “!” as first letter
  • commands are no longer case sensitive
  • added more commands
  • renamed command “stopConsole” to “!stop”
  • prevented crashing from null entries
  • added a confirmation after !stop
  • can exit program by pressing the “cancel” button or the “x” button
Code
import javax.swing.JOptionPane;
String pLines = "Welcome to quasi console!\n ";
int dialogButton = JOptionPane.YES_NO_OPTION;
void setup() {
  surface.setLocation(-width*2, -height*2);
  surface.setVisible(false);
}
void draw() {
  String strInp = getInput(0, pLines);
  if (strInp!=null) {
    println("User Input: "+strInp);
    pLines+=((pLines.length()==0)? "" : "\n")+strInp;
    if (strInp.charAt(0)=='!') executeCommand(strInp);
  } else exit();
}
String getInput(int windowType, String text) {
  if (windowType==0) {
    return JOptionPane.showInputDialog(null, text );
  }
  return "";
}
void executeCommand(String text) {
  println("identifying the command: " + text);
  String segments[] = split(text, " ");
  if (eic(text, "!stop")) if (JOptionPane.showConfirmDialog (null, "Do you want to exit Quasi Console?", "Warning", dialogButton)==dialogButton) exit();
  if (eic(text, "!clearConsole")) pLines="";
  //###################COMMANDS RELATED TO TIME
  if (eic(text, "!time")) pLines+="\nCONSOLE: current time is: " + nf(hour(), 2)+":"+nf(minute(), 2)+":"+nf(second(), 2);
  if (eic(text, "!date")) pLines+="\nCONSOLE: (D/M/Y) current date is: " + day()+". "+month()+". "+year();
  //###################COMMANDS RELATED TO CANVAS
  if (segments.length>2) if (eic(segments[0], "!window")) {
    if (eic(segments[1], "show")) { //######COMMANDS RELATED TO DISPLAYING CANVAS
      if (eic(segments[2], "true")) {
        surface.setVisible(true); 
        surface.setLocation(0, 0);
      } else if (eic(segments[2], "false")) {
        surface.setVisible(false); 
        surface.setLocation(-width*2, -height*2);
      }// else if(eic(segments[2], "check")) pLines+="\nCONSOLE: window visible: " + "unknown";
    }
  }
}
boolean eic(String s1, String s2) {
  return(s1.equalsIgnoreCase(s2));
}

1 Like

#42 Circular pattern

Code
//This code is hideous, it is just a mess of trigenometry : P
int n = 40;
void setup() {
  size(600, 600);
}
void draw() {
  background(0);
  stroke(255, 100);
  float sqrt2 = sqrt(2), r = width*0.4;
  for (int i = 0; i < 4; i++) {
    displaySquare( i, 20, 300, 300, r);
    displaySquare( i-2, 20, 300+cos(HALF_PI*(i+0.5))*r*sqrt2, 300+sin(HALF_PI*(i+0.5))*r*sqrt2, r);
    displaySquare( i+2, 20, 300+cos(HALF_PI*i)*r, 300+sin(HALF_PI*i)*r, r);
    displaySquare( i+1, 20, 300+cos(HALF_PI*i)*r, 300+sin(HALF_PI*i)*r, r);
  }
}
void displaySquare(float d, int n, float cx, float cy, float r) {
  float r2 = r*sqrt(2);
  translate(cx, cy);
  PVector p1 = new PVector(cos((d+1)*HALF_PI)*r, sin((d+1)*HALF_PI)*r);
  PVector p0 = new PVector(cos((d+0.5)*HALF_PI)*r2, sin((d+0.5)*HALF_PI)*r2);
  PVector p2 = new PVector(cos((d)*HALF_PI)*r, sin((d)*HALF_PI)*r);
  line(p1.x, p1.y, p0.x, p0.y);
  line(p2.x, p2.y, p0.x, p0.y);
  for (float i = 0; i < n; i++) {
    float lp = i/n;
    line( lerp(p0.x, p1.x, lp), lerp(p0.y, p1.y, lp), lerp(p0.x, p2.x, 1-lp), lerp(p0.y, p2.y, 1-lp));
  }
  translate(-cx, -cy);
}

1 Like

#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!

#44 Sudoku V1

Code
//sudoku | dictionary - grid - 9x9 | cell - 3x3 | slot - 1x1
import javax.swing.JOptionPane;
int grid[][] = new int[9][9];
int saved[][][] = new int[9][9][3];
boolean locked[][] = new boolean[9][9];
boolean editing = false, editLocked=false, showMoves=false, showCovered=true, showNotes=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=18, p4x=934, p4y=499;
float scl5X=21.333, scl5Y=16;
float p6x = 934-3*scl4X, p6y=499, scl6X=96, scl6Y=24;
PFont roboto;
String loadString = "873410900065028070020703000540000210208007490690080000480000500700031609010009807";
//EASY:              873410900065028070020703000540000210208007490690080000480000500700031609010009807
//MEDIUM:            730095000600030709200000300068704190000000860000000004900108400051900270000050080
//HARD:              080200009000300006960070001000000000090700200040001008070400500004030800306000000
void setup() {
  roboto = createFont("Roboto-Light.ttf", 70);
  textFont(roboto);
  size(1100, 576);
  textAlign(3, 3);
  textSize(scl*0.6);
  if (loadString.length()==81) loadBlueprint(loadString);
  //for (int i = 0; i < 100; i++) saved[(int)random(9)][(int)random(9)][(int)random(3)]= (int)random(9);
}
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();
  for (int i = 0; i < num; i++) for (int j = 0; j < num; j++) { //drawing the main grid
    textSize(scl*0.6);
    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);
    textSize(scl5Y*0.9);
    if (showNotes&&locked[i][j] == false) for (int k = 0; k < 3; k++) {
      fill( ((saved[i][j][k]==sel)? color(255, 0, 55) : color(255) ));
      if (saved[i][j][k]!=0) text( saved[i][j][k], i*scl+(k+0.5)*scl5X, j*scl+0.5*scl5Y );
    }
  }
  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)? "Ж" :  ((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.65);
    for (int i = 0; i < 4; i++) { //CHANGED TO 4
      noFill();
      rect(p4x, p4y+i*scl4Y, scl4X, scl4Y);
      fill( (( i==0&&editLocked || i==1&&showMoves || i==2&&showCovered || i==3&&showNotes)? color(255) : color(255, 150) ) );
      text( ((i==0)? "EDIT LOCKED" : ((i==1)? "SHOW MOVES" : ((i==2)?"SHOW COVERED":"SHOW NOTES"))), p4x+0.5*scl4X, p4y+(i+0.5)*scl4Y);
    }
    //LOAD/SAVE BUTTONS
    noFill();
    textSize(scl6Y*0.5);
    for (int i = 0; i < 2; i++) {
      rect(p6x, p6y+scl6Y*i, scl6X, scl6Y);
      text( ((i==0)? "LOAD BLUEPRINT" : "SAVE BLUEPRINT" ), p6x+scl6X*0.5, p6y+scl6Y*(i+0.5));
    }
  }

  fill(255);
  textSize(scl*0.6);
  if (showMoves==true && !editing) 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 && JOptionPane.showConfirmDialog (null, "Do you want to clear the board?", "Confirm", JOptionPane.YES_NO_OPTION)==JOptionPane.YES_NO_OPTION) {
        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;
          for (int k = 0; k < 3; k++) saved[i][j][k]=0;
        }
        moves=0;
      }
      if (mx==3) editing = !editing;
    }
    if (mouseX>p4x&&mouseY>p4y&&mouseX<p4x+scl4X&&mouseY<p4y+scl4Y*4) {
      int my = floor((mouseY-p4y)/scl4Y);
      if (my==0) editLocked = !editLocked;
      if (my==1) showMoves = !showMoves;
      if (my==2) showCovered = !showCovered;
      if (my==3) showNotes=!showNotes;
    }
    
    if(mouseX>p6x&&mouseY>p6y&&mouseX<p6x+scl6X&&mouseY<p6y+scl6Y*2) {
      int my = floor((mouseY-p6y)/scl6Y);
      if(my==0) loadBlueprint( JOptionPane.showInputDialog(null, "ENTER BLUEPRINT" ) );
      if(my==1) saveBlueprint();
    }
    
  } 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];
    }
    if (mouseX<scl*num) {
      int mx = constrain(floor(mouseX/scl), 0, 9), my = constrain(floor(mouseY/scl), 0, 9);
      if (showNotes==true) {
        int mx2 = floor(map(mouseX-mx*scl, 0, scl, 0, 3));
        saved[mx][my][mx2] = ((saved[mx][my][mx2]==sel)? 0 : sel);
      }
    }
  }
}
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 && (!locked[x][y]||editing)) {
    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);
      for(int k = 0; k < 3; k++) saved[x][y][k]=0;
    }
  }
}
String saveBlueprint() {
  String output="";
  for (int j = 0; j < num; j++) for (int i = 0; i < num; i++) output+=grid[i][j];
  println("Blueprint:"+output);
  JOptionPane.showMessageDialog(frame, "Current blueprint: [Available in console]\n"+output);
  return output;
}
void mouseWheel(MouseEvent event) {
  int e = event.getCount();
  sel= (sel-e)%(num+1);
  if(sel<0) sel = num;
  println(e,sel);
}
/* TODO: 
 the error checker will store the quantity of numbers instead of just if they are there.
 Add a LOAD/SAVE | Will be replaced with the BLUEPRINT button. It will make a popup, where it will ask you what you want
 so 1) SAVE 2) LOAD -> next menu, choose difficulty (1:easy,2:medium,3:hard)-> there are x blueprints of [difficulty], choose a number, -1 for random
 
 load/save prompt should show up if clicked  
 NEW CONTENT:
 - can save up to 3 numbers per slot with right click
 - roboto light font
 - confirmation before board erasure
 - can save/load blueprints mid game
 - scroll mouse wheel to change selection
 */

FEATURES:

  • can save up to 3 numbers per slot with right click
  • font changed to roboto light (if you have it in the data folder, I can’t share it with code)
  • popup window appears before you can erase the board
  • can save/load blueprints mid game
  • can use mouse wheel to change selection
  • moves are not shown while in LK mode
  • erasing the board now resets moves counter
  • retextured ERASER and CLEAR buttons

BUGFIXES:

  • BUG#0001 - double clicking on a locked slot will clear it even while not in LK mode

#45 Mastermind puzzle game

Code
int tries = 12, len = 4, clrs = 6, attempts = 0, sel = 1;
int grid[][] = new int[tries][len]; //[x][] - vertical | [][x] - horizontal
float scl = 48;
color colors[] = new color[clrs+1]; //0 - transparent, 1-6 (default) are colored
String result[] = new String[tries]; //shows O or X or ////
float p2x = 352, p2y=0, p2W = scl, p2maxH = tries*scl; //color picker
float p3x = 328, p3y = 0, p3W = 24, p3H=p2maxH; //confirm vertical bar (only useful if line is full)
boolean showPassword=false; //show password at the start of the game (testing)
boolean ended = false;
int password[] = new int[len]; //password
void setup() {
  size(400, 640);
  textAlign(LEFT, CENTER);
  textSize(scl*0.6);
  colorMode(HSB);
  colors[0] = color(0);
  for (int i = 1; i < colors.length; i++) colors[i] = color(map(i, 1, colors.length, 0, 255), 255, 255); //saving bright color values
  password = generateUniquePassword(len, clrs); //generate a code, where there is max 1 of each number, (4423 is not vaild)
}
void draw() {
  background(0);
  for (int j = 0; j < tries; j++) { //draw the grid
    if (attempts==j) { //highlight the active row
      noStroke();
      fill(255, 50);
      rect(0, j*scl, len*scl+2, scl);
    }
    for (int i = 0; i < len; i++) {
      stroke(255, 60);
      noFill();
      square((i)*scl, (j)*scl, scl);
      fill( colors[grid[j][i]]);
      if (j<=attempts && grid[j][i] != 0) circle( (i+0.5)*scl, (j+0.5)*scl, scl*0.8); //display circles into squares
    }
    if (result[j] != null) displayText(result[j]+"", (len+0.1)*scl, (j+0.5)*scl, color(255)); //display XOXX
  }
  stroke(255);
  for (int i = 0; i < len; i++) { //display the bottom line with solution
    noFill();
    square(i*scl, height-scl-1, scl);
    fill( colors[password[i]] );
    if (showPassword || ended) circle( (i+0.5)*scl, height-scl*0.5-1, scl*0.8); //show solution if game ended/showPassword==true
  } //(next line) show number of attempts used
  displayText(((!ended)?"ATTEMPTS:"+attempts:((attempts<tries)?"WON!!! A: "+attempts : "LOST")),(len+0.1)*scl,height-scl*0.5,color(255));
  stroke(0);//displaying color picker
  for (int i = 1; i <= clrs; i++) {
    fill(colors[i], ((i==sel)? 255 : 50));
    rect(p2x, p2y+p2maxH/clrs*(i-1), p2W, p2maxH/clrs);
  }
  //displaying the confirm bar | (next line) change colors based on user action, blank/hover/hover&mousePressed
  fill(255, ((  (mouseX>p3x&&mouseY>p3y&&mouseX<p3x+p3W&&mouseY<p3y+p3H)? ((mousePressed)? 255 : 150) : 50  ))  );
  rect(p3x, p3y, p3W, p3H);
  
  if(ended) noLoop();
}
void displayText(String txt, float x, float y, color clr) {
  fill(clr);
  text(txt, x, y);
}
void mousePressed() {
  if (mouseX>p2x && mouseX<p2x+p2W && mouseY>p2y && mouseY<p2y+p2maxH) { //color picker
    float my = mouseY-p2y;
    int myy = (int)(my/(p2maxH/clrs));
    sel = myy+1;
  }
  if (mouseX>0&&mouseX<len*scl&&mouseY>0+attempts*scl&&mouseY<0+(attempts+1)*scl) { //active input (highlighted line)
    int mmx = mouseX-0;
    int mx = (int)(mmx/scl);
    println(mx);
    grid[attempts][mx]=sel;
  }
  if (mouseX>p3x&&mouseY>p3y&&mouseX<p3x+p3W&&mouseY<p3x+p3H) { //confirm bar hitbox
    boolean filled = true;
    for (int i = 0; i < len; i++) if (grid[attempts][i]==0) filled=false;
    if (filled) { //checks if all slots have been filled
      if (check(grid[attempts], password)) { //checks for perfect match
        println("YOU WIN!");
        ended = true;
      } else attempts++;
      if (attempts>=tries) { //out of tries
        println("YOU LOSE");
        ended = true;
      }
    }
  }
}
boolean check(int input[], int pass[]) {
  int res[] = new int[len]; //result, basically stores the things from password that are already used
  int correct = 0, halfCorrect=0;
  for (int i = 0; i < len; i++) if (input[i] == pass[i]) {
    res[i] = 2; //correct - 2 | HALFcorrect - 1
    correct ++;
  }
  for (int i = 0; i < len; i++) for (int j = 0; j < len||j==-1; j++) { //i is from guess, j is from password
    if (res[j]==0 && i!=j) { //searching for HALFcorrect numbers
      if (input[i]==pass[j]) {
        halfCorrect++;
        res[j]=1;
        j=-1;
      }
    }
  }
  result[attempts]=modifyFormat(correct, halfCorrect);
  return(correct==len);
}
String modifyFormat(int cor, int hCor) { //modifying format of outut to n*O+m*X OR ////
  String output = "";
  for (int i = 0; i < cor; i++) output+="O";
  for (int i = 0; i < hCor; i++) output+="X";
  if (cor==0 && hCor == 0) output = "////";
  return output;
}
int[] generateUniquePassword(int len, int cs) { //length of the password & colors in password
  int newPass[] = new int[len];
  ArrayList<Integer> available = new ArrayList<Integer>();
  for (int i = 1; i <= cs; i++) available.add(i); 
  for (int i = 0; i < len; i++) {
    int rndNum = (int)random(available.size());
    newPass[i]=available.get(rndNum);
    available.remove(rndNum);
  }
  return newPass;
}
Version 2
int tries = 12, len = 4, clrs = 6, attempts = 0, sel = 1;
int grid[][] = new int[tries][len]; //[x][] - vertical | [][x] - horizontal
float scl = 48;
color colors[] = new color[clrs+1]; //0 - transparent, 1-6 (default) are colored
String result[] = new String[tries]; //shows O or X or ////
float p2x = 352, p2y=0, p2W = scl, p2maxH = tries*scl; //color picker
float p3x = 328, p3y = 0, p3W = 24, p3H=p2maxH; //confirm vertical bar (only useful if line is full)
boolean showPassword=false; //show password at the start of the game (testing)
boolean ended = false;
int password[] = new int[len]; //password
void setup() {
  size(400, 640);
  textAlign(LEFT, CENTER);
  textSize(scl*0.6);
  colorMode(HSB);
  colors[0] = color(0);
  for (int i = 1; i < colors.length; i++) colors[i] = color(map(i, 1, colors.length, 0, 255), 255, 255); //saving bright color values
  password = generateUniquePassword(len, clrs); //generate a code, where there is max 1 of each number, (4423 is not vaild)
}
void draw() {
  background(0);
  for (int j = 0; j < tries; j++) { //draw the grid
    if (attempts==j) { //highlight the active row
      noStroke();
      fill(255, 50);
      rect(0, j*scl, len*scl+2, scl);
    }
    for (int i = 0; i < len; i++) {
      stroke(255, 60);
      noFill();
      square((i)*scl, (j)*scl, scl);
      fill( colors[grid[j][i]]);
      if (j<=attempts && grid[j][i] != 0) circle( (i+0.5)*scl, (j+0.5)*scl, scl*0.8); //display circles into squares
    }
    if (result[j] != null) displayText(result[j]+"", (len+0.1)*scl, (j+0.5)*scl, color(255)); //display XOXX
  }
  stroke(255);
  for (int i = 0; i < len; i++) { //display the bottom line with solution
    noFill();
    square(i*scl, height-scl-1, scl);
    fill( colors[password[i]] );
    if (showPassword || ended) circle( (i+0.5)*scl, height-scl*0.5-1, scl*0.8); //show solution if game ended/showPassword==true
  } //(next line) show number of attempts used
  displayText(((!ended)?"ATTEMPTS:"+attempts:((attempts<tries)?"WON!!! A:"+attempts : "LOST")),(len+0.1)*scl,height-scl*0.5,color(255));
  stroke(0);//displaying color picker
  for (int i = 1; i <= clrs; i++) {
    fill(colors[i], ((i==sel)? 255 : 50));
    rect(p2x, p2y+p2maxH/clrs*(i-1), p2W, p2maxH/clrs);
  }
  //displaying the confirm bar | (next line) change colors based on user action, blank/hover/hover&mousePressed
  fill(255, ((  (mouseX>p3x&&mouseY>p3y&&mouseX<p3x+p3W&&mouseY<p3y+p3H)? ((mousePressed)? 255 : 150) : 50  ))  );
  rect(p3x, p3y, p3W, p3H);
  
  if(ended) noLoop();
}
void displayText(String txt, float x, float y, color clr) {
  fill(clr);
  text(txt, x, y);
}
void mousePressed() {
  if (mouseX>p2x && mouseX<p2x+p2W && mouseY>p2y && mouseY<p2y+p2maxH) { //color picker
    float my = mouseY-p2y;
    int myy = (int)(my/(p2maxH/clrs));
    sel = myy+1;
  }
  if (mouseX>0&&mouseX<len*scl&&mouseY>0+attempts*scl&&mouseY<0+(attempts+1)*scl) { //active input (highlighted line)
    int mmx = mouseX-0;
    int mx = (int)(mmx/scl);
    println(mx);
    grid[attempts][mx]=sel;
  }
  if (mouseX>p3x&&mouseY>p3y&&mouseX<p3x+p3W&&mouseY<p3x+p3H) { //confirm bar hitbox
    boolean filled = true;
    for (int i = 0; i < len; i++) if (grid[attempts][i]==0) filled=false;
    if (filled) { //checks if all slots have been filled
      if (check(grid[attempts], password)) { //checks for perfect match
        println("YOU WIN!");
        ended = true;
      } else attempts++;
      if (attempts>=tries) { //out of tries
        println("YOU LOSE");
        ended = true;
      }
    }
  }
}
boolean check(int input[], int pass[]) {
  int res[] = new int[len]; //result, basically stores the things from password that are already used
  int correct = 0, halfCorrect=0;
  for (int i = 0; i < len; i++) if (input[i] == pass[i]) {
    res[i] = 2; //correct - 2 | HALFcorrect - 1
    correct ++;
  }
  for (int i = 0; i < len; i++) for (int j = 0; j < len||j==-1; j++) { //i is from guess, j is from password
    if (res[j]==0 && i!=j) { //searching for HALFcorrect numbers
      if (input[i]==pass[j]) {
        halfCorrect++;
        res[j]=1;
        j=-1;
      }
    }
  }
  result[attempts]=modifyFormat(correct, halfCorrect);
  return(correct==len);
}
String modifyFormat(int cor, int hCor) { //modifying format of outut to n*O+m*X OR ////
  String output = "";
  for (int i = 0; i < cor; i++) output+="O";
  for (int i = 0; i < hCor; i++) output+="X";
  if (cor==0 && hCor == 0) output = "////";
  return output;
}
int[] generateUniquePassword(int len, int cs) { //length of the password & colors in password
  int newPass[] = new int[len];
  ArrayList<Integer> available = new ArrayList<Integer>();
  for (int i = 1; i <= cs; i++) available.add(i); 
  for (int i = 0; i < len; i++) {
    int rndNum = (int)random(available.size());
    newPass[i]=available.get(rndNum);
    available.remove(rndNum);
  }
  return newPass;
}
void keyPressed() {
  if (keyCode>47&&keyCode<49+clrs) {
    sel = constrain(1,keyCode-48,clrs-1);
  }
}
void mouseWheel(MouseEvent event) {
  int e = -event.getCount();
  sel= (sel-e)%(clrs);
  if(sel<1) sel = clrs;
  println(e,sel);
}
1 Like

#46 Simple Mine-Sweeper


(Won, Playing, Lost)

Code
int a = 10; //width and height of grid
int grid[][] = new int[a][a];
int scl = 600/a, m = 10;
boolean show[][] = new boolean[a][a];
boolean flagged[][] = new boolean[a][a];
int RESULT = 0; //-1: lost 0: undecided 1: won
void setup() {
  size(600, 600);
  grid = newGrid(a, m);
  textAlign(3, 3);
  textSize(scl*0.6);
}
void draw() {
  background(0);
  stroke(255, 50);
  for (int i = 1; i < a; i++) {
    line( i*scl, 0, i*scl, height);
    line( 0, i*scl, width, i*scl);
  }
  for (int i = 0; i < a; i++) for (int j = 0; j < a; j++) {
    if (show[i][j]||RESULT==1) {
      fill(100);
      square(i*scl, j*scl, scl);
      fill(255);
      if (grid[i][j] > 0) text(grid[i][j], (i+0.5)*scl, (j+0.5)*scl);
      else if(grid[i][j]==-1) drawMine(i,j);
    } else {
      if (mouseX>i*scl&&mouseY>j*scl&&mouseX<(i+1)*scl&&mouseY<(j+1)*scl) {
        fill(200);
      } else fill(0);
      square(i*scl, j*scl, scl);
      if (flagged[i][j]) {
        fill(0, 0, 255, 50);
        square(i*scl, j*scl, scl);
      }
    }
    if(RESULT==-1 && grid[i][j]==-1) drawMine(i,j);
  }
  if(RESULT!=0) {
    textSize(100+sin(frameCount*0.05)*scl*0.25);
    if(RESULT==1) {
      //sin -1 1
      //+1= 0 2
      // *0.5 = 0 1
      fill(20,255,20,map( sin(frameCount*0.05), -1,1, 100,255));
      text("YOU WIN!!",width*0.5,height*0.5);
    } else if(RESULT==-1) {
      fill(255,20,20,map( sin(frameCount*0.05), -1,1, 100,255));
      text("YOU LOSE!!",width*0.5,height*0.5);
    }
    textSize(scl*0.6);
  }
}
void drawMine(int x, int y) {
  fill(255,0,0,150);
  circle((x+0.5)*scl,(y+0.5)*scl,scl*0.5);
}

void mousePressed() {
  int mx = mouseX/scl, my = mouseY/scl;
  if (mouseButton==LEFT) {
    if (flagged[mx][my]==false) checkSlot(mx, my);
  } else if (mouseButton==RIGHT && RESULT==0) flagged[mx][my] = !flagged[mx][my];
}
void keyPressed() {
  if(key==' ') println(checkWin());
}
void checkSlot(int x, int y) {
  if (grid[x][y]==-1) {
    println("GAME OVER");
    RESULT=-1;
  } else if (RESULT==0) {
    show[x][y]=true;
    while (spreadVisible(x, y)>0);
    if (checkWin()) {
      RESULT=1;
      println("YOU WIN!");
    }
  }
}
int spreadVisible(int x, int y) {
  int num = 0;
  for (int i = 0; i < a; i++) for (int j = 0; j < a; j++) {
    if (grid[i][j]==0||i==x&&j==y) {
      for (int k = -1; k < 2; k++) for (int l = -1; l < 2; l++) if (inBounds(i, j, k, l, a)) {
        if (grid[i+k][j+l]!=-1) show[i+k][j+l]=true;
      }
    }
  }
  return num;
}
int[][] newGrid (int na, int nm) {
  int ngrid[][] = new int[na][na];
  if (nm>=na*na) nm = na*na-1; //to prevent infinite loops, the higher the mine:area ratio the longer it takes
  for (int i = 0, rx = (int)random(na), ry = (int)random(na); i < nm; i++, rx = (int)random(na), ry =(int)random(na)) {
    while (!canPlace(ngrid, rx, ry, 0)) {
      rx = (int)random(na); 
      ry = (int)random(na);
    }
    ngrid[rx][ry]=-1;
  }
  for (int i = 0; i < na; i++) for (int j = 0; j < na; j++) if (ngrid[i][j]!=-1) {
    int num = 0;
    for (int k = -1; k < 2; k++) for (int l = -1; l < 2; l++) if (!(k==0&&l==0) && inBounds(i, j, k, l, a)) {
      if (ngrid[i+k][j+l]==-1) num ++;
    }
    ngrid[i][j] = num;
  }
  a = na;
  m = nm;
  return ngrid;
}
boolean inBounds(int x, int y, int px, int py, int w) {
  return(x+px<w&&y+py<w&&x+px>=0&&y+py>=0);
}
boolean canPlace(int mgrid[][], int x, int y, int desired) {
  return(mgrid[x][y]==desired);
}
boolean checkWin() {
  boolean won = true; //first set it to true
  for (int i = 0; i < a; i++) for (int j = 0; j < a; j++) {
    if (!(show[i][j]==true&&grid[i][j]>=0 || show[i][j]==false&&grid[i][j]==-1)) won = false;
  }
  return won;
}

Notable features:

  • flexible grid size and amount of mines
  • flag slots to mark potential mines (cannot uncover unless you unflag)

A game I completed with 20x20 grid & 40 mines.

#47 3n+1 sequence
Outputs it format: [sum] [highest number] [sequence…] […] […] [1]

Code
void setup() {
  printArray(path(1001));
  exit();
}
long[] path(long start) { //0 - sum 1 - max
  ArrayList<Long> values = new ArrayList<Long>();
  long num = start, sum = 0, maxNum=0;
  while(num!=1) {
    if(num%2==0) num*=0.5;
    else num=num*3+1;
    values.add(num);
    sum+=num;
    if(num>maxNum) maxNum=num;
  }
  long output[] = {sum,maxNum};
  output = expand(output,values.size()+2);
  for(int i = 0; i < values.size(); i++) output[i+2]=values.get(i);
  return output;
}

EDIT: there are 3 issues:
1st: the entered number will not show up , so with path(1) you will get the output [0] [0] instead of [1] [1] [1]
2nd: if you enter 0 you will never get the result out
3rd: negative numbers enter an infinite loop. To stop this, just add in the while condition:

EDIT 2:
Version without the above issues (But it is slightly slower)

Version 2
void setup() {
  printArray(path(16));
  exit();
}
long[] path(long start) { //0 - sum 1 - max
  ArrayList<Long> values = new ArrayList<Long>();
  long num = start, sum = 0, maxNum=0;
  values.add(num);
  while(num!=1&&!values.contains(num)) {
    if(num%2==0) num*=0.5;
    else num=num*3+1;
    values.add(num);
    sum+=num;
    if(num>maxNum) maxNum=num;
    println(num);
  }
  long output[] = {sum,maxNum};
  output = expand(output,values.size()+2);
  for(int i = 0; i < values.size(); i++) output[i+2]=values.get(i);
  return output;
}

nice work keep on :wink: :wink: :wink:

1 Like

#48 String sum
Description: can add two integers (in string form) allowing you to have far larger range. Negative numbers are not supported.

The code contains a fibonacci example and limits allowing you to get the 1000 digit number (4781th value in sequence).

Code
String stringSum(String n1, String n2) {
  String output="";
  while(n1.length()!=n2.length()) {
    if(n1.length()>n2.length()) {
      n2 = "0"+n2;
    } else if(n2.length()>n1.length()) {
      n1 = "0"+n1;
    }
  }
  int rem = 0;
  for(int i = n1.length()-1; i >= 0; i--) {
    int sum = n1.charAt(i)+n2.charAt(i)-96+rem;
    rem=0;
    String abc = sum+"";
    output = abc.charAt(abc.length()-1)+output;
    if(abc.length()==2) rem = int(abc.charAt( abc.length()-2 ))-48;
  }
  if(rem>0)output = rem + output;
  return output;
}
void setup() {
  String a = "0";
  String b = "1";
  String c = "1";
  for(int i = 0; i < 4783; i++) {
    c = stringSum(a,b);
    a = b;
    b = c;
    println("["+i+"] L:",a.length(),"NEXT:\n"+a); //using a instead of c so it is aligned with the challenge
  }
}

#49 Wolfram cellular automata
Edges - looped

Code
//wolfram - by timbebender
ArrayList<int[]> grid = new ArrayList<int[]>();
int w = 330, h = 1000, scl = 660/w;
boolean rules[] = new boolean[8];
void setup() {
  size(660, 600);
  genRule();
}
void mousePressed() { 
  genRule();
}
void genRule() {
  grid.clear();
  int startW[] = new int[w];
  startW[floor(w*0.5)] = 1;

  for (int i = 0; i < rules.length; i++) rules[i] = (random(1)>0.5);
  int v = 0;
  for (int i = 0, m = 128; i < 8; i++, m*=0.5) v+=m*((rules[i])? 1 : 0);
  println(v);

  grid.add(startW);
}

void draw() {
  background(0); 
  noStroke();
  for (int j = 0; j < grid.size(); j++) {
    for (int i = 0; i < grid.get(j).length; i++) {
      fill( ((grid.get(j)[i]!=0)? color(255) : color(0) ) );
      square(i*scl, j*scl, scl);
    }
  }
  if (grid.size()*scl<height) {
    grid.add(generate(grid.get(grid.size()-1), rules));
  }
}
int[] generate(int[] prev, boolean[] ruls) {
  int next[] = new int[prev.length];
  next[0] = checkrule(prev[prev.length-1], prev[0], prev[1], ruls);
  next[next.length-1] = checkrule(prev[prev.length-2], prev[prev.length-1], prev[0], ruls); //ENDGES WRAP ARROUND
  for (int i = 1; i < next.length-1; i++) {
    next[i] = checkrule(prev[i-1], prev[i], prev[i+1], ruls);
  }
  return next;
}
int checkrule(int l, int c, int r, boolean[] ruls) {
  int combine = l*4+c*2+r;
  return 1*((ruls[combine])? 1 : 0);
}

#50 Mutated Wolfram cellular automata
(Mutated or modified, whichever : P)
The difference is that it doesn’t have rules for: [left cell, this cell, right cell] but also the 3 cells above them, so it generates the next row based on the previous two. It has 64 different rules (2^6), resulting in 2^64 different combination.

Code
int w = 600, h=600, gens=1;
int grid[][] = new int[h][w];
int rules[] = new int[64]; //2^6 = 64
boolean loop = true;
void setup() {
  size(600, 600);
  genBoard();
}
void draw() {
  background(0);
  loadPixels();
  for (int j = 0; j < gens; j++) for (int i = 0; i < w; i++) {
    int index = i+j*width;
    color clr = ((grid[j][i]==1)? color(255) : color(0) );
    pixels[index] = clr;
  }
  updatePixels();
  if (gens<h-1) {
    grid[gens] = generate(grid[gens-1], grid[gens], rules);
    gens++;
  }
}
void genBoard() {
  grid = new int[h][w];
  for (int i = 0; i < rules.length; i++) rules[i] = round(random(1));
  grid[0] = new int[w];
  grid[1] = new int[w];
  grid[1][300] = 1;
  gens=1;
}
int[] generate(int[] pp, int[] p, int[] rls) {
  int next[] = new int[w];
  if(!loop) for (int i = 1; i < w-1; i++) next[i] = checkRule(pp[i-1], pp[i], pp[i+1], p[i-1], p[i], p[i+1], rls);
  if(loop) for(int i = 0; i < w; i++) next[i] = checkRule(pp[((i-1>0)? i-1 : w-1)], pp[i], pp[(i+1)%w], p[((i-1>0)? i-1 : w-1)], p[i], p[(i+1)%w], rls);
  return next;
}
int checkRule(int pl, int pc, int pr, int cl, int cc, int cr, int[] rls) {
  int v = pl+pc*2+pr*4+cl*8+cc*16+cr*32;
  return rls[v];
}
void mousePressed() {
  genBoard();
}

Looping around the edges can be disabled.
If you press the mouse, another pattern will be generated

#51 Simple pong game

Code
int w = 400, h = 400;
int scoreA = 0, scoreB = 0; //LEFT - A, RIGHT - B
float speed=5, barSpeed=3, ballS = 20, ballX = w, ballY = h*0.5, xS = ((random(1)>=0.5)? 1 : -1), yS = ((random(1)>=0.5)? 1 : -1) * random(1,0.7);
float barX=0.1, barH = 32, barA = h*0.5, barB = h*0.5;
int mA = 0, mB = 0;
void keyPressed() {
  if (keyCode==UP) mB=-1;
  if (keyCode==DOWN) mB=1;
  if (key=='w') mA=-1;
  else if (key=='s') mA=1;
}
void keyReleased() {
  if (mB==-1 && keyCode==UP ||mB==1 && keyCode==DOWN) mB=0;
  if (mA==-1 && key=='w' ||mA==1 && key=='s') mA=0;
}


void setup() {
  size(800, 400);
  textSize(50);
}
void draw() {
  background(0);
  stroke(255);
  fill(255);
  line(w, 0, w, height);
  float sw1 = textWidth(scoreA+"");
  text(scoreA, w-sw1-5, textAscent());
  text(scoreB, w+5, textAscent());

  //bar movements
  barA=constrain(barA+mA*barSpeed, barH, h-barH);
  barB=constrain(barB+mB*barSpeed, barH, h-barH);
  line( w*barX, barA-barH, w*barX, barA+barH);
  line( w*(2-barX), barB-barH, w*(2-barX), barB+barH);


  //puck movement
  ballX+=speed*xS;
  ballY+=speed*yS;
  if (ballY>h-ballS*0.5||ballY<ballS*0.5) { //puck bounce of walls
    ballY = ((ballY>h*0.5)? h-ballS*0.5 : ballS*0.5 );
    yS*=-1;
  }
  //puck deflection
  if (ballX>(2-barX)*w-ballS*0.5&&ballX<(2-barX)*w+ballS*0.5 && ballY>barB-barH-ballS*0.5&&ballY<barB+barH+ballS*0.5) {
    ballX=(2-barX)*w-ballS*0.5;
    xS*=-1;
  }
  if (ballX>barX*w-ballS*0.5&&ballX<(barX)*w+ballS*0.5) {
    ballX=(barX)*w+ballS*0.5;
    xS*=-1;
  }

  //drawing the puck
  square(ballX-ballS*0.5, ballY-ballS*0.5, ballS);
  //scoring system
  if (ballX>w*2) scoreA++;
  if (ballX<0) scoreB++;
  else if (ballX<-ballS) scoreB++;
  if (ballX>w*2||ballX<0) {
    ballX=w;
    ballY=h*0.5;
    xS=((random(1)>=0.5)? 1 : -1);
  }
}

There is a bug where the puck bounces off empty air. Not sure what’s wrong but yeah. Besides that, I didn’t implement ignore-case-controlls, so playing with capslock is impossible. Good luck playing!

#52 SnakePVP

Code
int w = 20, h = 20, scl=30;
int grid[][] = new int[w][h];
color clr1 = color(255, 0, 0), clr2 = color(0, 0, 255);
color trail1 = color(50, 0, 0), trail2 = color(0, 0, 50);
int x1=5, y1=5, x2=15, y2=15;
float d1 = 0, d2 = 2;
int RESULT = 0;
void setup() {
  size(660, 660);
  textAlign(3, 3);
}
void keyPressed() {
  d1 = ((keyCode==RIGHT)? 0 : ((keyCode==DOWN)? 1 : ((keyCode==LEFT)? 2 : ((keyCode==UP)? 3 : d1)))); 
  char pressed = ((key+"").toLowerCase()).charAt(0);
  d2 = ((pressed=='d')? 0 : ((pressed=='s')? 1 : ((pressed=='a')? 2 : ((pressed=='w')? 3 : d2))));
}

void draw() {
  background(50, 255, 50);
  fill(0); 
  noStroke();
  square(scl, scl, scl*w);  
  int cx1 = round(cos(d1*HALF_PI)), cy1 = round(sin(d1*HALF_PI)), cx2 = round(cos(d2*HALF_PI)), cy2 = round(sin(d2*HALF_PI));
  if (grid[x1][y1]==0) grid[x1][y1] = 1;
  else RESULT = 2; //P1 LOSES
  if (grid[x2][y2]==0) grid[x2][y2] = 2;
  else RESULT = 1; //P2 LOSES
  if (RESULT==0) {
    x1+= cx1;
    y1+= cy1;
    x2+= cx2;
    y2+= cy2;
  }
  if(x1>=w||x1<0||y1>=h||y1<0) RESULT = 2;
  if(x2>=w||x2<0||y2>=h||y2<0) RESULT = 1;
  for (int i = 0; i < w; i++) for (int j = 0; j < h; j++) if (grid[i][j]!=0) {
    fill( ((grid[i][j]==1)? trail1 : trail2) );
    square((i+1)*scl, (j+1)*scl, scl);
  }

  fill(clr1);
  square((x1+1)*scl, (y1+1)*scl, scl);
  fill(clr2);
  square((x2+1)*scl, (y2+1)*scl, scl);
  if (RESULT!=0) {
    textSize(50);
    if (RESULT==1) {
      println("Player 1 wins!");
      fill(clr1, 150);
      text("PLAYER 1 WINS", width*0.5, height*0.5);
    } else if (RESULT == 2) {
      println("Player 2 wins!");
      fill(clr2, 150);
      text("PLAYER 2 WINS", width*0.5, height*0.5);
    }
    noLoop();
  }
  delay(300);
}

A PVP game for two players

#53 Artistic Connect-n (4)


A program that allows you to play connect-n in a w * h size grid. It allows you to resize the grid and the win requirement. There is no win message.

Code
int w = 7, h = 6, inRow = 4, turn = 1, mx=0;
int grid[][] = new int[w][h];
float scl = 70, rm = 0.85;
color clr[] = {#FF001C, #75A2BF, #FFFF00};
int bottomBuffer=5, x=floor(700*0.5-w*scl*0.5), y=600-bottomBuffer-int(h*scl), sideW=25;
float coinX = y+scl*w/2, coinY = y - scl*0.6;
int RESULT = 0;
int wx1, wy1, wx2=4, wy2=4;
void setup() {
  size(700, 600);
}
void draw() {
  mx = (int)constrain(map(mouseX, x, x+w*scl, 0, w), 0, w-1);
  noStroke();
  strokeWeight(1);
  noFill();
  background(0);
  displayBoard();
  if (RESULT!=0) { 
    displayWin(wx1, wy1, wx2, wy2);
  }
}
int checkWin() { //0-none, -1: yellow 1: red 2: out of space
  //checking for outofspace
  boolean outOfSpace=true;
  for (int i = 0; i < w && outOfSpace==true; i++)for (int j = 0; j < h && outOfSpace==true; j++) if (grid[i][j]==0) outOfSpace=false;
  if (outOfSpace) return 2;
  //check for horizontal win
  for (int j = 0; j < h; j++) for (int i = 0; i < w; i++) if (grid[i][j] != 0) for (int k = 0; k < 4; k++) {
    //HOR, VER, RDIG, LDIG
    int cx = ((k==0 || k == 2)? 1 : ((k==1)? 0 : -1)), cy = ((k==0)? 0 : 1);
    boolean win=true;
    int nx = i, ny = j, target = grid[i][j], row = 0;
    while (inBounds(nx, ny) && grid[nx][ny] == target) {
      row++;
      nx+=cx;
      ny+=cy;
    }
    if (row>=inRow) {
      wx1 = i;
      wy1 = j;
      wx2 = nx-cx;
      wy2 = ny-cy;
      return target;
    }
  }

  return 0;
}
boolean inBounds(int x, int y) {
  return(x>=0&&x<w&&y>=0&&y<h);
}
void displayWin(int x1, int y1, int x2, int y2) {
  stroke(0, 255, 0); 
  strokeWeight(3);
  boolean t = true, f = false;
  float nx1 = x+(x1+0.5)*scl, ny1 = y+(y1+0.5)*scl, nx2 = x+(x2+0.5)*scl, ny2 = y+(y2+0.5)*scl;
  float dir = atan2(y2-y1, x2-x1);
  float cx = move(0, dir+HALF_PI, scl*0.5, t), cy  = move(0, dir+HALF_PI, scl*0.5, f);
  line(nx1-cx, ny1-cy, nx2-cx, ny2-cy);
  line(nx1+cx, ny1+cy, nx2+cx, ny2+cy);
  noFill();
  arc(nx1, ny1, scl, scl, dir+HALF_PI, dir+3*HALF_PI);
  arc(nx2, ny2, scl, scl, dir-HALF_PI, dir+HALF_PI);
}
float move(float p, float dir, float dist, boolean x_) {
  if (x_) return p+cos(dir)*dist;
  else return p+sin(dir)*dist;
}
void displayBoard() {
  fill(#001540);
  rect(x-sideW, y, w*scl+2*sideW, h*scl+bottomBuffer, sideW, sideW, 0, 0);

  fill(#003366);
  rect(x, y, w*scl, h*scl);
  for (int i = 0; i < w; i++) for (int j = 0; j < h; j++) {
    fill( clr[grid[i][j]+1]);
    circle((i+0.5)*scl+x, (j+0.5)*scl+y, scl*rm);
  }
  fill(#001540);
  rect(x, y, w*scl, scl*(1-rm)*0.25);

  fill(255, 20);
  rect(x+mx*scl, y, scl, scl*h);
  if(RESULT==0) coinX = constrain(lerp(coinX, x+(mx+0.5)*scl, 0.05), x+scl*0.5, x+(w-0.5)*scl);

  fill(clr[turn+1]);
  circle(coinX, coinY, scl*(0.5+rm*0.5));
}
void mousePressed() {
  if (RESULT==0) {
    int y = h-1;
    while (grid[mx][constrain(y, 0, h)]!=0 && y>=0) y--;
    if (y>=0) { 
      grid[mx][y] = turn;
      turn*=-1;
      RESULT = checkWin();
    }
  }
}

set inRow to >3, since everything less is not interesting. To resize the grid change w and h.

Nice and good working keep on that

1 Like

#53-2 Artistic Connect-n V2


Changes:

  • added win message
  • more than one win can be displayed (look at picture)
  • minor changes
Code
int w = 7, h = 6, inRow =4, turn = 1, mx=0, wUsed = 0; //wUsed - wins used
int grid[][] = new int[w][h];
float scl = 70, rm = 0.85; //rm - radius multiplier
color clr[] = {#FF001C, #75A2BF, #FFFF00}; //red-empty-yellow
int bottomBuffer=5, x=floor(700*0.5-w*scl*0.5), y=600-bottomBuffer-int(h*scl), sideW=25, RESULT = 0;
float coinX = y+scl*w/2, coinY = y - scl*0.6;
PVector w1[] = new PVector[4], w2[] = new PVector[4];
void setup() {
  size(700, 600);
  textAlign(3,3);
}
void draw() {
  mx = (int)constrain(map(mouseX, x, x+w*scl, 0, w), 0, w-1);
  noStroke();
  strokeWeight(1);
  noFill();
  background(0);
  displayBoard();
  if (RESULT!=0) for(int i = 0; i < wUsed; i++) displayWin((int)w1[i].x,(int)w1[i].y,(int)w2[i].x,(int)w2[i].y);
  if (RESULT==2) displayWin(100,100,100,100);
}
int checkWin() { //0-none, -1: yellow 1: red 2: out of space
  boolean outOfSpace=true; //checking for outofspace
  int output = 0;
  for (int i = 0; i < w && outOfSpace==true; i++)for (int j = 0; j < h && outOfSpace==true; j++) if (grid[i][j]==0) outOfSpace=false;
  if (outOfSpace) return 2;
  //check connecting
  for (int j = 0; j < h; j++) for (int i = 0; i < w; i++) if (grid[i][j] != 0) for (int k = 0; k < 4; k++) {
    //HOR, VER, RDIG, LDIG
    int cx = ((k==0 || k == 2)? 1 : ((k==1)? 0 : -1)), cy = ((k==0)? 0 : 1);
    int nx = i, ny = j, target = grid[i][j], row = 0;
    while (inBounds(nx, ny) && grid[nx][ny] == target) {
      row++;
      nx+=cx;
      ny+=cy;
    }
    if (row>=inRow) {
      w1[wUsed] = new PVector(i,j);
      w2[wUsed] = new PVector(nx-cx,ny-cy);
      wUsed++;
      output = target;
    }
  }

  return output;
}
boolean inBounds(int x, int y) {
  return(x>=0&&x<w&&y>=0&&y<h);
}
void displayWin(int x1, int y1, int x2, int y2) {
  stroke(0, 255, 0); 
  strokeWeight(3);
  boolean t = true, f = false;
  float nx1 = x+(x1+0.5)*scl, ny1 = y+(y1+0.5)*scl, nx2 = x+(x2+0.5)*scl, ny2 = y+(y2+0.5)*scl;
  float dir = atan2(y2-y1, x2-x1);
  float cx = move(0, dir+HALF_PI, scl*0.5, t), cy  = move(0, dir+HALF_PI, scl*0.5, f);
  line(nx1-cx, ny1-cy, nx2-cx, ny2-cy);
  line(nx1+cx, ny1+cy, nx2+cx, ny2+cy);
  noFill();
  arc(nx1, ny1, scl, scl, dir+HALF_PI, dir+3*HALF_PI);
  arc(nx2, ny2, scl, scl, dir-HALF_PI, dir+HALF_PI);
  textSize(scl);
  if(RESULT==-1||RESULT==1) {
    fill(clr[RESULT+1]);
    text( ((RESULT==1)? "YELLOW" : "RED") + " WINS!", x+w*scl*0.5, y-scl);
  }
  if(RESULT==2) {
    fill(0,200,0);
    text( "OUT OF SPACE", x+w*scl*0.5, y-scl);
  }
}
float move(float p, float dir, float dist, boolean x_) {
  if (x_) return p+cos(dir)*dist;
  else return p+sin(dir)*dist;
}
void displayBoard() {
  fill(#001540);
  rect(x-sideW, y, w*scl+2*sideW, h*scl+bottomBuffer, sideW, sideW, 0, 0);

  fill(#003366);
  rect(x, y, w*scl, h*scl);
  for (int i = 0; i < w; i++) for (int j = 0; j < h; j++) {
    fill( clr[grid[i][j]+1]);
    circle((i+0.5)*scl+x, (j+0.5)*scl+y, scl*rm);
  }
  fill(#001540);
  rect(x, y, w*scl, scl*(1-rm)*0.25);

  fill(255, 20);
  rect(x+mx*scl, y, scl, scl*h);
  if(RESULT==0) coinX = constrain(lerp(coinX, x+(mx+0.5)*scl, 0.05), x+scl*0.5, x+(w-0.5)*scl);

  fill(clr[turn+1]);
  circle(coinX, coinY, scl*(0.5+rm*0.5));
}
void mousePressed() {
  if (RESULT==0) {
    int y = h-1;
    while (grid[mx][constrain(y, 0, h)]!=0 && y>=0) y--;
    if (y>=0) { 
      grid[mx][y] = turn;
      turn*=-1;
      RESULT = checkWin();
    }
  }
}

#54 2D simple collisions demo 1

This is a simple demo for a 2D collision detection with rectangles. The only square that can move is the player. If you find any bugs, do tell!

Code
int px = 10, py = 10, a = 20;
int cx = 0, cy = 0, speed = 1;
obstacle o = new obstacle(275, 275, 50, 50);
void setup() {
  size(600, 600);
}
void draw() {
  background(0);
  movePlayer();
  fill(255);
  square(px, py, a);
  o.display();
}
void movePlayer() {
  for (int i = 0; i < speed; i++) {
    int nx = px+cx, ny = py+cy;
    if(collision(nx,py,a,a, o.x,o.y,o.s,o.s2) == false) px = nx;
    if(collision(px,ny,a,a, o.x,o.y,o.s,o.s2) == false) py = ny;
  }
}
void keyPressed() {
  char ky = (key+"").toLowerCase().charAt(0);
  if (ky == 'a') cx = -1;
  if (ky == 'd') cx = 1;
  if (ky == 'w') cy = -1;
  if (ky == 's') cy = 1;
}
void keyReleased() {
  char ky = (key+"").toLowerCase().charAt(0);
  if (ky == 'a' && cx == -1) cx = 0;
  if (ky == 'd' && cx == 1) cx = 0;
  if (ky == 'w' && cy == -1) cy = 0;
  if (ky == 's' && cy == 1) cy = 0;
}
boolean collision(int x1, int y1, int s1, int s12, int x2, int y2, int s2, int s22) {
  if (x1>x2-s1&&y1>y2-s12&& x1<x2+s2 && y1<y2+s22) return true; //x2-s1, y2-s12, x2+s2, y2+s22
  return false;
}
class obstacle {
  int x, y, s, s2;
  obstacle(int x_, int y_, int s_, int s2_) {
    x = x_;
    y = y_;
    s = s_;
    s2 = s2_;
  }
  void display() {
    fill(0, 0, 255);
    rect(x, y, s, s2);
  }
}

#55 Simple posterization filter

Posterization filter sets the maximum amount of colors used. All colors on the screen get converted into those. explanation by josephh

Code
int clrs = 3; //end has clrs^3 colors, (1-1, 2-8, 3-27, 4-64, 5-125, 6-216,...)
color clr[];
PImage img;
void setup() {
  size(640,642);
  clr = generateColors(clrs);
  img = loadImage("house2.jpg");
  println(img.width,img.height);
}
void draw() {
  image(img,0,0); noLoop();
  loadPixels();
  for(int i = 0; i < width; i++) for(int j = 0; j < height*0.5; j++) {
    int in = i+j*width, off = floor(width*height*0.5);
    color base = pixels[in], chan = closest(base);
    pixels[in+off] = chan;
  }
  updatePixels();
}
color closest(color input) {
  int id=0;
  float d = -1;
  for(int i = 0; i < clr.length; i++) {
    float dis = dist(red(input),green(input),blue(input),red(clr[i]),green(clr[i]),blue(clr[i]));
    if(dis < d || d == -1) {
      id = i;
      d = dis;
    }
  }
  return clr[id];
}

color[] generateColors(int c) {
  float a = 255/c;
  color nclr[] = new color[c*c*c];
  for(int i = 0; i < c; i++) for(int j = 0; j < c; j++) for(int k = 0; k < c; k++) {
    nclr[i+j*c+k*c*c] = color(i*a, j*a, k*a);
  }
  return nclr;
}

It is a simple project (if you are using the simple color cube solution). It can be upgraded at any time by changing the generateColors() function.