原生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实现全屏切换以及导航栏滑动隐藏及显示——重构前
思路分析: 向后滚动鼠标滚轮,页面向下全屏切换:向前滚动滚轮,页面向上全屏切换.切换过程为动画效果. 第一屏时,导航栏固定在页面顶部,切换到第二屏时,导航条向左滑动隐藏.切换回第一屏时,导航栏向右滑动 ...
随机推荐
- 【[AH2017/HNOI2017]礼物】
题目 又是我不会做的题了 看看柿子吧 \[\sum(a_i+c-b_i)^2\] 最小化这个柿子 之所以不写下标是因为我们这个\(\{a\},\{b\}\)可以循环同构 那就开始化吧 \[\sum(a ...
- c#主窗体以及副窗体弹出
在program.cs中,Form1的位置就是主窗体的位置(主窗体特征:关闭窗体应用程序结束) 弹出副窗口(点击按钮弹出窗口) Close为关闭窗口(关闭对应对象,需要先自己new一个) this.C ...
- HDU 2859 Phalanx(对称矩阵 经典dp样例)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=2859 Phalanx Time Limit: 10000/5000 MS (Java/Others) ...
- FFMPEG系列一:Mac下FFMPEG编译安装配置及使用例子
系统环境:10.13以前系统版本,没有升级到macOS High Sierra.正常情况是直接输入brew install ffmpeg即可安装ffmpeg,但是该过程还是有一些坑需要填. 一.mac ...
- spring boot 解决后台返回 json 到前台中文乱码之后出现返回json数据报错 500:no convertter for return value of type
问题描述 spring Boot 中文返回给浏览器乱码 解析成问号?? fastJson jackJson spring boot 新增配置解决后台返回 json 到前台中文乱码之后,出现返回json ...
- c#一种存储结构解决动态平衡问题
不说其他了,最近为了实现这么一个场景了而提取的一种结构.我们把一种数据缓存,比如开辟的存储Buffer,或者连接池.放置在一个结构中.很多时候这有一个共同的特点,我们的业务在一段时间会急剧增长,我们开 ...
- axios基础用法
概述: 1.axios:一个基于Promise用于浏览器和nodejs的HTTP客户端.本质是对ajax的封装. 特征: 1>从浏览器中创建XMLHttpRequest 2>从node.j ...
- 【2018 ICPC焦作网络赛 K】Transport Ship(多重背包二进制优化)
There are N different kinds of transport ships on the port. The ith kind of ship can carry the weigh ...
- React学习(2)—— 组件的运用和数据传递
React官方中文文档地址: https://doc.react-china.org/ 了解了组件之后,就需要理解“Props”和“State”的用法.首先来介绍State,State按照字面意 ...
- Chrome Google 快捷键
窗口和标签页快捷方式 Ctrl+N 打开新窗口 按住 Ctrl 键,然后点击链接 在新标签页中打开链接 按住 Shift 键,然后点击链接 在新窗口中打开链接 Alt+F4 关闭当前窗口 Ctrl+ ...