为什突然做这个,因为这是个笔试题,拖了一个月才写(最近终于闲了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实现五子棋的更多相关文章

  1. 原生js实现 五子棋

    先初始化棋盘 HTML: <!--棋盘--> <div class="grid"></div> CSS: /*棋盘*/ .grid{ posit ...

  2. 原生JS+Canvas实现五子棋游戏

    一.功能模块 先看下现在做完的效果: 线上体验:https://wj704.github.io/five_game.html 主要功能模块为: 1.人机对战功能 2.悔棋功能 3.撤销悔棋功能 二.代 ...

  3. 原生 Javascript 编写五子棋

    原文地址:原生 Javascript 编写五子棋 博客地址:http://www.extlight.com 一.背景 近一个月没写 Javascript 代码,有点生疏.正好浏览网页时弹出五子棋的游戏 ...

  4. 原生JS封装Ajax插件(同域&&jsonp跨域)

    抛出一个问题,其实所谓的熟悉原生JS,怎样的程度才是熟悉呢? 最近都在做原生JS熟悉的练习... 用原生Js封装了一个Ajax插件,引入一般的项目,传传数据,感觉还是可行的...简单说说思路,如有不正 ...

  5. 常用原生JS方法总结(兼容性写法)

    经常会用到原生JS来写前端...但是原生JS的一些方法在适应各个浏览器的时候写法有的也不怎么一样的... 今天下班有点累... 就来总结一下简单的东西吧…… 备注:一下的方法都是包裹在一个EventU ...

  6. 原生JS实现"旋转木马"效果的图片轮播插件

    一.写在最前面 最近都忙一些杂七杂八的事情,复习软考.研读经典...好像都好久没写过博客了... 我自己写过三个图片轮播,一个是简单的原生JS实现的,没有什么动画效果的,一个是结合JQuery实现的, ...

  7. 再谈React.js实现原生js拖拽效果

    前几天写的那个拖拽,自己留下的疑问...这次在热心博友的提示下又修正了一些小小的bug,也加了拖拽的边缘检测部分...就再聊聊拖拽吧 一.不要直接操作dom元素 react中使用了虚拟dom的概念,目 ...

  8. React.js实现原生js拖拽效果及思考

    一.起因&思路 不知不觉,已经好几天没写博客了...近来除了研究React,还做了公司官网... 一直想写一个原生js拖拽效果,又加上近来学react学得比较嗨.所以就用react来实现这个拖 ...

  9. 原生JS实现全屏切换以及导航栏滑动隐藏及显示——重构前

    思路分析: 向后滚动鼠标滚轮,页面向下全屏切换:向前滚动滚轮,页面向上全屏切换.切换过程为动画效果. 第一屏时,导航栏固定在页面顶部,切换到第二屏时,导航条向左滑动隐藏.切换回第一屏时,导航栏向右滑动 ...

随机推荐

  1. 围绕react衍生出来的思考

    优势一.声明式开发 首先react是声明式的开发方式,这个与之对应的是命令式开发方式,之前在用jquery写代码的时候,都是直接来操作dom,直接操作dom的这种编程方式,我们把他叫做命令式的编程,也 ...

  2. 【转】JS gzip加密字符串并base64输出

    http://blog.csdn.net/zunwei/article/details/49886115 最近开发中遇到一些问题,关于js怎么给一个字符串进行字节流加密.下面就详细说下做法. 首先引入 ...

  3. 【题解】洛谷P1066 [NOIP2006TG] 2^k进制数(复杂高精+组合推导)

    洛谷P1066:https://www.luogu.org/problemnew/show/P1066 思路 挺难的一道题 也很复杂 满足题目要求的种数是两类组合数之和 r的最多位数m为 w/k(当w ...

  4. HDFS副本存放读取

    HDFS作为Hadoop中 的一个分布式文件系统,而且是专门为它的MapReduce设计,所以HDFS除了必须满足自己作为分布式文件系统的高可靠性外,还必须为 MapReduce提供高效的读写性能,那 ...

  5. 关于In-App Purchase(内购)的注意事项

    前言:关于In-App Purchase(内购)的注意事项 一点注意事项: 内购应该有游客身份的购买选项,不然可能被拒,前一段时间我这边一直是因为没有游客身份购买被拒. 在验证内购结果的时候要注意使用 ...

  6. 牛B的swift屏幕旋转经验终结者(OC统一思路)

    牛B的swift屏幕旋转经验终结者(OC统一思路) 1.AppDelegate (1)定义变量 var blockRotation: Bool = false (2)定义方法 Swift代码 func ...

  7. npm ERR! code: 'EPERM' (权限问题 errro permit)

    PS C:\Users\user\Desktop\test\my-project> npm run iview --save npm ERR! missing script: iview npm ...

  8. 第十四届浙江财经大学程序设计竞赛重现赛--A-A Sad Story

    链接:https://www.nowcoder.com/acm/contest/89/A 来源:牛客网 1.题目描述 The Great Wall story of Meng Jiangnv’s Bi ...

  9. 第13届景驰-埃森哲杯广东工业大学ACM程序设计大赛--A-跳台阶

    链接:https://www.nowcoder.com/acm/contest/90/A 来源:牛客网 1.题目描述 小明在坐景驰科技研发的无人车到达了目的地. 景驰科技(JingChi.ai)是一家 ...

  10. Windows环境下的RTKPlot_Qt版本编译时遇到的问题和解决方法

    在使用了 RTKLIB开源包自带的 rtkplot.exe后,知道了它所具有的功能,就想着如何模仿它做出一个 demo.一开始看的是之前下载的 2.4.2版本的 RTKLIB,里面是使用 Delphi ...