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 ...
随机推荐
- UE4纯C++实现游戏快捷栏
要想创建一个游戏中的快捷栏我们往往通过以下几步来实现(目录导航): 1.创建UI:我们首先需要有在游戏视口中添加一个快捷栏UI界面,以供玩家看到自身的快捷栏. 2.物品读取:其次有了界面之后我们需要往 ...
- fabric基本使用
fabric简介 Fabric 是一个 Python 的库,同时它也是一个命令行工具.它提供了丰富的同 SSH 交互的接口,可以用来在本地或远程机器上自动化.流水化地执行 Shell 命令.使用 ...
- ARC127E Priority Queue
ARC127E Priority Queue 分析性质+dp. 思路 由于每次加入的数肯定是一个 \(a\) 的排列,但这个角度不好考虑. 设 \(\{a\}\) 为最终状态的集合,其中 \(a_i& ...
- 基本数据结构-双端队列(Deque)
6.基本数据结构-双端队列(Deque) 一.双端队列(Deque) - 概念:deque(也称为双端队列)是与队列类似的项的有序集合.它有两个端部,首部和尾部,并且项在集合中保持不变. - 特性:d ...
- 使用SwingWorker异步加载JTree
SwingWorker是Java SE 6.0新加入的一个工具包,利用它可以使长时间运行并更新用户界面的任务大大简化.本文以一个异步加载JTree的demo演示了SwingWorker的基本功能. 环 ...
- Linux之新增硬盘,分区,挂载
1.新增硬盘后, 查看当前磁盘信息 fdisk -l 可以看到除了当前的第一块硬盘(sda)外还有一块sdb的第二块硬盘(sdb),然后用命令: fdisk /dev/sdb 给第二块硬盘进行分区 ...
- golang之JSON处理
在强类型语言中,JSON 通常很难处理 -- JSON 类型有字符串.数字.字典和数组.如果你使用的语言是 javascript.python.ruby 或 PHP,那么 JSON 有一个很大的好处就 ...
- Laravel环境搭建之HomeStead
开发laravel,官方推荐使用HomeStead虚拟环境进行搭建. Linux: 1. 安装virtualbox(https://www.virtualbox.org/) 1)可以找到可供下载的镜像 ...
- IDA+kali 远程动态调试
一.找到IDA文件目录下的 linux_server和linux_server64 复制到kali中去 给权限: chmod a+x ./linux_server chmod a+x ./linux_ ...
- 第一个 milestone:内推 50 人拿到微软 offer!
就在昨天,我的一位候选人和我说,他已经通过面试,正在 offer 沟通阶段.由此,我达成第一个小里程碑:成功内推 50 人拿到了微软 offer! 内推了多少人? 从 2019 年年初开始内推,到现在 ...