任務分解
一、繪製棋盤
二、繫結事件
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();