window.onload = function() {
var row = 4;
var col = 4;
var num = 1;
// 判断踩雷之后不能胜利
var gg = false;
// 生成地图
function mineMap(r, c, num) {
// 定义行
var map = [];
//给行数,生成二维数组
for (var i = 0; i < r; i++) {
map[i] = new Array()
}
// 赋值
for (var i = 0; i < map.length; i++) {
for (var j = 0; j < c; j++) {
// //周围的地雷数
map[i][j] = 0;
}
}
var plus = function(array, x, y) {
if (x >= 0 && x < r && y >= 0 && y < c) {
if (array[x][y] !== 9) {
array[x][y]++
}
}
}
for (var i = 0; i < num; i++) {
var x = Math.floor(Math.random() * r)
var y = Math.floor(Math.random() * c)
if (map[x][y] != 9) {
map[x][y] = 9
//上下6个 +1
for (var j = -1; j < 2; j++) {
//上三个
plus(map, x - 1, y + j)
//下三个
plus(map, x + 1, y + j)
}
//左右2个 +1
plus(map, x, y - 1)
plus(map, x, y + 1)
} else {
//重新随机
num++
}
}
return map;
}
//先通过x轴数量写入ul,再讲过y轴的属性写入li
function writeHtml(map) {
// 获取盒子
var gameBox = document.querySelector(".gameBox");
// 声明空字符串,存放生成的ul、li
var gridHTML = "";
for (var i = 0; i < map.length; i++) {
gridHTML += '
';
//生成li
for (var j = 0; j < map[0].length; j++) {
var m = map[i][j]
if (m == 0) {
m = "";
}
gridHTML += "
" +
"" + m + "" +
"" +
"
"
}
gridHTML += '
'
gameBox.innerHTML = gridHTML;
}
}
//给方格绑定事件, 点开数字 地雷 右键标记
function show() {
// 获取行ul
var rows = document.querySelectorAll(".row");
// 遍历所有ul
for (var i = 0; i < rows.length; i++) {
var element = rows[i];
// 添加点击事件
element.onclick = function(event) {
// 当前点击元素
var el = event.target;
// 判断是否为li
if (el.nodeName != "LI") {
return;
}
//todo 判断是否被打开以及标记了
if (el.style.background == "white" || !el.children[1].classList.contains("hide")) {
return;
}
// 获取span标签内容
var mineNum = el.children[0].innerHTML;
if (mineNum !== "9" && el.style.background !== "white") {
// 空白连锁打开
if (mineNum == "") {
var x = parseInt(el.parentNode.dataset.x);
var y = parseInt(el.dataset.y);
showNoMine(x, y);
}
// li背景变白色;span显示
el.style.background = "white";
el.children[0].style.display = "inline";
// 判断打开数量
clearMineNum++;
// 胜利函数
judgeVictory()
} else if (mineNum == "9") {
// 清除胜利计时器
clearInterval(stopTime);
// li添加类名
el.classList.add("boom");
alert("你真菜!")
gg = true;
// 显示所有地雷,获取所有li
var all = document.querySelectorAll(".col");
// 放置所有的地雷
var ff = [];
var allnum = 0;
// 遍历所有li
for (var i = 0; i < all.length; i++) {
if (all[i].children[0].innerHTML == "9") {
// 雷赋值给数组
ff[allnum] = all[i];
allnum++;
}
}
// 设置一个计时器一个一个打开雷
allnum = 0;
var stop = setInterval(function() {
ff[allnum].classList.add("boom")
allnum++;
// 判断结束条件
if (allnum == ff.length) {
// 清除计时器
clearInterval(stop);
}
}, 30)
}
}
// 右键标记地雷
element.oncontextmenu = function(event) {
// 阻止右键菜单
event.preventDefault();
// 获取当前点击节点
var el = event.target;
// 判断是否是
if (el.parentNode.nodeName == "LI") {
el = el.parentNode;
}
if (el.nodeName != "LI") {
return;
}
// 获取img
var classList = el.children[1].classList;
// 剩余雷数
var residue = document.querySelector(".residue");
var mineNum = parseInt(residue.innerHTML);
// 如果没有旗子,没有被点开,可以插旗子
if (classList.contains("hide") && el.style.background != "white") {
// 移除隐藏
classList.remove("hide");
// 获取雷数
mineNum--;
} else if (el.style.background != "white") {
classList.add("hide");
// 判断雷数
if (mineNum < num) {
mineNum++;
}
}
// 剩余雷数
residue.innerHTML = mineNum;
}
}
}
function judgeVictory() {
//游戏胜利
if (clearMineNum === (row * col - num)) {
//做一个小动画
var all = document.querySelectorAll(".col");
var allNum = 0;
var stop = setInterval(function() {
var r = Math.floor(Math.random() * 256)
var g = Math.floor(Math.random() * 256)
var b = Math.floor(Math.random() * 256)
all[allNum].style.background = "rgba(" + r + "," + g + "," + b + ",0.6)";
//将旗子和span都隐藏
all[allNum].children[0].style.display = "none"
all[allNum].children[1].style.display = "none"
allNum++
if (allNum === all.length) {
clearInterval(stop)
if (!gg) {
alert("大吉大利,今晚吃鸡")
init(row, col, num)
}
}
}, 20)
}
}
//自动打开空格
function showNoMine(x, y) {
for (var i = -1; i <= 1; i++) {
if (x + i >= 0 && x + i < row) {
// 获取当前行
var rowElement = document.querySelectorAll(".row")[x + i];
for (var j = -1; j <= 1; j++) {
if (y + j >= 0 && y + j < col) {
//获取当前单元格
var el = rowElement.children[y + j]
//自动打开必须是未打开的方格
if (el.style.background != "white") {
el.style.background = "white"
el.children[0].style.display = "inline"
//打开方格数量+1
clearMineNum++
//判断游戏是否胜利
judgeVictory(clearMineNum)
if (el.children[0].innerText === "") {
showNoMine(x + i, y + j)
}
}
}
}
}
// if (x + i >= 0 && x + i < row) {
// // 获取当前行
// var rowElement = document.querySelectorAll(".row")[x + i];
// for (var j = -1; j <= 1; j++ && y + j < col) {
// // 获取当前单元格
// var el = rowElement.children[y + j];
// if (el.style.background !== "white") {
// el.style.background = "white";
// el.children[0].style.display = "inline";
// // 打开放格数量加1
// clearMineNum++;
// // 判断游戏是否胜利
// judgeVictory(clearMineNum);
// // 判断打开周围的放格周围是否为空
// if (el.children[0].innerHTML === "") {
// showNoMine(x + i, y + j)
// }
// }
// }
// }
}
}
//初始化方法
var stopTime;
function init(row, col, num) {
//数据初始化
clearMineNum = 0
gg = false;
//清除原来的地图,生成新的地图
var box = document.querySelector(".gameBox")
box.innerHTML = "";
var map = mineMap(row, col, num);
// 新建地图
writeHtml(map);
show()
//将雷数写入html中
var residue = document.querySelector(".residue")
residue.innerHTML = num
// 获取计时
var tick = document.querySelector(".tick");
var i = 0;
// 初始化
tick.innerHTML = i;
// 清除计时
clearInterval(stopTime);
// 时间计时器
stopTime = setInterval(function() {
tick.innerHTML = ++i
}, 1000)
}
// 重置
var restart = document.querySelector(".restart");
restart.onclick = function(event) {
//阻止冒泡
event.stopPropagation()
init(row, col, num)
}
// 自定义
var level = document.querySelector(".level")
level.onclick = function(event) {
var el = event.target;
switch (el.innerHTML) {
case "初级":
row = 9;
col = 9;
num = 10;
init(row, col, num)
break;
case "中级":
row = 16;
col = 16;
num = 40;
init(row, col, num)
break;
case "高级":
row = 16;
col = 30;
num = 479;
init(row, col, num)
break;
case "魔鬼级":
row = 40;
col = 50;
num = 300;
init(row, col, num)
break;
case "自定义":
row = prompt("请输入列数!");
col = prompt("请输入行数!");
num = prompt("请输入你想要的雷数,(请慎重选择)");
init(row, col, num);
break;
default:
row = 9;
col = 9;
num = 10;
init(row, col, num)
break;
}
}
init(row, col, num)
}