js五子棋效果
任务分解
一、绘制棋盘
二、绑定事件
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五子棋效果的更多相关文章
- JS原生效果瀑布流布局的实现(一)
JS原生效果 实现: HTML页面布局: <!DOCTYPE html> <html> <head> <meta charset="utf-8&qu ...
- js sleep效果
js sleep效果 s = setInterval(function(){ //需要执行的函数 alert("我延迟了2秒弹出"); },2000); 并不是每2秒执行一次,而是 ...
- JS打字效果的动态菜单代码分享
这篇文章主要介绍了JS打字效果的动态菜单,推荐给大家,有需要的小伙伴可以参考下. 这是一款基于javascript实现的打字效果的动态菜单特效代码,分享给大家学习学习. 小提示:浏览器中如果不能正常运 ...
- js 动画效果实现
1. 实现方式 - 应用场景 自己写 - 简单的.不用 jq 的项目 jq - 普通动画 成熟插件 - 复杂动画 2. 相关文章 JavaScript基于时间的动画算法 九种原生js动画效果 Twee ...
- 页面倒计时跳转页面效果,js倒计时效果
页面倒计时跳转页面效果,js倒计时效果 >>>>>>>>>>>>>>>>>>>> ...
- 非常不错的一个JS分页效果代码
这里分享一个不错的js分页代码. 代码中cpage是页面计数,应为全局变量,可以随处调用它: totalpage是总页数. 与asp分页代码很类似,也是先取得记录总数,然后实现分页,基本的分页思路与原 ...
- 纯js倒计时效果(交流加群:452892873)(本群每天都更新学习资料)
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- js 技巧 (十)广告JS代码效果大全 【3】
3.[允许关闭] 与前面两个代码不同的是,广告图下方增加了一个图片按纽,允许访客点击关闭广告图片,下面文本框中就是实现效果所需代码: var delta=0.015; var coll ...
- js 技巧 (十)广告JS代码效果大全 【1】
广告JS代码效果大全 1.[普通效果] 现在很多网站广告做的如火如荼,现在我就来介绍一下常见的对联浮动广告效果的代码使用方法,介绍的这种效果,在1024*768分辨率下正常显示,在800*60 ...
- Js 拖动效果
<!DOCTYPE html> <html> <head> <meta charset="utf8"> <title>j ...
随机推荐
- HTTP相关返回值异常如何解决(上篇)
今天我们讲讲HTTP相关返回值异常如何解决(实例持续更新中) 一.HTTP介绍 HTTP(超文本传输协议,Hypertext Transfer Protocol)是用于在网络上进行数据交换的应用层 ...
- 国密SSL证书,为政务数据安全保驾护航
随着数字化转型的加速,政务信息化建设已成为提升政府服务效率和质量的关键.近期,国家相关部门发布了<互联网政务应用安全管理规定>,为政务应用的安全管理提供了明确的规范和要求.该规定自2024 ...
- jmeter如何产生批量数据?
在使用jmeter时,若需要产生批量数据,可以通过连接数据库--执行相关sql进行操作,例如添加20条数据 步骤: 1.添加jdbc 数据库配置信息 2.添加循环控制器(循环次数20) 3.循环控制器 ...
- NZOJ 模拟赛6
T1 叉叉 现在有一个字符串,每个字母出现的次数均为偶数.接下来我们把第一次出现的字母a和第二次出现的a连一条线,第三次出现的和四次出现的字母a连一条线,第五次出现的和六次出现的字母a连一条线...对 ...
- FastJson漏洞复现
FastJson漏洞复现 环境:vulhub/fastjson Fastjson是阿里巴巴公司开源的一个高性能的Java库,专门用于处理JSON数据格式. 它不仅能够将Java对象序列化为JSON格式 ...
- linux 查看进程的bin文件所在路径
1.获取进程pid ps aux |grep nginx|grep master|grep -v grep|awk '{print $2}' 2.根据进程pid 获取 bin路径 方法a pwdx p ...
- 加密 DB2 Universal Database 中的数据值
在本文中,我们演示了 IBM DB2 Universal Database Version 7.2 中新的加密函数如何提供简单方式来加密敏感数据. 评论: Bruce BenfieldIBM Ric ...
- 面向 Java 开发人员的 Scala 指南: 构建计算器,第 1 部分
Scala 的 case 类和模式匹配 Ted Neward, 主管, Neward & Associates 简介: 特定于领域的语言已经成为一个热门话题:很多函数性语言之所以受欢迎,主要是 ...
- 借助AI助手如何高效排查SQL问题
快乐的时光总是转瞬即逝,尤其是当我们面对bug时,不仅浪费了宝贵的时间,更让人感到沮丧.因为bug往往是非常奇怪.难以捉摸的,找来找去你始终无法确定问题所在,最终意识到这些bug并没有多大技术含量.尽 ...
- PTA-1002
原先主要错误: 没有考虑到有关0的相关情况 观看的大佬代码 整理思路 无非就是在相同的指数的情况下,系数相加 因为最后是要从大到小输出来. 注意 要对最后的结果进行四舍五入: PTA的英语题对英语不好 ...