任务分解

一、绘制棋盘

二、绑定事件

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();

js五子棋效果的更多相关文章

  1. JS原生效果瀑布流布局的实现(一)

    JS原生效果 实现: HTML页面布局: <!DOCTYPE html> <html> <head> <meta charset="utf-8&qu ...

  2. js sleep效果

    js sleep效果 s = setInterval(function(){ //需要执行的函数 alert("我延迟了2秒弹出"); },2000); 并不是每2秒执行一次,而是 ...

  3. JS打字效果的动态菜单代码分享

    这篇文章主要介绍了JS打字效果的动态菜单,推荐给大家,有需要的小伙伴可以参考下. 这是一款基于javascript实现的打字效果的动态菜单特效代码,分享给大家学习学习. 小提示:浏览器中如果不能正常运 ...

  4. js 动画效果实现

    1. 实现方式 - 应用场景 自己写 - 简单的.不用 jq 的项目 jq - 普通动画 成熟插件 - 复杂动画 2. 相关文章 JavaScript基于时间的动画算法 九种原生js动画效果 Twee ...

  5. 页面倒计时跳转页面效果,js倒计时效果

    页面倒计时跳转页面效果,js倒计时效果 >>>>>>>>>>>>>>>>>>>> ...

  6. 非常不错的一个JS分页效果代码

    这里分享一个不错的js分页代码. 代码中cpage是页面计数,应为全局变量,可以随处调用它: totalpage是总页数. 与asp分页代码很类似,也是先取得记录总数,然后实现分页,基本的分页思路与原 ...

  7. 纯js倒计时效果(交流加群:452892873)(本群每天都更新学习资料)

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  8. js 技巧 (十)广告JS代码效果大全 【3】

    3.[允许关闭]     与前面两个代码不同的是,广告图下方增加了一个图片按纽,允许访客点击关闭广告图片,下面文本框中就是实现效果所需代码: var delta=0.015;     var coll ...

  9. js 技巧 (十)广告JS代码效果大全 【1】

    广告JS代码效果大全 1.[普通效果]     现在很多网站广告做的如火如荼,现在我就来介绍一下常见的对联浮动广告效果的代码使用方法,介绍的这种效果,在1024*768分辨率下正常显示,在800*60 ...

  10. Js 拖动效果

    <!DOCTYPE html> <html> <head> <meta charset="utf8"> <title>j ...

随机推荐

  1. CUDA 编程学习 (5)——内存访问性能

    1. DRAM 带宽 1.1 DRAM 核心阵列结构 每个 DRAM 核心阵列约有 \(16M\) bits 每个 bits 存储在由一个晶体管组成的微小电容器中 超小型(8x2-bit)DRAM 内 ...

  2. flask+APScheduler定时任务的使用

    目录 APScheduler简介 安装 add_job参数详解 结合flask使用 用uwsgi启动项目 用gunicorn+gevent启动flask项目 APScheduler简介 APSched ...

  3. PasteEx:一款.NET开源的Windows快捷粘贴神器

    前言 PasteEx是一款.NET开源的用于增强 Windows 粘贴功能的小工具,它解决了将剪贴板内容保存为文件的繁琐步骤.无需打开记事本等应用,它可直接将文字.图片等内容粘贴到桌面上,极大提升了效 ...

  4. NOIP 备赛:CF 2E 板刷

    从 \(2024.11.05\) 之前的比赛排着刷. CF2028 E 这道题主要考察的是手玩能力和转移技巧. 给定一棵树,根为 \(1\).爱丽丝的起点位于某个顶点 \(v\) .她想走出洞口,但不 ...

  5. monitor磁盘空间不足警告

    虚拟机安装ceph时,执行ceph -s monitor主机遇到了 mon c101(monitor主机名) is low on available space 错误 这是我找到的解决办法 monit ...

  6. u-chart

    1.前言 uni-app能用的图表插件太少,这是唯一能用,虽然官方声称 傻瓜式 配置,但是在我看来异常繁琐,可选的配置项一大堆统统堆到demo里面,导致上手非常困难.既然踩了坑,我就记录下来. 2.基 ...

  7. 服务迁移之《mysql数据同步问题》

    我们大概是从2022年十月份开始进行拆分的.面对一百多个服务的时候,真的是无从下手,然后公司突然空降了一个从阿里出来的架构师,然后就带着我们大刀阔斧的整体迁移. 先是服务器购买阿里云的,然后从几个核心 ...

  8. GPU 驱动漏洞:窥探驱动漏洞利用的技术奥秘

    GPU 驱动漏洞:窥探驱动漏洞利用的技术奥秘 本文尝试以 GPU 漏洞为引介绍围绕 GPU 驱动这一攻击面,安全研究人员对内核漏洞利用技术做的一些探索. 背景介绍 目前移动 SOC 平台上由多个硬件模 ...

  9. 【Amadeus原创】docker安装TOMCAT,并运行本地代码

    1,docker 下载tomcat [root@it-1c2d ~]# docker pull tomcat ... [root@it-1c2d ~]# docker images REPOSITOR ...

  10. .NET Threadpool 饥渴,以及队列是如何使它更糟的

    .NET Threadpool 饥渴,以及队列是如何使它更糟的 .NET Threadpool starvation, and how queuing makes it worse - Criteo ...