原生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实现全屏切换以及导航栏滑动隐藏及显示——重构前
思路分析: 向后滚动鼠标滚轮,页面向下全屏切换:向前滚动滚轮,页面向上全屏切换.切换过程为动画效果. 第一屏时,导航栏固定在页面顶部,切换到第二屏时,导航条向左滑动隐藏.切换回第一屏时,导航栏向右滑动 ...
随机推荐
- luogu P2124 奶牛美容
嘟嘟嘟 首先数据范围那么小,那么算法也是相当暴力的. 对于一个点(x, y)所属的联通块,预处理出从这个点出发到这个块外的所有点的曼哈顿距离.复杂度O(n4). 然后求答案:最少答案不一定是三个联通块 ...
- 【转】android ListView详解
由于google doc 很多人都打不开,故更新了源码下载地址 [源码下载]----2011-01-18 在android开发中ListView是比较常用的组件,它以列表的形式展示具体内容,并且能够根 ...
- [19/03/21-星期四] 异常(Exception) (一)
一.引言 在实际工作中,我们遇到的情况不可能是非常完美的.比如:你写的某个模块,用户输入不一定符合你的要求;你的程序要打开某个文件, 这个文件可能不存在或者文件格式不对 ,你要读取数据库的数据,数据可 ...
- 【题解】洛谷P1006传纸条
链接 https://www.luogu.org/problemnew/show/P1006 日常牢骚 过年前最后一节课上完了坐标DP 也接触了一点区间DP(noi1995石子合并)下次做做看看吧 老 ...
- Git push提示pre-receive hook declined
master:local auto@ubuntu:~/src/code/ git push Counting objects: 5, done. Delta compression using up ...
- bzoj2982: combination(lucas)
Description LMZ有n个不同的基友,他每天晚上要选m个进行[河蟹],而且要求每天晚上的选择都不一样.那么LMZ能够持续多少个这样的夜晚呢?当然,LMZ的一年有10007天,所以他想知道答案 ...
- ABAP术语-Object Name
Object Name 原文:http://www.cnblogs.com/qiangsheng/archive/2008/03/05/1091092.html An object name is a ...
- 思维导图 XMind 8 Update 8 Pro for Mac 中文破解版
破解包下载地址 在官网下载8版本就可以了
- 高级同步器:信号量Semaphore
引自:https://blog.csdn.net/Dason_yu/article/details/79734425 一.信号量一个计数信号量.从概念上讲,信号量维护了一个许可集.Semaphore经 ...
- Ajax知识总结
一 AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML). AJAX 不是新的编程语言,而是一种使用现有标准的新方法.AJAX 最大 ...