任务分解

一、绘制棋盘

二、绑定事件

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. macOS安装使用OpenConnect客户端替代cisco连接公司内网环境

    mac_os安装openconnect服务 brew install openconnect 使用OpenConnect客户端拨通VPN,打开终端执行以下命令: sudo openconnect -u ...

  2. CSP 2024-S 游记 黑暗的枷锁

    09-21 今天考完了初赛,明显感觉数学门槛变高了一些,有高中数学知识才能保证看得懂题意,只是苦了小学和初中同学,看数据参加人数还涨了50%,权当拉低分数线了吧.用小图灵估分70.应该是稳过. 09- ...

  3. 基于Java+SpringBoot+Mysql实现的古诗词平台功能设计与实现八

    一.前言介绍: 1.1 项目摘要 随着信息技术的迅猛发展和数字化时代的到来,传统文化与现代科技的融合已成为一种趋势.古诗词作为中华民族的文化瑰宝,具有深厚的历史底蕴和独特的艺术魅力.然而,在现代社会中 ...

  4. lua中table中null的表示方法以及判断redis返回null

    今天遇到一个麻烦的问题,查询redis时候,查到数据的时候正常返回,查询不到数据时,返回了null,然而在lua中,常见的nil,但不常见null,这时候lua中对redis返回的null如何做判断呢 ...

  5. Chrome插件之油猴(详尽版本)

    官方文档: https://www.tampermonkey.net/documentation.php#google_vignette 1.注释语法: // @match https://passp ...

  6. Mybatis【14】-- Mybatis如何实现一对多查询?

    ++注:代码已托管在GitHub上,地址是:https://github.com/Damaer/Mybatis-Learning ,项目是mybatis-10-one2many,需要自取,需要配置ma ...

  7. 💥TinyPro Vue v1.1.0 正式发布:增加细粒度权限管理、页签模式、多级菜单,支持 Webpack/Vite/Rspack/Farm 多种构建工具

    你好,我是 Kagol,个人公众号:前端开源星球. 视频教程:https://www.bilibili.com/video/BV1SUBRYGECg/ 为了提升前端开发效率,OpenTiny 提供了一 ...

  8. Postman 汉化教程

    Postman 汉化教程(Postman中文版) 迷恋自留地 postman官网下载地址 https://www.postman.com/downloads/ postman汉化包 https://g ...

  9. Mysql的整体架构设计

    整体分层 连接层 服务层 存储引擎层 连接层 客户端要连接到服务器 3306 端口,必须要跟服务端建立连接,那么 管理所有的连接,验证客户端的身份和权限,这些功能就在连接层完成. 服务层 连接层会把 ...

  10. 技术实践|数据迁移中GBK转UTF8字符集问题分析

    导语:在国产化创新的大背景下,数据库迁移项目逐渐增多,在数据库迁移过程中,源数据库和目标数据库字符集有时会不同,这时如何进行字符集转换则成为了一个重要的问题,同时在转换过程中还需要确保数据的完整性和一 ...