原生js实现五子棋
为什突然做这个,因为这是个笔试题,拖了一个月才写(最近终于闲了O(∩_∩)O),废话不多说,说说这个题吧
题目要求
编写一个单机【五子棋】游戏,要求如下:
1.使用原生技术实现,兼容 Chrome 浏览器即可。
2.实现胜负判断,并给出赢棋提示;任意玩家赢得棋局,锁定棋盘。
3.请尽可能的考虑游戏的扩展性,界面可以使用 DOM / Canvas 实现。考虑后续切换界面实现的方式成本最低。(比如选择使用 DOM 实现界面,需求改变为使用 Canvas 实现时尽可能少的改动代码)。
4.实现一个悔棋功能
5.实现一个撤销悔棋功能。
6.人机对战部分可选。
7.尽可能的考虑实现的灵活性和扩展性。
UI部分
棋盘
五子棋,首先我们会想到棋盘、棋子,这是棋类游戏的基本元素,实现棋盘、棋子基本的两种思路,一种使用html标签模拟,另外一种就是使用canvas去画。这里我们选择使用canvas。

canvas.strokeStyle = "#ccc";
for(let i = 0; i<=15; i++){
canvasA.moveTo(20+40*i, 20);
canvasA.lineTo(20+40*i, 620);
canvasA.stroke();
canvasA.moveTo(20, 20+40*i);
canvasA.lineTo(620, 20+40*i);
canvasA.stroke();
}
主要的思路就是画等距离的直线,包活横向和纵向,用一个循环即可。

棋子
棋子的注意点就是位置,圆心和棋盘的交叉点要对齐,当鼠标点击某个范围的时候要在对应的交叉点为圆心处画圆。
oChess.addEventListener('click', (event) => {
let x = Math.floor(event.offsetX/40),
y = Math.floor(event.offsetY/40);
}, false)
我们以交叉点为中心的正方形(变长为棋格边长)为范围,也就是说每当鼠标点击到红色区域就在该中心点画棋子。这里获得中心点坐标之后就可以在对应点画棋子

//画棋子
const drawChessman = (x, y, temp) => {
canvas.beginPath();
canvas.arc(20+x*40,20+y*40, 18, 0, 360);
canvas.closePath();
canvas.fillStyle = temp ? "#fff" : "#000";
canvas.fill();
}
其他
由于有悔棋功能,我们可以使用canvas的clearRect,但是,在清除棋子的时候不仅把棋子清除掉,而且棋子覆盖的棋盘也被清除掉,这是不被允许的,但是我们总不能把棋盘再重新画一遍,这样棋盘就会把棋子覆盖,而且总归是有性能问题。

这里耍了个小聪明,我们使用两个canvas来完成,底层的canvas用来画棋盘,上层的canvas用来画棋谱,并将其背景色设置为透明,这样清除棋子就不会影响到棋盘。
算法
界面是有了,但是玩的的时候怎么确定谁赢了?人机的时候电脑该怎么走?
赢法
这里使用一种最简单的算法,那就是先枚举出所有的赢法,然后再每走一步的时候都去判断下棋人赢的权重。那么有多少种赢的方式呢,当然是跟棋盘大小有关(可不是棋盘的宽高哦
原生js实现五子棋的更多相关文章
- 原生js实现 五子棋
先初始化棋盘 HTML: <!--棋盘--> <div class="grid"></div> CSS: /*棋盘*/ .grid{ posit ...
- 原生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实现全屏切换以及导航栏滑动隐藏及显示——重构前
思路分析: 向后滚动鼠标滚轮,页面向下全屏切换:向前滚动滚轮,页面向上全屏切换.切换过程为动画效果. 第一屏时,导航栏固定在页面顶部,切换到第二屏时,导航条向左滑动隐藏.切换回第一屏时,导航栏向右滑动 ...
随机推荐
- 【[TJOI2007]可爱的质数】
题目 用一道板子题来复习一下\(bsgs\) \(bsgs\)用于求解形如 \[a^x\equiv b(mod\ p)\] 这样的高次不定方程 由于费马小定理的存在,我们可是直接暴力扫一遍\(p\), ...
- Node.js使用MySQL数据库中对RowDataPacket对象的使用
使用Node.js开发使用MySQL数据库的网站,在查询后返回一RowDataPacket类型的对象 原先使用toString()方法一直得到仅为object的字符串,无法使用 后思考,才发现忽略了其 ...
- Codeforces Round #512 (Div. 2, based on Technocup 2019 Elimination Round 1) C. Vasya and Golden Ticket 【。。。】
任意门:http://codeforces.com/contest/1058/problem/C C. Vasya and Golden Ticket time limit per test 1 se ...
- [18/12/03] 多态(polymorphism)和对象的转型(casting)
一.多态 多态指的是同一个方法调用,由于对象不同可能会有不同的行为.现实生活中,同一个方法,具体实现会完全不同. 比如:同样是调用人的“休息”方法,张三是睡觉,李四是旅游,同样是调用人“吃饭”的方法, ...
- 检查WIFI是否连接
查看网络连接 查看WiFi连接状态 (连接- -断开)
- sst上传和下载码云
第一次 Team-----share---->Add----->commit-------remote----->pull 第二次 直接share开始.
- 【luogu P2746 [USACO5.3]校园网Network of Schools】 题解
题目链接:https://www.luogu.org/problemnew/show/P2812 注意:判断出入度是否为0的时候枚举只需到颜色的数量. 坑点:当只有一个强连通分量时,不需要再添加新边. ...
- 【luogu P2764 最小路径覆盖问题】 模板
题目链接:https://www.luogu.org/problemnew/show/P2764 把每个点在左边建一遍右边建一遍,再加上源点汇点,跑最大流,n-最大流就是答案. #include &l ...
- javascript操作Date对象
Date 对象用于处理日期和时间. 创建 Date 对象的语法: var myDate=new Date() Date 对象会自动把当前日期和时间保存为其初始值. 参数形式有以下5种: new Dat ...
- windows 平台下 安装解密 openssl
1 在openssl 官网下载 openssl 安装, 本机是 64位 win 8.1 系统 http://slproweb.com/products/Win32OpenSSL.html 下载:Win ...