js五子棋效果
任务分解
一、绘制棋盘
二、绑定事件
1、先计算出需要绘制棋子的坐标 即将来绘制的棋子在哪个单元格内
2、绘制棋子 首先判断棋子是否存在 应该添加到哪个单元格内,分四种情况:
1.1 正常情况
1.2 最右侧 超出边界只能放在最后一个单元格内
1.3 左下侧 超出边界只能放在最后一个单元格内
1.4 右下侧 超出边界只能放在最后一个单元格内
3、当5个连续的棋子一样就算赢了 游戏结束 处理结束的逻辑 五个连续的需要处理四种情况:
1.1 横向的5个连续相同的棋子
1.2 竖着的5个连续相同的棋子
1.3 二个斜着的5个连续相同的棋子
<!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 class="container"> <table class="chessboard"></table> </div> <script src="./js/index.js"></script> </body> </html>
*{ /* margin: 0; padding: 0; */ } .container{ width: 500px; height: 500px; border: 1px solid #ccc; background-color: bisque; margin: 30px auto; display: flex; justify-content: center; align-items: center; } .chessboard{ border-collapse: collapse; border-spacing: 0; width: 94%; height: 94%; } .chessboard td{ border: 1px solid #000; position: relative; } .chess{ position: absolute; top: -50%; left: -50%; width: 80%; height: 80%; background-color: lightgrey; border-radius: 50%; color: lightgrey; font-size: 12px; font-weight: bold; /* 弹性盒文字居中 */ display: flex; align-items: center; justify-content: center; } .white{ background: #fff; } .blackc{ background-color: #000; } .win{ border: 1px solid red; box-shadow: 0 0 3px 2px red; }
function $(selector) { return document.querySelector(selector); } function $$(selector) { return document.querySelectorAll(selector); } var chessboard = document.querySelector('.chessboard'); var whichOne = "white"; //生成的最大范围区间 var sectionNum = 14; //是否结束 var isGameOver = false; var chessArr = []; function initChessboard() { var tableContent = ''; for (var i = 0; i < sectionNum; i++) { var row = `<tr>`; for (var j = 0; j < sectionNum; j++) { row += `<td data-row="${i}" data-line="${j}"></td>`; } row += '</tr>'; tableContent += row; } chessboard.innerHTML = tableContent; } //offsetLeft 一个元素相对于父元素的的水平偏移量 function bindEvent() { chessboard.addEventListener('click', function (e) { console.log(e); if (!isGameOver) { var temp = Object.assign({}, e.target.dataset); if (e.target.nodeName === 'TD') { //首先判断点击的td 所处的坐标 (从而计算出 棋子在哪个单元格) //比较鼠标点击的位置 与单元格的一半哪个大哪个小 从而计算出棋子是在当前单元格还是在下一个单元格内 //求出单元格的宽高 var tdw = chessboard.clientWidth * 0.94 / sectionNum; //比一半小则保留当前在当前单元格内 //比一半大则保留在下一个单元格内 var positionX = e.offsetX > tdw / 2; var positionY = e.offsetY > tdw / 2; //计算出棋子的坐标 也就是在哪个单元格内 var chessPoint = { x: positionX ? parseInt(temp.line) + 1 : parseInt(temp.line), y: positionY ? parseInt(temp.row) + 1 : parseInt(temp.row), c: whichOne } //绘制棋子 chessMove(chessPoint); } } else { //结束了是否要重新开始 if (window.confirm('恭喜你赢了,是否要重新开始?')) { //重新开始 重新绘制 数组置空 isGameOver = false; initChessboard(); chessArr = []; } } }) } function chessMove(chessPoint) { //检测棋子已经绘制 在点击到当前范围内不在绘制棋子 //判断棋子是否已经存在 if (exist(chessPoint) && !isGameOver) { //绘制棋子 就是将div添加到单元格内 var newDiv = `<div class="chess ${chessPoint.c}" data-row="${chessPoint.y}" data-line="${chessPoint.x}">`; chessArr.push(chessPoint); //添加到哪个单元格内分四种情况 (处理边界条件) //正常情况 if (chessPoint.x < 14 && chessPoint.y < 14) { var tdP = $(`td[data-row='${chessPoint.y}'][data-line='${chessPoint.x}']`); console.log(tdP) tdP.innerHTML += newDiv; } //最右侧 超出边界只能放在最后一个单元格内 if (chessPoint.x === 14 && chessPoint.y < 14) { var tdP = $(`td[data-row='${chessPoint.y}'][data-line='${chessPoint.x - 1}']`); tdP.innerHTML += newDiv; tdP.lastChild.style.left = '50%'; } //左下侧 超出边界只能放在最后一个单元格内 if (chessPoint.x < 14 && chessPoint.y === 14) { var tdP = $(`td[data-row='${chessPoint.y - 1}'][data-line='${chessPoint.x}']`); tdP.innerHTML += newDiv; tdP.lastChild.style.top = '50%'; } //右下侧 超出边界只能放在最后一个单元格内 if (chessPoint.x === 14 && chessPoint.y === 14) { var tdP = $(`td[data-row='${chessPoint.y - 1}'][data-line='${chessPoint.x - 1}']`); tdP.innerHTML += newDiv; tdP.lastChild.style.left = '50%'; tdP.lastChild.style.top = '50%'; } whichOne = whichOne === 'white' ? 'blackc' : 'white'; } //判断游戏是否结束 checker() } function exist(chessPoint) { var res = chessArr.find(function (item) { return item.x === chessPoint.x && item.y === chessPoint.y && item.c === chessPoint.c }) return res === undefined ? true : false; } function checker() { console.log(chessArr); for (var i = 0; i < chessArr.length; i++) { var chess = chessArr[i]; var chess2, chess3, chess4, chess5; //处理边界条件 5个连续的 分四种情况 //连续横着的 chess2 = chessArr.find(function (item) { return chess.x === item.x + 1 && chess.y === item.y && chess.c === item.c; }); chess3 = chessArr.find(function (item) { return chess.x === item.x + 2 && chess.y === item.y && chess.c === item.c; }); chess4 = chessArr.find(function (item) { return chess.x === item.x + 3 && chess.y === item.y && chess.c === item.c; }); chess5 = chessArr.find(function (item) { return chess.x === item.x + 4 && chess.y === item.y && chess.c === item.c; }); if (chess2 && chess3 && chess4 && chess5) { end(chess, chess2, chess3, chess4, chess5); } //连续竖着的 chess2 = chessArr.find(function (item) { return chess.y === item.y + 1 && chess.x === item.x && chess.c === item.c; }) chess3 = chessArr.find(function (item) { return chess.y === item.y + 2 && chess.x === item.x && chess.c === item.c; }) chess4 = chessArr.find(function (item) { return chess.y === item.y + 3 && chess.x === item.x && chess.c === item.c; }) chess5 = chessArr.find(function (item) { return chess.y === item.y + 4 && chess.x === item.x && chess.c === item.c; }) if (chess2 && chess3 && chess4 && chess5) { end(chess, chess2, chess3, chess4, chess5); } //连续斜着的 chess2 = chessArr.find(function (item) { return chess.x === item.x + 1 && chess.y === item.y + 1 && chess.c === item.c; }); chess3 = chessArr.find(function (item) { return chess.x === item.x + 2 && chess.y === item.y + 2 && chess.c === item.c; }); chess4 = chessArr.find(function (item) { return chess.x === item.x + 3 && chess.y === item.y + 3 && chess.c === item.c; }); chess5 = chessArr.find(function (item) { return chess.x === item.x + 4 && chess.y === item.y + 4 && chess.c === item.c; }); if (chess2 && chess3 && chess4 && chess5) { end(chess, chess2, chess3, chess4, chess5); } //反斜着的 chess2 = chessArr.find(function (item) { return chess.x === item.x - 1 && chess.y === item.y + 1 && chess.c === item.c; }); chess3 = chessArr.find(function (item) { return chess.x === item.x - 2 && chess.y === item.y + 2 && chess.c === item.c; }); chess4 = chessArr.find(function (item) { return chess.x === item.x - 3 && chess.y === item.y + 3 && chess.c === item.c; }); chess5 = chessArr.find(function (item) { return chess.x === item.x - 4 && chess.y === item.y + 4 && chess.c === item.c; }); if (chess2 && chess3 && chess4 && chess5) { end(chess, chess2, chess3, chess4, chess5); } } } function end() { if (!isGameOver) { isGameOver = true; //结束之后显示棋子的顺序 for (var i = 0; i < chessArr.length; i++) { $(`div[data-row='${chessArr[i].y}'][data-line='${chessArr[i].x}']`).innerHTML = i + 1; } //给胜利的棋子加高亮显示 for (var j = 0; j < arguments.length; j++) { console.dir($(`div[data-row='${arguments[j].y}'][data-line='${arguments[j].x}']`)) $(`div[data-row='${arguments[j].y}'][data-line='${arguments[j].x}']`).classList.add('win'); } } } function main() { //初始化棋盘 initChessboard(); //绑定监听事件 bindEvent(); } main();