效果图
源码
html
<!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>
css
.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;}
js
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 = true
for (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, chess5
console.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, chess5
chess2 = 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, chess5
chess2 = 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, chess5
chess2 = 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 0
chessArr.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 += newChess
tdPos.lastChild.style.left = '50%'
} else if (chessInfo.positionX < 14 && chessInfo.positionY === 14) {
const tdPos = $(`td[data-row="13"][data-col="${chessInfo.positionX}"]`)
tdPos.innerHTML += newChess
tdPos.lastChild.style.top = '50%'
} else if (chessInfo.positionX === 14 && chessInfo.positionY === 14) {
const tdPos = $(`td[data-row="13"][data-col="13"]`)
tdPos.innerHTML += newChess
tdPos.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 0
if (isGameOver) return alert('游戏已结束')
const temp = Object.assign({}, e.target.dataset)
const tdw = chessboard.clientWidth * 0.92 / 14
const tdh = chessboard.clientHeight * 0.92 / 14
const positionX = e.offsetX > tdw / 2
const 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 优化了性能
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();