js实现扫雷
实现扫雷游戏的基本思路
扫雷游戏的核心逻辑包括生成雷区、计算周围雷数、处理点击事件以及判断游戏胜负。以下是实现扫雷的关键步骤。
初始化游戏棋盘
创建一个二维数组表示游戏棋盘,初始化时填充为0或随机布置地雷。地雷可以用特定值(如-1)标记。
function createBoard(rows, cols, mines) {
const board = Array(rows).fill().map(() => Array(cols).fill(0));
let minesPlaced = 0;
while (minesPlaced < mines) {
const x = Math.floor(Math.random() * rows);
const y = Math.floor(Math.random() * cols);
if (board[x][y] !== -1) {
board[x][y] = -1;
minesPlaced++;
}
}
return board;
}
计算周围雷数
遍历棋盘,对非雷格子计算周围8个格子中的雷数。

function calculateNumbers(board) {
const rows = board.length;
const cols = board[0].length;
const directions = [
[-1, -1], [-1, 0], [-1, 1],
[0, -1], [0, 1],
[1, -1], [1, 0], [1, 1]
];
for (let x = 0; x < rows; x++) {
for (let y = 0; y < cols; y++) {
if (board[x][y] === -1) continue;
let count = 0;
for (const [dx, dy] of directions) {
const nx = x + dx, ny = y + dy;
if (nx >= 0 && nx < rows && ny >= 0 && ny < cols && board[nx][ny] === -1) {
count++;
}
}
board[x][y] = count;
}
}
}
处理点击事件
实现点击格子时的逻辑,包括揭示格子、递归揭示空白区域以及游戏结束判断。
function reveal(board, revealed, x, y) {
const rows = board.length;
const cols = board[0].length;
if (x < 0 || x >= rows || y < 0 || y >= cols || revealed[x][y]) return;
revealed[x][y] = true;
if (board[x][y] === -1) {
// 踩到雷,游戏结束
return false;
}
if (board[x][y] === 0) {
// 递归揭示周围的空白格子
const directions = [
[-1, -1], [-1, 0], [-1, 1],
[0, -1], [0, 1],
[1, -1], [1, 0], [1, 1]
];
for (const [dx, dy] of directions) {
reveal(board, revealed, x + dx, y + dy);
}
}
return true;
}
渲染游戏界面
使用HTML和CSS创建游戏界面,并通过JavaScript动态更新。

<div id="board" style="display: grid; grid-template-columns: repeat(10, 30px);"></div>
<script>
const rows = 10, cols = 10, mines = 15;
const board = createBoard(rows, cols, mines);
calculateNumbers(board);
const revealed = Array(rows).fill().map(() => Array(cols).fill(false));
const boardElement = document.getElementById('board');
for (let x = 0; x < rows; x++) {
for (let y = 0; y < cols; y++) {
const cell = document.createElement('div');
cell.style.width = '30px';
cell.style.height = '30px';
cell.style.border = '1px solid #000';
cell.style.display = 'flex';
cell.style.justifyContent = 'center';
cell.style.alignItems = 'center';
cell.addEventListener('click', () => {
if (!reveal(board, revealed, x, y)) {
alert('Game Over!');
}
renderBoard();
});
boardElement.appendChild(cell);
}
}
function renderBoard() {
const cells = boardElement.children;
for (let x = 0; x < rows; x++) {
for (let y = 0; y < cols; y++) {
const index = x * cols + y;
if (revealed[x][y]) {
cells[index].textContent = board[x][y] === -1 ? '💣' : board[x][y];
cells[index].style.backgroundColor = '#ddd';
} else {
cells[index].textContent = '';
cells[index].style.backgroundColor = '#fff';
}
}
}
}
</script>
添加标记功能
允许玩家右键标记疑似地雷的格子。
cell.addEventListener('contextmenu', (e) => {
e.preventDefault();
if (!revealed[x][y]) {
cells[index].textContent = cells[index].textContent === '🚩' ? '' : '🚩';
}
});
游戏胜负判断
检查是否所有非雷格子均被揭示或所有地雷被正确标记。
function checkWin(board, revealed) {
const rows = board.length;
const cols = board[0].length;
for (let x = 0; x < rows; x++) {
for (let y = 0; y < cols; y++) {
if (board[x][y] !== -1 && !revealed[x][y]) {
return false;
}
}
}
return true;
}
通过以上步骤,可以实现一个基本的扫雷游戏。可以根据需求进一步优化界面和添加更多功能,如计时器、难度选择等。






