web 五子棋小游戏

效果图

源码

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();
相关推荐
林涧泣5 分钟前
【Uniapp-Vue3】uni-icons的安装和使用
前端·vue.js·uni-app
勤又氪猿7 分钟前
【问题】Qt c++ 界面 lineEdit、comboBox、tableWidget.... SIGSEGV错误
开发语言·c++·qt
拉一次撑死狗17 分钟前
Vue基础(2)
前端·javascript·vue.js
Ciderw19 分钟前
Go中的三种锁
开发语言·c++·后端·golang·互斥锁·
查理零世20 分钟前
【算法】经典博弈论问题——巴什博弈 python
开发语言·python·算法
jk_1011 小时前
MATLAB中insertAfter函数用法
开发语言·matlab
热情仔1 小时前
mock可视化&生成前端代码
前端
m0_748246351 小时前
SpringBoot返回文件让前端下载的几种方式
前端·spring boot·后端
啥也学不会a1 小时前
PLC通信
开发语言·网络·网络协议·c#
wjs04061 小时前
用css实现一个类似于elementUI中Loading组件有缺口的加载圆环
前端·css·elementui·css实现loading圆环