Open ccforward opened 7 years ago
牛逼
厉害了我的哥
厉害了office哥,不过还有优化空间,棋子加上渐变、棋盘四周搞上跑马灯、出棋发出拔剑的声音基本就差不多了。
厉害了我的天
吊炸天!!
一个字,吊
好玩好玩
相当6,咳咳
厉害厉害,学习了!
献上膝盖
你好,仔细学习了一下你的源码,感觉你的思路好清晰。我自己实现的时候,我发觉对于斜线的分析还是有一些吃力,这种思维方面的训练有好的推荐吗?基础不是很好,这是我的弱项。还有一个小疑问就是这种判断的算法其实不是最优的对吗?比如说,我现在把棋盘扩大,其实我只是需要判断以落子的位置以最大可能为5的范围来判断就行,是吗?
@cangku 训练的话 建议你去做做 leetcode 上面的题目 绝大多数都可用js实现 顺带着去看看算法和数据结构,算法的思维还是个长时间慢慢的积累的东西
关于落子的判断范围,其实可以做到5次最少判断的,就是需要考虑更多的情况,尤其是在边界上的判断,这就需要更详细的算法了。因为实际情况下棋盘也不是很大,以现在的算法对性能影响微乎其微,所以也没做优化了。
@ccforward 好的,谢谢
厉害了我的哥,献上膝盖的同时,推荐其它vue的实例,http://www.17shulihua.com/archives/category/frontend-demo/vue-demo
66
PS:你的判断输赢逻辑有bug吧,[2][4],[3][3],[4][2],[5][1],[6][0]不会判断为赢
厉害,值得学习。
厉害了我的哥
demo挂了
厉害了我的哥!
可联机demo 4个文件拷到本地文件夹 然后npm install下载之后 再node socket.js 发现跑不起来啊 题主能说说怎么在本地跑吗 漏了什么 http://localhost:8888/ 打不开无法运行啊
@ccforward 但是访问 chess-connect.html 打开这个页面是一片空白啊...
@shacai
你看看源码 里面两个外部js文件的引用方式没有加 schema
你改成自己本地的服务器访问或者给两个外部的js 加上 http:
@ccforward 真的是 谢谢大神指点 原来是没有加 http: 难怪空白
大神很厉害啊!不过有 BUG:
厉害,思路好清晰...自己的五子棋拖了很久也没把联机功能加上,不过这里的五子棋是用canvas画的,当时还用了vue,然后用canvas画的话..基本也展现不出vue的优点了...
既然vue提供了mvvm的思路, 那么维护 一个vue数组就好,数据模型同步到view上面,
const map = [
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
];
socket.io 和 Vue.js 的五子棋
群里有个同学要做个五子棋的面试题,于是拿出了以前写的代码,但是有bug,所以重做了一遍。
代码只是做了简单实现,但是去面试足够了,顺便写篇文章对思路和代码详细解释下。
Demo & 源码
单机Demo
单机Demo源码 可联机Demo源码
单机版详解
1、棋盘布局
棋盘(正方形)是由一个个的方块构成,棋子可落在横竖线的交点处,棋盘基本都是这种样子
那就用一个空的
<i></i>
标签作为一个方块,伪元素before
after
作为横竖中心线形成一个十字然后一行的
<i>
标签排列下去,在需要换行处加一个<br>
标签, 伪代码如下,棋盘样式代码
2、坐标初始化
对于后面每一步下棋落子,都需要知道具体棋子的位置,所以要把棋盘所有位置都添加坐标
因为是二维棋盘,所以只需要用长和宽两个嵌套循环初始化每个位置的坐标信息,并存储在 pieces 对象中,而且可以初始化中间棋子的为黑棋子。
每个坐标对象的key为 (x,y) 坐标值, value 为当前坐标的棋子信息 (w:白棋 b:黑棋)
3.1、落子
这一步很简单,因为每一个坐标初始化了数据,所以加上监听
tick
方法即可3.2、悔棋
这算是额外的功能,加个状态
last
用来存储每一步的坐标, 想悔棋,直接把上一步坐标的数据置空即可。4、判断输赢
这是五子棋的核心,相对也最麻烦,每次落子(坐标 x,y ), 都需要从 横向、竖向、\向、/向 四个方向的其他棋子来判断结果。
横向 竖向
这两个方向很简单,从落子坐标的最左处和最上处挨个判断是否和当前落子的颜色是否相同,连续5个即为获胜。
\ 方向
先计算 \ 方向上从当前落子点往左上方后退x(最大5)个位置后的坐标(_x,_y)
然后从 (_x,_y) 开始往右下角方向用 for 循环逐一的比较每个坐标,循环长度为该方向最多棋子数(其实这里判断五次即可,用最多棋子数会有多余的超出棋盘的坐标进入循环中,小细节,暂时不修改)
/ 方向
/ 方向 相当于 \ 方向的镜像
同样计算出从当前落子点往左下方后退x (最大5) 个位置后的坐标, 然后往右上角方向逐一的比较,据该方向上是否有连续5个相同的棋子判断结果,这里涉及到镜像坐标的计算,算法有点绕,具体的判断可以参考代码
联机版
每个联机的用户都可以做主机,也都可以输入其他主机的 socket.id 来配对
这里 WebSocket 用了 socket.io 来做通信。
服务端
players 对象存储每个玩家的 sid和socket 对象映射关系
relations 对象存储每个玩家和对手的对应关系
这里只用了两个事件 link 和 tick
用于监听用户连接一个主机,连接成功后存储用户关系并通知双方连接成功
监听任意用户下棋落子事件,接收所有坐标和落子信息,并通知给对手
客户端
客户端监听 连接事件 和 落子事件(tick-back)
客户端发送 link事件 来连接主机
发送 tick事件 来同步落子和坐标信息 (为了方便没有添加websocket通信失败的处理)
整个客户端的代码都比较简单,直接贴出来了
最后
这是给群里的学弟提供面试题的demo,主要看思路,难免很多细节没处理,bug多点。。。