You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

扫雷游戏按钮事件监听器中函数无法运行问题求助

扫雷游戏问题修复方案

核心问题说明

  • 原代码在生成tile的循环中重复绑定按钮点击事件,调用getMinePositions生成新坐标后没有更新每个tile的mine属性,导致地雷位置不会变化
  • 游戏失败后绑定的stopImmediatePropagation拦截事件没有移除,导致无法点击操作

修复代码

仅需要修改JS代码,HTML和CSS无需改动,修改后完整JS代码如下:

const TILE_STATUSES = {
  HIDDEN: "hidden",
  MINE: "mine",
  NUMBER: "number",
};

function createBoard(boardSize, numberOfMines) {
  const board = [];
  const minePositions = getMinePositions(boardSize, numberOfMines);

  for (let x = 0; x < boardSize; x++) {
    const row = [];
    for (let y = 0; y < boardSize; y++) {
      const element = document.createElement("div");
      element.dataset.status = TILE_STATUSES.HIDDEN;

      const tile = {
        element,
        x,
        y,
        mine: minePositions.some(positionMatch.bind(null, { x, y })),
        get status() {
          return this.element.dataset.status;
        },
        set status(value) {
          this.element.dataset.status = value;
        },
      };

      row.push(tile);
    }
    board.push(row);
  }
  return board;
}

function revealTile(tile) {
  if (tile.status !== TILE_STATUSES.HIDDEN) {
    return;
  }
  if (tile.mine) {
    tile.status = TILE_STATUSES.MINE;
    return;
  }
  tile.status = TILE_STATUSES.NUMBER;
}

function checkLose(board) {
  return board.some((row) => {
    return row.some((tile) => {
      return tile.status === TILE_STATUSES.MINE;
    });
  });
}

function getMinePositions(boardSize, numberOfMines) {
  const positions = [];

  while (positions.length < numberOfMines) {
    const position = {
      x: randomNumber(boardSize),
      y: randomNumber(boardSize),
    };

    if (!positions.some(positionMatch.bind(null, position))) {
      positions.push(position);
    }
  }

  return positions;
}

function positionMatch(a, b) {
  return a.x === b.x && a.y === b.y;
}

function randomNumber(size) {
  return Math.floor(Math.random() * size);
}

const BOARD_SIZE = 5;
const NUMBER_OF_MINES = 2;

const board = createBoard(BOARD_SIZE, NUMBER_OF_MINES);
const boardElement = document.querySelector(".board");

board.forEach((row) => {
  row.forEach((tile) => {
    boardElement.append(tile.element);
    tile.element.addEventListener("click", () => {
      revealTile(tile);
      checkGameEnd();
    });
    tile.element.addEventListener("contextmenu", (e) => {
      e.preventDefault();
    });
  });
});

boardElement.style.setProperty("--size", BOARD_SIZE);

function checkGameEnd() {
  const lose = checkLose(board);

  if (lose) {
    boardElement.addEventListener("click", stopProp, { capture: true });
    boardElement.addEventListener("contextmenu", stopProp, { capture: true });
  }

  if (lose) {
    board.forEach((row) => {
      row.forEach((tile) => {
        if (tile.mine) revealTile(tile);
      });
    });
  }
}

function stopProp(a) {
  a.stopImmediatePropagation();
}

// 新增重置游戏逻辑
document.querySelector(".btn").addEventListener("click", resetGame);
function resetGame() {
  // 移除游戏结束拦截事件
  boardElement.removeEventListener("click", stopProp, { capture: true });
  boardElement.removeEventListener("contextmenu", stopProp, { capture: true });
  // 生成新地雷坐标
  const newMinePositions = getMinePositions(BOARD_SIZE, NUMBER_OF_MINES);
  // 重置所有tiles状态
  board.forEach(row => {
    row.forEach(tile => {
      tile.status = TILE_STATUSES.HIDDEN;
      tile.mine = newMinePositions.some(positionMatch.bind(null, {x: tile.x, y: tile.y}))
    })
  })
}

内容的提问来源于stack exchange,提问作者Bagnom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 14:15:02