1

I'm trying to make a minesweeper clone using Processing's java. I have managed to create a grid and each tile has a randomized value assigned to it, but for some reason, only the top left tile can be clicked, the rest of the tiles do not return a value. If anyone knows whats wrong with my code or what I could try that would be great, thanks

Here's my Java code:

int realWidth = 500;
int realHeight = 500;
int tilemount = 0;

boolean mousePress = false;

//calls class
Tile[] tile = new Tile[100];
float tileSize = realWidth/10;

//sets size of window
void settings() {
  size(realWidth, realHeight);
}

//Draws 100 tiles on the grid and assignemts each with a value from -1 - 9
void setup() {
  int x = 0;
  int y = 0;
  for (int i = 0; i < tile.length; i++) {
    tile[i] = new Tile(x, y, int(random(-1,9)), tilemount);
    x += tileSize;
    if (x > realWidth-tileSize) {
      x = 0;
      y += tileSize;
    }
    tilemount ++;
  }
  print("done");
}

//updates each tile in the list
void draw() {
  background(50);
  for (int i = 0; i < tile.length; i++) {
    tile[i].display();
    tile[i].tileClicked();
  }
  //checks if tiles are clicked
  clickCheck();
}



//sets up tile class
class Tile {
  int x;
  int y;
  int value;
  int tilemount;
  
  Tile(int x, int y, int value, int tilemount) {
    this.x = x;
    this.y = y;
    this.value = value;
    this.tilemount = tilemount;
  } 
  
  //positions the tile based off of display values
  void display() {
    rect(x, y, tileSize, tileSize);
  }
  
  //the problem:
  
  
  /*if tile is clicked, it should run through all 100 tiles in the list, 
  detect if the mouse is inside the x value assinged to each tile, and produce the 
  value of the tile the mouse is currently inside */
  
  void tileClicked() {
    if (mousePressed && mousePress == false) {
      mousePress = true;
      for (int i = 0; i < tile.length; i++) {
        //println(tile[i].x, tile[i].y);
        //println(tile[2].x, tile[2].y, mouseX, mouseY);
        if (mouseX > tile[i].x && mouseX < tileSize && mouseY > tile[i].y  && mouseY < tileSize) {
          println(i, tile[i].value);
          break;
        }
      }
    } 
  }
}

//Checks if mouse is clicked
void clickCheck() {
  if (!mousePressed) {
    mousePress = false;
  }
}
George Profenza
  • 50,687
  • 19
  • 144
  • 218

2 Answers2

1

There is a bit of confusion over classes/objects and global variables in your code.

I say that for a few reasons:

  • boolean mousePress = false; is a global variable, accessible throughout the sketch, however you are accessing it and changing it from each Tile instance, resetting it's value: you probably meant to use a mousePress property for Tile. This way, each Tile has it's mousePress without interfering with one another.
  • in tileClicked() you're itereratting through all the tiles, from Tile which means unecessarily doing the loop for each time: each tile can check it's own coordinates and position to know if it's being clicked or not (no need for the loop)
  • speaking of checking bounds, checking if mouseX < tileSize and mouseY < tileSize will only check for the top left tile: you probably meant mouseX < x + tileSize and mouseY < y + tileSize

Here's a version of your sketch with the above notes applied (and optional debug text rendering to double check the printed value against the tile):


    int realWidth = 500;
    int realHeight = 500;
    int tilemount = 0;
    
    //calls class
    Tile[] tile = new Tile[100];
    float tileSize = realWidth/10;
    
    //sets size of window
    void settings() {
      size(realWidth, realHeight);
    }
    
    //Draws 100 tiles on the grid and assignemts each with a value from -1 - 9
    void setup() {
      int x = 0;
      int y = 0;
      for (int i = 0; i < tile.length; i++) {
        tile[i] = new Tile(x, y, int(random(-1,9)), tilemount);
        x += tileSize;
        if (x > realWidth-tileSize) {
          x = 0;
          y += tileSize;
        }
        tilemount ++;
      }
      println("done");
    }
    
    //updates each tile in the list
    void draw() {
      background(50);
      for (int i = 0; i < tile.length; i++) {
        tile[i].display();
        tile[i].tileClicked();
        //checks if tiles are clicked
        tile[i].clickCheck();
      }
    }
    
    
    
    //sets up tile class
    class Tile {
      int x;
      int y;
      int value;
      int tilemount;
      
      boolean mousePress = false;
      
      Tile(int x, int y, int value, int tilemount) {
        this.x = x;
        this.y = y;
        this.value = value;
        this.tilemount = tilemount;
      } 
      
      //positions the tile based off of display values
      void display() {
        fill(255);
        rect(x, y, tileSize, tileSize);
        fill(0);
        text(value,x + tileSize * 0.5, y + tileSize * 0.5);
      }
      
      //the problem:
      
      
      /*if tile is clicked, it should run through all 100 tiles in the list, 
      detect if the mouse is inside the x value assinged to each tile, and produce the 
      value of the tile the mouse is currently inside */
      
      void tileClicked() {
        if (mousePressed && mousePress == false) {
          mousePress = true;
          //println(tile[2].x, tile[2].y, mouseX, mouseY);
          if (mouseX > x && mouseX < x + tileSize && mouseY > y  && mouseY < y + tileSize) {
            println(value);
          }
        } 
      }
      //Checks if mouse is clicked
      void clickCheck() {
        if (!mousePressed) {
          mousePress = false;
        }
      }
    }

I understand the intent of the mousePress variable, but I'd like to mousePressed() function which you can use to avoid de-bouncing/resetting this value and simplify code a bit.

Here's a version of the above sketch using mousePressed() (and renaming variables a touch to be in line with Java naming conventions):

int realWidth = 500;
int realHeight = 500;
int tileCount = 0;

//calls class
Tile[] tiles = new Tile[100];
float tileSize = realWidth/10;

//sets size of window
void settings() {
  size(realWidth, realHeight);
}

//Draws 100 tiles on the grid and assignemts each with a value from -1 - 9
void setup() {
  int x = 0;
  int y = 0;
  for (int i = 0; i < tiles.length; i++) {
    tiles[i] = new Tile(x, y, int(random(-1,9)), tileCount);
    x += tileSize;
    if (x > realWidth-tileSize) {
      x = 0;
      y += tileSize;
    }
    tileCount ++;
  }
  println("done");
}

//updates each tile in the list
void draw() {
  background(50);
  for (int i = 0; i < tiles.length; i++) {
    tiles[i].display();
  }
}

void mousePressed(){
  for (int i = 0; i < tiles.length; i++) {
    tiles[i].click();
  }
}



//sets up tile class
class Tile {
  int x;
  int y;
  int value;
  int index;
  
  Tile(int x, int y, int value, int tileCount) {
    this.x = x;
    this.y = y;
    this.value = value;
    this.index = tileCount;
  } 
  
  //positions the tile based off of display values
  void display() {
    fill(255);
    rect(x, y, tileSize, tileSize);
    // optional: display the tile value for debugging purposes
    fill(0);
    text(value, x + tileSize * 0.5, y + tileSize * 0.5);
  }
  
  //the problem:
  /*if tile is clicked, it should detect if the mouse is inside the
  value assinged to each tile, and produce the 
  value of the tile the mouse is currently inside */
  
  void click() {
    if (mouseX > x && mouseX < x + tileSize && mouseY > y  && mouseY < y + tileSize) {
      println("index", index, "value", value);
    }
  }
}

Good start though: keep going! The rest of the code is good, congrats on using a 1D array for a 2D grid layout (and the logic for resetting the x position on each row). Have fun learning !

George Profenza
  • 50,687
  • 19
  • 144
  • 218
0

I think you did a good job naming functions and classes and what not. From this point, I would recommend breaking your code down so that you can make sure that at least 3 tiles function fully before allowing the tilelength to be something like 100 (for 100 tiles).

so from what I can see:

+ You have 3 apostrophes at the end of your code that need to be removed.

+ you use tile.length but never defined a length variable in your class, so when your for loop runs it has no number to use to determine it's number of cycles.

+ Please double check your logic in the tileClicked function with the help of a truth/logic table: https://en.wikipedia.org/wiki/Truth_table . I didn't look too deeply into this but this looks like an area where one misunderstanding could throw ;

Try adding this.length = 3; in your tile class and then re-run your code to see if more tiles pop up. And it might be good to use some system.out.println calls to print conditional values out so that you can see the intermeediate results and compare them to what you expect to happen. Just some basic debugging.

Good luck.

cstax
  • 47
  • 1