效果图
源码
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Gomoku</title><link rel="stylesheet" href="./style/css/index.css">
</head><body><div class="container"><table class="chessboard"></table></div><script src="./js/index.js"></script>
</body></html>
.container{border: 3px double rgb(207, 188 , 188);width: 500px;height: 500px;margin: 50px auto;display: flex;justify-content: center;align-items: center;background-color: antiquewhite;
}
.chessboard{width: 92%;height: 92%;border-collapse: collapse;
}
.chessboard td{border: 1px solid black;position: relative;
}.chess{border:1px solid lightgrey;border-radius: 50%;position: absolute;left: -50%;top: -50%;width: 90%;height: 90%;color: lightgrey;font-size: 12px;font-weight: bold;display: flex;justify-content: center;align-items: center;
}.white{background-color: white;
}
.black{background-color: black;}
const $ = selector => document.querySelector(selector)
const $$ = selector => document.querySelectorAll(selector)
const chessboard = $('.chessboard')
let isGameOver = false
let currentPlayer = 'black'
const chessArr = []
const initChessboard = () => {let tableContent = ''for (let i = 0; i < 14; i++) {let row = '<tr>'for (let ii = 0; ii < 14; ii++) {row += `<td data-row="${i}" data-col="${ii}"></td>`}row += '</tr>'tableContent += row}chessboard.innerHTML = tableContent
}
const end = () => {isGameOver = truefor (let i = 0; i < chessArr.length; i++) {const e = chessArr[i];$(`div[data-row="${e.positionY}"][data-col="${e.positionX}"]`).innerHTML = i + 1}
}
const check = () => {// 检查有没有竖着的五子for (const curChess of chessArr) {let chess2, chess3, chess4, chess5console.log(curChess)chess2 = chessArr.some(item => item.positionX === curChess.positionX && item.positionY === curChess.positionY + 1 && item.color === curChess.color)chess3 = chessArr.some(item => item.positionX === curChess.positionX && item.positionY === curChess.positionY + 2 && item.color === curChess.color)chess4 = chessArr.some(item => item.positionX === curChess.positionX && item.positionY === curChess.positionY + 3 && item.color === curChess.color)chess5 = chessArr.some(item => item.positionX === curChess.positionX && item.positionY === curChess.positionY + 4 && item.color === curChess.color)if (chess2 && chess3 && chess4 && chess5) {end()}}// 检查有没有横着的五子for (const curChess of chessArr) {let chess2, chess3, chess4, chess5chess2 = chessArr.some(item => item.positionX === curChess.positionX + 1 && item.positionY === curChess.positionY && item.color === curChess.color)chess3 = chessArr.some(item => item.positionX === curChess.positionX + 2 && item.positionY === curChess.positionY && item.color === curChess.color)chess4 = chessArr.some(item => item.positionX === curChess.positionX + 3 && item.positionY === curChess.positionY && item.color === curChess.color)chess5 = chessArr.some(item => item.positionX === curChess.positionX + 4 && item.positionY === curChess.positionY && item.color === curChess.color)console.log(chess2, chess3, chess4, chess5, chessArr)if (chess2 && chess3 && chess4 && chess5) {end()}}// 检查有没有斜着的五子for (const curChess of chessArr) {let chess2, chess3, chess4, chess5chess2 = chessArr.some(item => item.positionX === curChess.positionX + 1 && item.positionY === curChess.positionY + 1)chess3 = chessArr.some(item => item.positionX === curChess.positionX + 2 && item.positionY === curChess.positionY + 2)chess4 = chessArr.some(item => item.positionX === curChess.positionX + 3 && item.positionY === curChess.positionY + 3)chess5 = chessArr.some(item => item.positionX === curChess.positionX + 4 && item.positionY === curChess.positionY + 4)if (chess2 && chess3 && chess4 && chess5) {end()}}// 检查有没有斜着的五子for (const curChess of chessArr) {let chess2, chess3, chess4, chess5chess2 = chessArr.some(item => item.positionX === curChess.positionX - 1 && item.positionY === curChess.positionY + 1)chess3 = chessArr.some(item => item.positionX === curChess.positionX - 2 && item.positionY === curChess.positionY + 2)chess4 = chessArr.some(item => item.positionX === curChess.positionX - 3 && item.positionY === curChess.positionY + 3)chess5 = chessArr.some(item => item.positionX === curChess.positionX - 4 && item.positionY === curChess.positionY + 4)if (chess2 && chess3 && chess4 && chess5) {end()}}
}
const exists = (row, col) => chessArr.some(item => item.row === row && item.col === col)
const chessDrawing = chessInfo => {if (exists(chessInfo) || isGameOver) return void 0chessArr.push(chessInfo)const newChess = `<div class="chess ${chessInfo.color}" data-row="${chessInfo.positionY}" data-col="${chessInfo.positionX}"></div>`console.log(newChess)if (chessInfo.positionX < 14 && chessInfo.positionY < 14) {$(`td[data-row="${chessInfo.positionY}"][data-col="${chessInfo.positionX}"]`).innerHTML += newChess} else if (chessInfo.positionX === 14 && chessInfo.positionY < 14) {const tdPos = $(`td[data-row="${chessInfo.positionY}"][data-col="13"]`)tdPos.innerHTML += newChesstdPos.lastChild.style.left = '50%'} else if (chessInfo.positionX < 14 && chessInfo.positionY === 14) {const tdPos = $(`td[data-row="13"][data-col="${chessInfo.positionX}"]`)tdPos.innerHTML += newChesstdPos.lastChild.style.top = '50%'} else if (chessInfo.positionX === 14 && chessInfo.positionY === 14) {const tdPos = $(`td[data-row="13"][data-col="13"]`)tdPos.innerHTML += newChesstdPos.lastChild.style.top = '50%'tdPos.lastChild.style.left = '50%'}currentPlayer = currentPlayer === 'black' ? 'white' : 'black'check()
}const bindEvent = () => {chessboard.addEventListener('click', e => {if (e.target.nodeName !== 'TD') return void 0if (isGameOver) return alert('游戏已结束')const temp = Object.assign({}, e.target.dataset)const tdw = chessboard.clientWidth * 0.92 / 14const tdh = chessboard.clientHeight * 0.92 / 14const positionX = e.offsetX > tdw / 2const positionY = e.offsetY > tdh / 2//确定棋子信息const chessInfo = {positionX: positionX ? parseInt(temp.col) + 1 : parseInt(temp.col),positionY: positionY ? parseInt(temp.row) + 1 : parseInt(temp.row),color: currentPlayer}chessDrawing(chessInfo)})
}
const main = () => {//初始化棋盘initChessboard()//绑定对应事件bindEvent()
}main()
--------------------2024-12-15号更新-----------------------
主要更新了js 优化了性能
const $ = selector => document.querySelector(selector);
const $$ = selector => document.querySelectorAll(selector);// 获取棋盘元素
const chessboard = $('.chessboard');// 游戏状态变量
let isGameOver = false;
let currentPlayer = 'black';
const chessArr = [];// 初始化棋盘
const initChessboard = () => {const rows = Array.from({ length: 14 }, (_, rowIndex) =>`<tr>${Array.from({ length: 14 }, (_, colIndex) =>`<td data-row="${rowIndex}" data-col="${colIndex}"></td>`).join('')}</tr>`).join('');chessboard.innerHTML = rows;
};// 结束游戏
const end = () => {isGameOver = true;for (let i = 0; i < chessArr.length; i++) {const e = chessArr[i];const chessElement = $(`div[data-row="${e.positionY}"][data-col="${e.positionX}"]`);// 创建一个新的元素来显示序号const numberElement = document.createElement('span');numberElement.textContent = i + 1;numberElement.classList.add('end-number'); // 添加一个类以便应用样式// 将序号元素添加到棋子中if (!chessElement.querySelector('.end-number')) {chessElement.appendChild(numberElement);}}
};// 检查是否有五子连珠
const check = () => {for (let i = chessArr.length - 1; i >= 0; i--) {const curChess = chessArr[i];const directions = [{ dx: 0, dy: 1 }, // 竖直{ dx: 1, dy: 0 }, // 水平{ dx: 1, dy: 1 }, // 斜对角(右下){ dx: -1, dy: 1 } // 斜对角(左下)];for (const dir of directions) {let count = 1;for (let step = 1; step < 5; step++) {const x = curChess.positionX + dir.dx * step;const y = curChess.positionY + dir.dy * step;const isExist = chessArr.some(item => item.positionX === x && item.positionY === y && item.color === curChess.color)if (x >= 0 && x < 14 && y >= 0 && y < 14 && isExist) {count++;} else {break;}}count >= 5 && end()}}
};// 检查是否存在相同位置的棋子
const exists = (positionX, positionY) =>chessArr.some(item => item.positionX === positionX && item.positionY === positionY);// 绘制棋子
const chessDrawing = ({ positionX, positionY, color }) => {if (exists(positionX, positionY) || isGameOver) return;chessArr.push({ positionX, positionY, color });const newChess = document.createElement('div');newChess.classList.add('chess', color);newChess.setAttribute('data-row', positionY);newChess.setAttribute('data-col', positionX);const td = $(`td[data-row="${positionY}"][data-col="${positionX}"]`);td.appendChild(newChess);currentPlayer = currentPlayer === 'black' ? 'white' : 'black';check();
};// 绑定事件监听器
const bindEvent = () => {chessboard.addEventListener('click', e => {if (e.target.nodeName !== 'TD' || isGameOver) return;const { row, col } = e.target.dataset;const positionX = parseInt(col);const positionY = parseInt(row);// 确定落子位置const offsetX = e.offsetX > (chessboard.clientWidth * 0.92 / 14) / 2;const offsetY = e.offsetY > (chessboard.clientHeight * 0.92 / 14) / 2;const chessInfo = {positionX: offsetX ? positionX + 1 : positionX,positionY: offsetY ? positionY + 1 : positionY,color: currentPlayer};chessDrawing(chessInfo);});
};// 主函数
const main = () => {initChessboard();bindEvent();
};main();