作为继贪吃蛇练手后的第二个练习五子棋着实有点难,由于训练不多,主要是学习的视频教学
不多说了直接看效果发代码
html代码
在这里插入代码片
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="../css/index.css">
</head>
<body>
<div id="content">
<div class="level">
<button class="active">初级</button>
<button>中级</button>
<button>高级</button>
<button>重新开始</button>
</div>
<div class="gameBox">
</div>
<div class="mineNum">
剩余雷数 :<span class="numberLeishu"></span>
</div>
</div>
<script src="../js/index.js"></script>
</body>
</html>
css代码
#content{
margin:50px auto;
}
.level{
text-align: center;
margin: 10px;
}
.level button{
padding: 5px 15px;
background: #02a4ad;
border: none;
color: #fff;
border-radius: 3px;
outline:none;
cursor: pointer;
}
.level button.active{
background: #00abff;
}
.mineNum{
margin-top:10px;
text-align:center;
}
table{
border-spacing: 1px;
background: #929196;
margin:0 auto;
}
td{
padding: 0;
width:20px;
height:20px;
background:#ccc;
border:2px solid;
border-color: #fff #a1a1a1 #a1a1a1 #fff;
text-align: center;
line-height: 20px;
font-weight: bold;
}
.mine{
background: #d9d9d9 url(../images/dl.png);
background-size: cover;
}
.flag{
background: #ccc url(../images/hq.png);
background-size: cover;
}
td.zero{
border-color: #d9d9d9;
background: #d9d9d9;
}
td.one{
border-color: #d9d9d9;
background: #d9d9d9;
color:#0332fe;
}
td.two{
border-color: #d9d9d9;
background: #d9d9d9;
color: #019f02;
}
td.three{
border-color: #d9d9d9;
background: #d9d9d9;
color: #ff2600;
}
td.four{
border-color: #d9d9d9;
background: #d9d9d9;
color: #93208f;
}
td.five{
border-color: #d9d9d9;
background: #d9d9d9;
color: #ff7f29;
}
td.six{
border-color: #d9d9d9;
background: #d9d9d9;
color: #ff3fff;
}
td.seven{
border-color: #d9d9d9;
background: #d9d9d9;
color: #3fffbf;
}
td.eight{
border-color: #d9d9d9;
background: #d9d9d9;
color:#22ee0f;
}
js代码
function Mine(tr, td, mineNum) {
this.tr = tr; //行数
this.td = td; //列数
this.mineNum = mineNum;//雷数
this.squares = [];//一个二维数组,按照行和列的方式放雷
this.tds = []; //存储所有单元格的DOM
this.surplusMine = mineNum; //剩余雷的数量
this.allRight = false; //右击标出来的小红旗是否全是雷 用来判断游戏是否成功
this.parent = document.querySelector('.gameBox');
}
Mine.prototype.randomNum = function () {
var square = new Array(this.tr * this.td);//生成一个空数组但是有长度,长度为格子的总数
for (var i = 0; i < square.length; i++) {
square[i] = i;
}
square.sort(function () {
return 0.5 - Math.random()
})
return square.slice(0, this.mineNum);
}
Mine.prototype.init = function () {
// console.log(this.randomNum());
var rn = this.randomNum(); //雷在格子里的位置
var n = 0; //用来找到格子对应的索引
for (var i = 0; i < this.tr; i++) {
this.squares[i] = [];
for (var j = 0; j < this.td; j++) {
// this.squares[i][j] =
n++;
//取一个方块在数组里的数据要是用行和列的方式去取
//找方块周围的数字要用坐标的形式去取,(行和列的形式与坐标形式恰好相反)
if (rn.indexOf(n) != -1) {
// 如果这个条件成立,说明现在循环到这个索引在雷的数组里找到了,那就表示这个索引对应的是个雷
this.squares[i][j] = { type: 'mine', x: j, y: i };
} else {
this.squares[i][j] = { type: 'number', x: j, y: i, value: 0 };
}
}
}
// console.log(this.squares);
this.updataNum();
this.creatDom();
this.parent.oncontextmenu = function () {
return false;
}
//剩余雷数
this.mineNumDom = document.querySelector('.numberLeishu');
this.mineNumDom.innerHTML = this.surplusMine;
};
//创建表格
Mine.prototype.creatDom = function () {
var This = this;
var table = document.createElement('table');
for (var i = 0; i < this.tr; i++) { //行
var domTr = document.createElement('tr');
this.tds[i] = [];//将所有行放在一个空数组里
for (var j = 0; j < this.td; j++) { //列
var domTd = document.createElement('td');
// domTd.innerHTML = 0;
domTd.pos = [i, j];//把格子对应的行和列存到格子身上,为了下面通过这个值去数组里取得相应的数据
domTd.onmousedown = function () {
This.play(event, this)//This指的是实例对象,this指的是年级的那个td
}
this.tds[i][j] = domTd; //这里把用DOM所创建的td添加到数组当中
// if (this.squares[i][j].type == 'mine') {
// domTd.className = 'mine';
// }
// if (this.squares[i][j].type == "number") {
// domTd.innerHTML = this.squares[i][j].value;
// }
domTr.appendChild(domTd);
}
table.appendChild(domTr);
}
this.parent.innerHTML = '';//类似于清屏功能
this.parent.appendChild(table);
};
Mine.prototype.getAround = function (square) {
var x = square.x;
var y = square.y;
var result = [];//找到格子的坐标返回出去
for (var i = x - 1; i <= x + 1; i++) {
for (var j = y - 1; j <= y + 1; j++) {
if (
i < 0 || //格子左边超了
j < 0 || //格子上边超了
i > this.td - 1 || //格子右边超了
j > this.tr - 1 || //格子下边超了
(i == x && j == y) || //格子自己
this.squares[j][i].type == 'mine' //格子周围是雷
) {
continue
}
result.push([j, i]);
}
}
return result
};
//更新所有数字
Mine.prototype.updataNum = function () {
for (i = 0; i < this.tr; i++) {
for (var j = 0; j < this.td; j++) {
//只更新雷周围的数字
if (this.squares[i][j].type == 'number') {
continue;
}
var num = this.getAround(this.squares[i][j]);//获取到每一个雷周围的数字
for (var k = 0; k < num.length; k++) {
// num[i] == [0, 1]
// num[i][0] = 0;
// num[i][1] = 1
this.squares[num[k][0]][num[k][1]].value += 1;
}
// console.log(num);
}
}
// console.log(this.squares);
}
// x-1,y-1 x,y-1 x+1,y-1
// x-1,y x,y x+1,y
// x-1,y+1 x,y+1 x+1,y+1
//找周围的8个方格
Mine.prototype.play = function (ev, obj) {
var This = this;
if (ev.which == 1) {
//点击的是左键
// console.log(obj);
var curSquare = this.squares[obj.pos[0]][obj.pos[1]];
var cl = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight'];
// console.log(curSquare);
if (curSquare.type == "number") {
obj.innerHTML = curSquare.value;
obj.className = cl[curSquare.value];
if (curSquare.value == 0) {
//点到数字0的情况
//1、显示自己
//2、找四周
// 1、显示四周(如果四周的值有不为0即停止)
// 2、如果为0
// 1、显示四周(如果四周的值有不为0即停止)
// 2、如果为0
// 1、显示四周(如果四周的值有不为0即停止)
// 2、如果为0
// 1、显示四周(如果四周的值有不为0即停止)
// 2、如果为0
obj.innerHTML = ''
function getAllzero(square) {
var around = This.getAround(square);//找到了周围的n个格子
for (var i = 0; i < around.length; i++) {
var x = around[i][0]; //行
var y = around[i][1]; //列
This.tds[x][y].className = cl[This.squares[x][y].value];
if (This.squares[x][y].value == 0) {//递归条件
// getAllzero(This.squares[x][y]);
if (!This.tds[x][y].check) {
This.tds[x][y].check = true;
getAllzero(This.squares[x][y]);
}
}
else {
This.tds[x][y].innerHTML = This.squares[x][y].value;
}
}
}
getAllzero(curSquare);
//点到非0
}
} else {
// console.log('点到雷了');
this.gameOver(obj);
}
}
//点击的邮件
if (ev.which == 3) {
if (obj.className && obj.className != 'flag') {
return;
}
obj.className = obj.className == 'flag' ? '' : 'flag';
if (this.squares[obj.pos[0]][obj.pos[1]].type == 'mine') {
this.allRight = true;
} else {
this.allRight = false;
}
if (obj.className == 'flag') {
this.mineNumDom.innerHTML = --this.surplusMine;
} else {
this.mineNumDom.innerHTML = ++this.surplusMine;
}
if (this.surplusMine == 0) {
if (this.allRight) {
alert('恭喜过关');
} else {
alert('游戏失败');
}
}
}
};
Mine.prototype.gameOver = function (clickTd) {
for (var i = 0; i < this.tr; i++) {
for (var j = 0; j < this.td; j++) {
if (this.squares[i][j].type == 'mine') {
this.tds[i][j].className = 'mine';
}
this.tds[i][j].onmousedown = null;
}
}
if (clickTd) {
clickTd.style.backgroundColor = '#f00';
}
}
// 上边button的功能
var btns = document.querySelectorAll('.level button');
var mine = null;
var ln = 0;
var arr = [[9, 9, 10], [16, 16, 40], [28, 28, 99]];
for (let i = 0; i < btns.length - 1; i++) {
btns[i].onclick = function () {
btns[ln].className = '';
this.className = 'active';
mine = new Mine(...arr[i]);
mine.init();
ln = i;
}
}
btns[0].onclick();//初始化
btns[3].onclick = function(){
mine.init();
}
// var mine = new Mine(20, 20, 10);
// mine.init();
// console.log(mine.getAround(mine.squares[0][0]));