javascript 扫雷问题显示点击的 0 瓦片周围的瓦片

javascript minesweeper issue with revealing tiles surrounding a clicked 0 tile

单击其中一个图块会触发 clickerbox()。

问题是,如果用户点击带有 b 的磁贴 没有周围的地雷它应该显示它们,如果其中任何一个也没有地雷它应该做同样的事情。

它似乎做了一些,然后在显示它应该显示的所有图块之前停止了。我想知道是否有人知道为什么或如何解决这个问题?

点击零后的游戏面板截图

前 5 次点击由用户点击,其余点击由函数触发。

var width = 0;
var height = 0;
var bombs = 0;
var score = 0;
var boxs = 0;
let feild = new Array(2);
userfeild = new Array;

function selectdificulty() {
  feild = new Array(2);
  userfeild = new Array;
  document.getElementById('board').innerHTML = '';
  boxs = 0;
  score = 0;
  if (document.getElementById('dificulty').value == '4') {
    var widthinput = document.createElement('input');
    var heightinput = document.createElement('input');
    var bombinput = document.createElement('input');
    widthinput.placeholder = 'width';
    heightinput.placeholder = 'height';
    bombinput.placeholder = 'mines';
    widthinput.id = 'width';
    heightinput.id = 'height';
    bombinput.id = 'bombs';
    widthinput.setAttribute('type', 'text');
    heightinput.setAttribute('type', 'text');
    bombinput.setAttribute('type', 'text');
    document.getElementById('board').appendChild(widthinput);
    document.getElementById('board').appendChild(heightinput);
    document.getElementById('board').appendChild(bombinput);
    var entercustom = document.createElement('button')
    entercustom.id = 'entercustom';
    entercustom.innerHTML = 'enter custom values'
    document.getElementById('board').appendChild(entercustom);
    document.getElementById('entercustom').addEventListener('click', customsize);
  } else {
    if (document.getElementById('dificulty').value == '1') {
      width = 9;
      height = 9;
      bombs = 10;
    } else if (document.getElementById('dificulty').value == '2') {
      width = 16;
      height = 16;
      bombs = 38;
    } else if (document.getElementById('dificulty').value == '3') {
      width = 32;
      height = 16;
      bombs = 99;
    }
    createuserboard(width, height, bombs);
  }
}

function customsize() {
  var width = document.getElementById('width').value;
  var height = document.getElementById('height').value;
  var bombs = document.getElementById('bombs').value;
  if (!isNaN(width) && !isNaN(height) && !isNaN(bombs)) {
    if (width * height <= 601) {
      createuserboard(width, height, bombs);
    }
  }
}

function createuserboard(width, height, bombs) {
  document.getElementById('board').innerHTML = '';
  for (y = 0; y < height; y++) {
    userfeild[y] = new Array;
    var row = document.createElement('div');
    row.classList = 'row';
    row.id = 'row' + y;
    document.getElementById('board').appendChild(row);
    for (x = 0; x < width; x++) {
      var box = document.createElement('button');
      box.classList = 'box';
      box.id = +y + ',' + x;
      document.getElementById('row' + y).appendChild(box);
      document.getElementById(y + ',' + x).onclick = clickedbox;
      userfeild[y][x] = '/';
    }
  }
}

function clickedbox() {
  var y = this.id.split(',')[0];
  var x = this.id.split(',')[1];
  if (boxs == 0) {
    createmineboard(x, y)
  }
  autoclick(x, y);
}

function autoclick(x, y) {
  userfeild[y][x] = feild[y][x];
  boxs = boxs + 1;
  document.getElementById(y + ',' + x).innerHTML = feild[y][x];
  document.getElementById(y + ',' + x).classList = 'clickedbox';
  console.log(userfeild[y][x] + ' | x:' + x + ' | y:' + y);
  document.getElementById(y + ',' + x).onclick = '';
  if (feild[y][x] == 9) {
    //gameover();
  } else if (feild[y][x] == 0) {
    var check = [
      [-1, 0, 1, -1, 1, -1, 0, 1],
      [-1, -1, -1, 0, 0, 1, 1, 1]
    ];
    for (i = 0; i < 8; i++) {
      var newx = parseInt(x) + parseInt(check[0][i]);
      var newy = parseInt(y) + parseInt(check[1][i]);
      if (newx >= 0 && newx < width && newy >= 0 && newy < height) {
        if (userfeild[newy][newx] == '/') {
          autoclick(newx, newy);
        }
      }
    }
  }
}

function createmineboard(clickedx, clickedy) {
  for (x = 0; x < height; x++) {
    feild[x] = new Array;
    for (y = 0; y < width; y++) {
      feild[x][y] = 0;
    }
  }
  for (bomb = 0; bomb < bombs;) {
    var valid = false;
    let bombx = 0;
    let bomby = 0;
    bombx = Math.floor(Math.random() * width);
    bomby = Math.floor(Math.random() * height);
    if (feild[bomby][bombx] !== 9 && !(bombx == clickedx && bomby == clickedy)) {
      valid = true;
      feild[bomby][bombx] = 9;
      bomb++
    }
  }

  function nearbombs(x, y, w, h, feild) {
    var count = 0;
    if (y !== 0) {
      if (x !== 0) {
        if (feild[y - 1][x - 1] == 9) {
          count = count + 1
        }
      } //top left
      if (feild[y - 1][x] == 9) {
        count = count + 1
      } //top
      if (x !== w - 1) {
        if (feild[y - 1][x + 1] == 9) {
          count = count + 1
        }
      } //top right
    }
    if (x !== 0) {
      if (feild[y][x - 1] == 9) {
        count = count + 1
      }
    } //left
    if (x !== w - 1) {
      if (feild[y][x + 1] == 9) {
        count = count + 1
      }
    } // right

    if (y !== h - 1) {
      if (x !== 0) {
        if (feild[y + 1][x - 1] == 9) {
          count = count + 1
        }
      } //bottom left
      if (feild[y + 1][x] == 9) {
        count = count + 1
      } //bottom
      if (x !== w - 1) {
        if (feild[y + 1][x + 1] == 9) {
          count = count + 1
        }
      } //bottom right
    }
    return count;
  }
  for (y = 0; y < height; y++) {
    for (x = 0; x < width; x++) {
      if (feild[y][x] == 0) {
        feild[y][x] = nearbombs(x, y, width, height, feild);
      }
    }
  }
  console.log(feild);
}
.board {
  display: flex;
  flex-direction: column;
  height: fit-content;
  width: fit-content;
}

.row {
  display: flex;
  flex-direction: row;
  height: fit-content;
  width: fit-content;
  background-color: aquamarine;
}

.box {
  width: 30px;
  height: 30px;
  background-color: #C0C0C0;
  border-radius: 0;
  border: 0 solid;
  box-shadow: inset 2px 2px #FFFFFF, inset -2px -2px #808080, inset 4px 4px #FFFFFF, inset -4px -4px #808080;
}

.clickedbox {
  width: 30px;
  height: 30px;
  background-color: #C0C0C0;
  border-radius: 0;
  border: 0 solid;
  box-shadow: inset 2px 2px #808080;
}
<select name="dificulty" id="dificulty" onchange="selectdificulty()">
  <option value="1">begginer</option>
  <option value="2">intermediate</option>
  <option value="3">expert</option>
  <option value="4">custom</option>
</select>
<script src="windows.js"></script>
<script src="minesweeper.js"></script>
<div class="board" id="board">
</div>

错误隐藏在autoclick函数的for循环中:

for (i = 0; i < 8; i++) { ... }

您必须使用 var 关键字来创建局部迭代变量。否则,全局变量将被递归调用创建和重用。

for (var i = 0; i < 8; i++) { ... }

我最喜欢的游戏。