原生js实现 五子棋
先初始化棋盘
HTML:
<!--棋盘-->
<div class="grid"></div>
CSS:
/*棋盘*/
.grid{
position: relative;
width: 762px;
height: 762px;
background-image: url('./image/timg.jpg');
-webkit-background-size: 100% 100%;
background-size: 100% 100%;
background-position: center center;
margin: 100px auto;
} /*每个棋子落点区域*/
.per-zone{
position: absolute;
width: 50px;
height: 50px;
padding: 10px;
background-origin: content-box;
box-sizing: border-box;
background-position: center center;
background-size: 100% 100%;
background-repeat: no-repeat;
}
JS:// 棋盘
const grid = document.getElementsByClassName('grid')[0];
// 棋盘有15列,  15行
const column = 15 , line = 15;
// 装棋子的二维数组
let gridArr = [];
// 初始化二维数组
function init() {
    // 文档碎片用来装棋子优化效率
    const fragment = document.createDocumentFragment();
    gridArr = new Array(line);
    for(let i = 0; i < gridArr.length; i ++) {
        gridArr[i] = new Array(column);
        for(let j = 0; j < gridArr[i].length; j ++) {
            // 创建每个棋子落点区域
            fragment.appendChild(createZone(j, i));
        }
    }
    grid.appendChild(fragment);
    // 事件委托, 性能优化
    grid.addEventListener('click', (e) => {
        begin(e);
    }, false)
}
init();
function createZone(x, y) {
    // 创建棋子
    const div = document.createElement('div');
    div.classList.add('per-zone');
    div.style.left = x * 50 + 7 + 'px';
    div.style.top = y * 50 + 7 + 'px';
    // 标记棋子的类型,黑子为1, 白子为2, 初始化为0
    div.value = 1;
    div.style.backgroundImage = `url(${'./image/' + div.value + '.png' })`;
    return div
}
我们先让每个棋子的value都为1,看看效果:

不要犯密集恐惧症哦,
我们用事件委托来绑定事件, 这样事件只需要绑定一次而不用绑定15 * 15次,
很大地提升了效率,
开始写点击事件:
// 计数, 用来判定落黑子还是落白子
let count = 0; // 黑:value =1 ; 白: value = 2
function begin(target) {
// 判断value为0 才能下子
if (!target.value) {
target.value = count%2 + 1 ;
target.style.backgroundImage = `url(${'./image/' + target.value + '.png' })`;
// 判断是否结束
judgeFinish();
count ++ ;
}
}
现在我们可以下棋了:

很有成就感是不是,就差最后一步也最是核心的一步
判断横着, 竖着, 斜着 是否有5个以上相同颜色的棋子
function judgeFinish() {
    for (let i = 0; i < gridArr.length; i ++) {
        for(let j = 0; j < gridArr[i].length; j ++) {
            // value 为 0 跳过
            if (gridArr[i][j].value === 0) {
                continue;
            }
            // 判断是否五子连珠
            const result = judgeLine(i, j);
            if (result === 1) {
                alert('黑棋胜利');
                replay();
                return
            } else if (result === 2) {
                alert('白棋胜利');
                replay();
                return
            }
        }
    }
}
// 判断向下, 向右, 向斜上, 向斜下四个方向
function judgeLine(x, y) {
    // 黑1, 白2
    let result1 = 3, result2 = 3, result3 =3, result4 =3;
    for (let i = 0; i < 5; i ++) {
        // 向下
        result1 &= y + i < 14 ? gridArr[x][y + i].value : 0;
        // 向右
        result2 &= x + i < 14 ? gridArr[x + i][y].value : 0;
        // 斜上
        result3 &= (x + i > 14 || y - i < 0) ? 0 : gridArr[x + i][y - i].value;
        // 斜下
        result4 &= (x + i > 14 || y + i > 14) ? 0 : gridArr[x + i][y + i].value;
    }
    // 只要有一个方向不为0 游戏结束
    return result1 | result2 | result3 | result4
}
function replay() {
// 装棋子的二维数组
    gridArr = [];
// 计数, 用来判定落黑子还是落白子
    count = 0;
    grid.innerHTML = '';
    init();
}
核心: 使用& 运算符 来 判断 是否 5 子 的 value 相同
1& 1& 1& 1& 1 = 1
2 & 2 &2 &2 &2 = 2
为什么初始值设成3 呢, 因为任何数 & 3 都不会变
先转化成2进制 再运算 3 =》 11
最后的效果:

原生js实现 五子棋的更多相关文章
- 原生js实现五子棋
		
为什突然做这个,因为这是个笔试题,拖了一个月才写(最近终于闲了O(∩_∩)O),废话不多说,说说这个题吧 题目要求 编写一个单机[五子棋]游戏,要求如下: 1.使用原生技术实现,兼容 Chrome 浏 ...
 - 原生JS+Canvas实现五子棋游戏
		
一.功能模块 先看下现在做完的效果: 线上体验:https://wj704.github.io/five_game.html 主要功能模块为: 1.人机对战功能 2.悔棋功能 3.撤销悔棋功能 二.代 ...
 - 原生 Javascript 编写五子棋
		
原文地址:原生 Javascript 编写五子棋 博客地址:http://www.extlight.com 一.背景 近一个月没写 Javascript 代码,有点生疏.正好浏览网页时弹出五子棋的游戏 ...
 - 原生JS封装Ajax插件(同域&&jsonp跨域)
		
抛出一个问题,其实所谓的熟悉原生JS,怎样的程度才是熟悉呢? 最近都在做原生JS熟悉的练习... 用原生Js封装了一个Ajax插件,引入一般的项目,传传数据,感觉还是可行的...简单说说思路,如有不正 ...
 - 常用原生JS方法总结(兼容性写法)
		
经常会用到原生JS来写前端...但是原生JS的一些方法在适应各个浏览器的时候写法有的也不怎么一样的... 今天下班有点累... 就来总结一下简单的东西吧…… 备注:一下的方法都是包裹在一个EventU ...
 - 原生JS实现"旋转木马"效果的图片轮播插件
		
一.写在最前面 最近都忙一些杂七杂八的事情,复习软考.研读经典...好像都好久没写过博客了... 我自己写过三个图片轮播,一个是简单的原生JS实现的,没有什么动画效果的,一个是结合JQuery实现的, ...
 - 再谈React.js实现原生js拖拽效果
		
前几天写的那个拖拽,自己留下的疑问...这次在热心博友的提示下又修正了一些小小的bug,也加了拖拽的边缘检测部分...就再聊聊拖拽吧 一.不要直接操作dom元素 react中使用了虚拟dom的概念,目 ...
 - React.js实现原生js拖拽效果及思考
		
一.起因&思路 不知不觉,已经好几天没写博客了...近来除了研究React,还做了公司官网... 一直想写一个原生js拖拽效果,又加上近来学react学得比较嗨.所以就用react来实现这个拖 ...
 - 原生JS实现全屏切换以及导航栏滑动隐藏及显示——重构前
		
思路分析: 向后滚动鼠标滚轮,页面向下全屏切换:向前滚动滚轮,页面向上全屏切换.切换过程为动画效果. 第一屏时,导航栏固定在页面顶部,切换到第二屏时,导航条向左滑动隐藏.切换回第一屏时,导航栏向右滑动 ...
 
随机推荐
- gevent程序员指南
			
gevent程序员指南 由Gevent社区编写 gevent是一个基于libev的并发库.它为各种并发和网络相关的任务提供了整洁的API. 介绍 本指南假定读者有中级Python水平,但不要求有其 ...
 - require './ex25' can't load such file
			
require './ex25' can't load such file 在练习learn ruby the hard way时候,第25题,发生了一下错误 LoadError: cannot lo ...
 - .net core2.0添加json文件并转化成类注入控制器使用
			
上一篇,我们介绍了如何读取自定义的json文件,数据是读取出来了,只是处理的时候太麻烦,需要一遍一遍写,很枯燥.那么有没有很好的办法呢?经过钻研,办法有了. 既然一个一个读取比较麻烦,那么可以把它放入 ...
 - Page.ClientScript.RegisterStartupScript用法小结
			
使用类型.键.脚本文本和指示是否添加脚本标记的布尔值向 Page 对象注册启动脚本. 参数 type 要注册的启动脚本的类型. key 要注册的启动脚本的键. script 要注册的启动脚本文本. a ...
 - Python 3.6 中文手册——前言
			
1. 前言 如果你在电脑上做了很多工作,最终你会发现有一些任务你想要自动化.例如,你可能希望对大量的文本文件执行搜索和替换,或者以复杂的方式重命名并排列一堆照片文件.也许你想写一个小的自定义数据库,或 ...
 - 关于springboot的定时器配置
			
关于springboot的定时器: 比较重要的两个注解: @EnableScheduling:标注启动定时任务. @Scheduled(fixedRate = 1000 * 30) 定义某个定时任务 ...
 - Scrapy 和 scrapy-redis的区别
			
Scrapy 和 scrapy-redis的区别 Scrapy 是一个通用的爬虫框架,但是不支持分布式,Scrapy-redis是为了更方便地实现Scrapy分布式爬取,而提供了一些以redis为基础 ...
 - springMVC引入Validation详解
			
本文简单介绍如何引入validation的步骤,如何通过自定义validation减少代码量,提高生产力.特别提及:非基本类型属性的valid,GET方法的处理,validation错误信息的统一re ...
 - Ajax 与服务器通信 验证编号重复
			
在最近的一个Web项目中,需要实现一个功能,就是用户在前端输入一个编号,后台需要验证这个编号是否在数据库中已经存在,如果存在就提示用户. 主要用到两个模块.第一:在jsp中添加一个脚本,利用ajax向 ...
 - Vue.js中前端知识点总结笔记
			
1.框架和库的区别: 框架:framework 有着自己的语法特点.都有对应的各个模块库 library 专注于一点 框架的好处: 1.提到代码的质量,开发速度 2.提高代码的复用率 3.降低模块之间 ...