简体   繁体   中英

Flagging cells in grid (Minesweeper in plain JavaScript + p5.js framework)

I've been trying to make a function that flags cells when right-clicked. I already have the rightclick and all the stuff. The only problem is that all the revealed cells get flagged on click. If you have any questions with p5.js, visit the reference here .

I have this for now:


sketch.js

var grid;
var cols;
var rows;
var w = 40;

var totalBoom = 10;

function make2DArray(cols, rows) {
  var arr = new Array(cols);
  for (var i = 0; i < arr.length; i++) {
    arr[i] = new Array(rows);
  }
  return arr;
}

function setup() {
  createCanvas(400, 400);
  cols = floor(width / w);
  rows = floor(height / w);
  grid = make2DArray(cols, rows);
  for (var i = 0; i < cols; i++) {
    for (var j = 0; j < rows; j++) {
      grid[i][j] = new cell(i, j, w);
    }
  }

  var spots = [];
  for (var i = 0; i < cols; i++) {
    for (var j = 0; j < rows; j++) {
      spots.push([i, j]);
    }
  }

  for (var n = 0; n < totalBoom; n++) {
    var index = floor(random(spots.length));
    var choice = spots[index];
    var i = choice[0];
    var j = choice[1];
    spots.splice(index, 1);
    grid[i][j].boom = true;
  }

  for (var i = 0; i < cols; i++) {
    for (var j = 0; j < rows; j++) {
      grid[i][j].adjacentCells();
    }
  }
}

function gameOver() {
  for (var i = 0; i < cols; i++) {
    for (var j = 0; j < rows; j++) {
      grid[i][j].revealed = true;
    }
  }
}

function win() {
  if (boom.checked = true) {

  }
}

function mousePressed() {
  if (mouseButton == LEFT) {
    for (var i = 0; i < cols; i++) {
      for (var j = 0; j < rows; j++) {
        if (grid[i][j].hasBoom(mouseX, mouseY)) {
          grid[i][j].showBoom();

          if (grid[i][j].boom) {
            gameOver();
          }
        }
         else if (mouseButton == RIGHT) {
          console.log("RIGHTCLICK");
        }
      }
    }
  }
}

function draw() {
  background(200);
  for (var i = 0; i < cols; i++) {
    for (var j = 0; j < rows; j++) {
      grid[i][j].show();
    }
  }
}




cell.js

function cell(i, j, w) {
  this.i = i;
  this.j = j;
  this.x = i * w;
  this.y = j * w;
  this.w = w;
  this.neighborCount = 0;

  this.boom = false;
  this.revealed = false;
  this.checked = false;
}

cell.prototype.show = function () {
  stroke(0);
  noFill();
  rect(this.x, this.y, this.w, this.w);
  if (this.revealed) {
    if (this.boom) {
      fill(floor(random(10, 200)), 0, 0);
      ellipse(this.x + w * 0.5, this.y + w * 0.5, this.w * 0.5);
    } else {
      fill(125);
      stroke(12);
      rect(this.x, this.y, this.w, this.w);
      if (this.neighborCount > 0) {
        textAlign(CENTER);
        textSize(this.w * 0.5);
        fill(0);
        text(this.neighborCount, this.x + this.w * 0.5, this.y + this.w * 0.75);
      }
    }
  }
}

cell.prototype.adjacentCells = function () {
  if (this.boom) {
    this.neighborCount = -1;
    return;
  }
  var total = 0;

  for (var xoff = -1; xoff <= 1; xoff++) {
    for (var yoff = -1; yoff <= 1; yoff++) {
      var i = this.i + xoff;
      var j = this.j + yoff;
      if (i > -1 && i < cols && j > -1 && j < rows) {
        var neighbor = grid[i][j];
        if (neighbor.boom) {
          total++;
        }
      }
    }
  }
  this.neighborCount = total;
}

cell.prototype.hasBoom = function (x, y) {
  return x > this.x && x < this.x + this.w && y > this.y && y < this.y + this.w;
}

cell.prototype.showBoom = function () {
  this.revealed = true;
  if (this.neighborCount == 0) {
    this.floodFill();
  }
}

cell.prototype.floodFill = function () {
  for (var xoff = -1; xoff <= 1; xoff++) {
    for (var yoff = -1; yoff <= 1; yoff++) {
      var i = this.i + xoff;
      var j = this.j + yoff;
      if (i > -1 && i < cols && j > -1 && j < rows) {
        var neighbor = grid[i][j];
        if (!neighbor.boom && !neighbor.revealed) {
          neighbor.showBoom();
        }
      }
    }
  }
}

If you want to see how the code is running, click here

By the way, don't use class constructors or any of these shenigan code thingies, they confuse me;-;

After going through your code, I found that you have a nested loop inside the mouseevent method which is used to detect the current clicked cell and need the correct index for different action based on the RIGHT | LEFT RIGHT | LEFT click.

You are checking for the RIGHT click inside the condition of LEFT click and it will never be true. So, here is a modified code.

function mousePressed() {
    for (var i = 0; i < cols; i++) {
      for (var j = 0; j < rows; j++) {
        /*
         * on every mouse event, we go through each cell.
         * If the click is RIGHT we will mark it check and get out of the loop.
         */ 
        if(mouseButton == RIGHT) { 
          grid[i][j].checked = true; 
          return;
        }
        if (grid[i][j].hasBoom(mouseX, mouseY)) {
          grid[i][j].showBoom(); 
 
          if (grid[i][j].boom) {
            gameOver();
          }
        }
      }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM