Match 3 remove from arraylist

I’m trying to create a match 3 & made a check function that works & tell me when there are 3 in a row. I tried giving each one a float but when I go to remove the letters assign to each i that met nothing happened. Can anyone tell me why? here the code for the block. I’m typing in java using processing.

first page

ArrayList<block> Block = new ArrayList<block>(); // making a new array
int wide = 5; // declaring the width
int hei = 5; // declaring the height
float time; // declaring time
// time is part of the falling system every time something moves I want time to go to like 5
void addBlock(){// decided to take some advise and add an add block at least for now
  for (int i = 0; i < wide; i++){// here to the next lines is where I make my blocks
    for (int j = 0; j < hei; j++){
      float t = random(5);
      t = round(t);
      Block.add(new block(10 + (50*i),10 + (50*j),50,t));
    }
  }
}
void setup(){ // setup
  size(500,500);// setting the size
  addBlock();
}
void draw(){// draw
  background(0);// black background
  for (int i = 0; i < Block.size(); i++){ // going through blocks
    block b = Block.get(i);// I forgot what this part is called     getting block
    b.show();// showing block
    b.update(); // updating block
    b.move(); // moving block
  }//////////////////////////////////////////////
}

void keyPressed(){// looking at what keys are being pressed
  if (key == 'r'){// checking the r key so I can reset
    for (int i = Block.size()-1; i >= 0; i--){ // erasing all old blocks for my reset
      Block.remove(i);
    }///////////////////////////////////////////////
    addBlock();
  }
  if (key == ' '){// checking space
    for (int i = Block.size()-1; i >= 0; i--){ // running through blocks
        block b = Block.get(i);// getting blocks
        if (b.check == true){// checking if check = true
          Block.remove(i);// removing any that equal true
        }
      }/////////////////
    }
}

block page

class block{// making a new class
  float x,y,w,type,a,d,c,e,f;// setting a bunch of floats will say why later
  boolean first, second, third, fourth, check = false; // setting a bunch of booleans
  boolean collide = false; // setting collide currently not working correct
  block(float x, float y, float w, float type){ // making my block or whatever this is called
    this.x = x;// setting the x position to the x float above
    this.y = y;// setting the y position to the y above
    this.w = w;// setting the width
    this.type = type;// setting the type
  }
  void show(){// showing the block
    if (type == 0){fill(255,0,0);}// setting color determined by type
    if (type == 1){fill(0,255,0);}
    if (type == 2){fill(0,0,255);}
    if (type == 3){fill(255,0,255);}
    if (type == 4){fill(255,255,0);}
    if (type == 5){fill(0,255,255);}
    rect(x,y,w,w);// drawing a rectangle
  }
  void move(){// not working yet it suppose to move them
    for (int i = 0; i < Block.size(); i++){// runs through all blocks
      block b = Block.get(i);// get blocks
      // the idea behind this is run through them all and stop if a block is a certain height above another
    }
  }// move
  void update(){// updating
    textSize(15);
    // here I check for matches
    for (int i = 0; i < Block.size(); i++){// running through blocks
      block b = Block.get(i);// getting blocks
      if (b.type == type){// checking type
        if (b.x == x && b.y == y){ // checking position
          c = i; // setting c the block that is checking all the rest
        }
        if (b.x + w == x && b.y == y){ // checking 60 x away for a match
          first = true;// turning first to true so I know which blocks found both matches
          a = i; // setting a to i to save the i number
        }
        if (b.x + (w*2) == x && b.y == y && first == true){ // checking 120 x away I should do these by width
          second = true; // checking second which means the first one been found
          // I only check for 3 because with all the blocks checking 3 all matches should be gone
          d = i; // setting d to i to save i
        }
        if (b.y + w == y && b.x == x){ //checking 60 y
          third = true;// setting third to true
          e = i; // setting e to i to save i
        }
        if (b.y + (w*2) == y && b.x == x && third == true){ // check 120 y
          fourth = true; // setting fourth to true 
          f = i;// setting f to i
        }
      }
    }
    if (first == true && second == true){// checking to see if there 3 in a row x
      for (int i = 0; i < Block.size(); i++){// running through the blocks
        block b = Block.get(i);// getting blocks
        if (a == i){// getting a
          b.check = true;// setting the a block to true
        }
        if (d == i){ // getting d
          b.check = true;// setting the d block to true
        }
        if (c == i){// getting c
          b.check = true; // setting the c block to true
        }
      }//////
    }
    if (third == true && fourth == true){// checking third and fourth y
      for (int i = 0; i < Block.size(); i++){// running through blocks
        block b = Block.get(i);// gettig blocks
        if (e == i){// getting e
          b.check = true; // setting e to true
        }
        if (f == i){ // getting f
          b.check = true; // setting f to true
        }
        if (c == i){ // getting c
          b.check = true; // setting c to true
        }
      }//////
    }
  }
}

All we have is your class. We can run it, and it defines an object. But that does’t help us debug it because the sketch doesn’t DO anything!

Please post the code of your global variables, setup(), and draw() functions too! Then we might be able to see your code doing something.

I made an int to hold each i that was in the correct spot and tried erasing them. As you can see but it didn’t work.

Few things:

class block should be class Block. In Java, it is a good practice to have the first letter of the name of a class in upper case. Additionally, any instant of any class should start with a lower case. Consequently you should write: ArrayList<Block> blocks = new ArrayList<Block>(); Notice I made it plural as it is a container which its functionality is to hold multiple blocks.

You have properly implemented a removal operation in your keyPressed() in the code above. However, your removal operation in block’s update() is not proper. You are removing elements of the array from within the class. Since the array is made of objects of this class, the class should not be aware of the array at all. Instead, you should remove your update() and move this functionality to your draw(). Your class could still check if two other elements are in a row with itself. It could return a boolean value describing so, like this:

boolean checkBlocksRowAlignment(Block firstBlock, Block secBlock){

  boolean blocksAligned=false;

    //Now you ahve three blocks: firstBlock, secBock and the current block which for clarity, 
    //you can access with the `this` keyword.

    //Now, you perform your test to check if they are in a row and return the result of your test
    //...
    //... you design this part
    //

    return blocksAligned;

}

Last, you can perform this test in draw():

void setup(){
   //...
   //... Other functions
   //...
   addBlocks();
}

void draw(){
  
  //Check alignment  of first three blocks
  boolean areThreeFirstBlocksAligned=false;
  Block firstBlockHandle=blocks.get(0);
  areThreeFirstBlocksAligned =  firstBlockHandle.checkBlocksRowAlignment(blocks.get(1),blocks.get(2));

  //Now if areThreeFirstBlocksAligned returns true, you can remove them
}

void addBlocks(){
  for (int i = 0; i < wide; i++){
    for (int j = 0; j < hei; j++){
      float t = random(4);
      t = round(t);
      Block.add(new block(50+(50*i),50+(50*j),50,t));
    }
  }
}

This is a pseudo-code. Notice This is a rough implementation and you need to re-design the above to be able to handle more than three blocks since I am only dealing with the first three blocks. This implies to have some sort of for loop that perform row check alignment in the different unique block combinations. For four blocks abcd you need to test for abc, abd, bcd, acd. I hope this helps.

Kf

1 Like

Thanks for your comment but I knew most the stuff you said. I got it where mine can detect 3 blocks & now it assigns those 3 blocks a boolean check then tries to delete them. I really dont see why I would use a function to add blocks since its only to test the blocks atm later it will be in a bigger thing not its own function. Here the new code that still dont erase right & please dont give me the bs of wrong caps.
first page

ArrayList<block> Block = new ArrayList<block>();
int wide = 5;
int hei = 5;
void setup(){
  size(500,500);
  for (int i = 0; i < wide; i++){
    for (int j = 0; j < hei; j++){
      float t = random(4);
      t = round(t);
      Block.add(new block(50+(50*i),50+(50*j),50,t));
    }
  }
}
void draw(){
  background(0);
  for (int i = 0; i < Block.size(); i++){
    block b = Block.get(i);
    b.show();
    b.update();
  }
}

void keyPressed(){
  if (key == 'r'){
    for (int i = Block.size()-1; i >= 0; i--){
      Block.remove(i);
    }
    for (int i = 0; i < wide; i++){
      for (int j = 0; j < hei; j++){
        float t = random(4);
        t = round(t);
        Block.add(new block(50+(50*i),50+(50*j),50,t));
      }
    }
  }
  if (key == ' '){
    for (int i = Block.size()-1; i >= 0; i--){
        block b = Block.get(i);
        if (b.check == true){
          Block.remove(i);
        }
      }//////
  }
}

blocks

class block{
  float x,y,w,type,a,d,c;
  boolean first, second, third, fourth, check = false;
  block(float x, float y, float w, float type){
    this.x = x;
    this.y = y;
    this.w = w;
    this.type = type;
  }
  void show(){
    if (type == 0){fill(255,0,0);}
    if (type == 1){fill(0,255,0);}
    if (type == 2){fill(0,0,255);}
    if (type == 3){fill(255,0,255);}
    if (type == 4){fill(255,255,0);}
    rect(x,y,w,w);
  }
  
  void update(){
    textSize(15);
    for (int i = 0; i < Block.size(); i++){
      block b = Block.get(i);
      if (b.type == type){
        if (b.x == x && b.y == y){
          c = i;
        }
        if (b.x + 50 == x && b.y == y){
          first = true;
          a = i;
        }
        if (b.x + 100 == x && b.y == y && first == true){
          second = true;
          fill(255,255,0);
          rect(x-100,y,150,10);
          d = i;
        }
        if (b.y + 50 == y && b.x == x){
          third = true;
        }
        if (b.y + 100 == y && b.x == x && third == true){
          fourth = true;
          fill(255,255,0);
          rect(x,y-100,10,150);
        }
      }
    }
    if (first == true && second == true || third == true && fourth == true)
      for (int i = 0; i < Block.size(); i++){
        block b = Block.get(i);
        if (a == i){
          b.check = true;
        }
        if (d == i){
          b.check = true;
        }
        if (c == i){
          b.check = true;
        }
      }//////
    }
  }

I make a big effort to ask people to make their code more readable. It is not only about formatting your code in the forum. You need to properly tab your code, which you do, as well as following standard java practices. I mean, nobody forces you to do something as simple as proper upper/lower case formatting. Matters are even worse since you sue Block and block in your code which, from any other people reading your code, will require to learn the way you think. This is important. I do not want to learn how you do things. You are not making life any easier to any of the forum volunteers that spend their own free time to help YOU.

I went an extra mile in your code because, your design is not proper. I mean, your previous code is doing something that should not be done. Your class block is accessing the array containing your blocks. I couldn’t go any further because your code is hard to read, exactly what is inside your update() function. Instead of writing code, you should explain what you are trying to do while performing those checkings there, or add short concise comments to your code.

Related to the adding blocks function, my bad. This is my practice of making code more readable and I do it when I see repeated code.

Kf

2 Likes

TY, sorry I wasn’t feeling good when I sent that last comment. I fixed the code now they all erase how they should. I’ll paste the code soon so someone might learn from it. I added comments and tried adding a fall system but atm it not working. TY for trying to help. If wanna feel free to shorten my code I hope the comments help you to understand it.

I have written a code that demonstrates removal of 3 cells that are the same in the same row.

Check it out below. I removed your update of function and I rewrote an algorithm that it might be useful to you.
I have added the following keys: ‘t’ and ‘c’ in addition to your key commands ‘r’ and ’ ’ aka. space key. Their functionality are:

  • ‘t’ For testing
  • ‘c’ for checking when at least three items in a row are the same, and mark them for further processing
  • ‘r’ to randomize your color table (generates a new one)
  • space: Removes those items that are marked by the ‘c’ command.

The proper way to run this example:

  1. Press r as many times as you see three cells of the same type adjacent to each other in the same row. Then press ‘c’ for checking and marking them. Finally, press ‘space’ bar to remove them.
  2. Same as 1 but start pressing the ‘t’ to manually set certain adjacent cells the same. Then press ‘c’ followed by ‘space’

I hope this helps.

Kf

final int NROWS=5;
final int NCOLS=5;

ArrayList<Block> block = new ArrayList<Block>();

int wide = NROWS;
int hei = NCOLS;

void setup() {
  size(500, 500);
  
  
  for (int i = 0; i < wide; i++) {
    for (int j = 0; j < hei; j++) {
      float t = random(4);
      t = round(t);
      block.add(new Block(50+(50*i), 50+(50*j), 50, t));
    }
  }
}
void draw() {
  background(0);
  for (int i = 0; i < block.size(); i++) {
    Block b = block.get(i);
    b.show();
  }
}

void keyPressed() {
  if (key == 'r') {
    for (int i = block.size()-1; i >= 0; i--) {
      block.remove(i);
    }
    for (int i = 0; i < wide; i++) {
      for (int j = 0; j < hei; j++) {
        float t = random(4);
        t = round(t);
        block.add(new Block(50+(50*i), 50+(50*j), 50, t));
      }
    }
  }

  //c for 'check' for overlap on the same row
  //Notice blocks are added by column
  //Algorithm: Traversing down each column from left to right
  //Skip the last two columns
  //In each step, take the curent cell (aka c1) and the two 
  //   adjacents cells to the right in the same row - aka cells 
  //   c2 and c3) and check if there are of the same type. If 
  //  they are, mark them for removal.
  //Since I am taking thre cells in the same row, I have to watch
  //  I am inside the table at all times. This is the reason I 
  //  skipped the last two columns.
  if (key == 'c') {  

    for (int i = 0; i < block.size()-2*NCOLS; i++) {
      Block c1 = block.get(i+0*NCOLS);
      Block c2 = block.get(i+1*NCOLS);
      Block c3 = block.get(i+2*NCOLS);

      if (c1.type==c2.type && c2.type==c3.type) {
        c1.markForRemoval=c2.markForRemoval=c3.markForRemoval=true;
      }
    }
  }


  if (key == ' ') {
    for (int i = block.size()-1; i >= 0; i--) {
      Block b = block.get(i);
      if (b.markForRemoval == true) {
        block.remove(i);
      }
    }//////
  }
  
  //'t' for testing
  //For testing purposes. It marks the first three blocks
  // in a row the smae. It also marks the last three blocks in a row 
  //the same.
  //This is for testing purposes.
  if (key == 't') {
    ((Block)block.get(0+0*NCOLS)).type=0;
    ((Block)block.get(0+1*NCOLS)).type=0;
    ((Block)block.get(0+2*NCOLS)).type=0;
    
    ((Block)block.get((NROWS-2)*NCOLS-1)).type=0;
    ((Block)block.get((NROWS-1)*NCOLS-1)).type=0;
    ((Block)block.get((NROWS-0)*NCOLS-1)).type=0;    
  }
}


class Block {
  float x, y, w, type, a, d, c;
  boolean markForRemoval;

  boolean first, second, third, fourth, check = false;

  Block(float x, float y, float w, float type) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.type = type;
    this.markForRemoval=false;
  }

  void show() {
    if (type == 0) {
      fill(255, 0, 0);
    }
    if (type == 1) {
      fill(0, 255, 0);
    }
    if (type == 2) {
      fill(0, 0, 255);
    }
    if (type == 3) {
      fill(255, 0, 255);
    }
    if (type == 4) {
      fill(255, 255, 0);
    }
    
    if(markForRemoval){
      stroke(255);
      strokeWeight(5);
    }
    else{
      stroke(0);
      strokeWeight(1);
    }
    
    rect(x, y, w, w);
  }
}

TY very much. I’ll try it out.