无聊时做的一个简易的WEB版连连看

本文介绍了实现连连看游戏的算法思路,包括随机生成格子的方法及判断棋子能否消除的算法。利用图的最短路径思想,通过记录路径来确定两个棋子间是否可达。此外,还分享了使用jQuery进行开发的心得。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这几天写毕业论文写的实在烦闷,想起来有次面试问我连连看中判断是否相消的算法,那时根本不知道怎么回事,直接被鄙视,后来才知道原来是编程之美里面的题,后悔的一塌糊涂,突然萌生了写个连连看的想法。

这次写的连连看主要应该包括随机生成格子和判断是否相消两部分,其实还应该有一个是判断是死局,也就是判断是否存在可以相消的格子,这两天太懒了,下次在写。


首先是随机数的生成,每次生成两个随机位置放随机生成的图案一样的格子,要保证每次生成的两个位置是原来没有初始化过的。这里有个小的技巧,想象手里13张扑克牌,第一次抽出一张,将抽出的这张与最后一张交换,第二次从前12张抽出一张,与第12张交换,持续这个过程,就可以生成一个序列,保证每次抽出的牌都是以前没有抽到过的,随机生成格子就是基于这样一个小技巧。


然后就是判断相消的算法了,不知道的时候觉得很难,看了编程之美真是恍然大悟,还是基础不行,平时玩的太多,看书太少。这个算法类似与图的最短路径算法(忘了叫什么名字了,囧),那个算法中,第一次从源节点出发,找1步可以到的节点,得出一个集合,设为U1,从U1出发,找两步可以到达的节点,得出U2,类似这样下去,直到找到目标节点,或者遍历完整个图。这里也是类似的做法,只不过是将一步,两步改成可以直接到的,拐一个弯能到的,拐两个弯能到的,如果目标节点最后出现在前面的集合里面,就说明是可以相消的。

 

再后面就是具体的实现了,是用jquery写的,这里存储用的是Object数组,相当于一个Map,key是节点所在的位置,value是前一个节点的位置,相当于value所在的节点可以不拐弯直接连到value所在节点,这样,通过当前节点的key得到它的value,这个value就是前一个节点的key,这样向前找,就可以找到源节点,就得到了从源节点到目标节点的一个路径。

 

剩下的就是一些显示的问题了,比如一般的连连看,可以相消的情况,一般会有几条线画出源节点到目标节点的路径,由于是新学的jquery,不知道有没有画线的函数,就直接用几个div,把路径画出来了,要注意一下这些div要将position设置为absolute,不然会打乱原来的布局。其他的就是一些css和html的东西了,只是想做个简易的,用数字表示格子的种类。

 

写完了才发现原来csdn的博客好像不能传附件,那就不传了,本身就是新手,就不献丑了,欢迎高手拍砖。

好的,以下是一个简单的 HTML 连连看游戏示例代码,您可以在浏览器中打开它来玩。 ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>连连看</title> <style type="text/css"> .container { margin: 0 auto; width: 500px; height: 500px; background-color: #f9f9f9; border: 1px solid #ccc; position: relative; overflow: hidden; } .box { position: absolute; top: 0; left: 0; width: 50px; height: 50px; background-color: #fff; border: 1px solid #ccc; box-sizing: border-box; text-align: center; line-height: 50px; font-size: 20px; cursor: pointer; transition: all 0.3s ease-in-out; } .box:hover { background-color: #ccc; } .active { background-color: #f00; } </style> </head> <body> <div class="container"> </div> <script type="text/javascript"> var data = [ [1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20], [21, 22, 23, 24, 25] ]; var container = document.querySelector('.container'); var boxes = []; // 创建游戏盘面 for (var i = 0; i < data.length; i++) { for (var j = 0; j < data[i].length; j++) { var box = document.createElement('div'); box.className = 'box'; box.dataset.row = i; box.dataset.col = j; box.textContent = data[i][j]; container.appendChild(box); boxes.push(box); } } // 处理点击事件 var activeBox = null; function handleClick(e) { var box = e.target; if (box === activeBox) { box.classList.remove('active'); activeBox = null; return; } if (!activeBox) { box.classList.add('active'); activeBox = box; } else { if (isLinkable(activeBox, box)) { removeBoxes(activeBox, box); } else { activeBox.classList.remove('active'); box.classList.add('active'); activeBox = box; } } } // 判断两个格子是否可以连通 function isLinkable(box1, box2) { var row1 = parseInt(box1.dataset.row); var col1 = parseInt(box1.dataset.col); var row2 = parseInt(box2.dataset.row); var col2 = parseInt(box2.dataset.col); if (row1 === row2 && col1 === col2) { return false; } if (box1.textContent !== box2.textContent) { return false; } if (row1 === row2) { if (isRowLinkable(row1, col1, col2)) { return true; } } if (col1 === col2) { if (isColLinkable(col1, row1, row2)) { return true; } } if (isVLinkable(row1, col1, row2, col2)) { return true; } if (isVLinkable(row2, col2, row1, col1)) { return true; } return false; } // 判断两个格子在同一行是否可连通 function isRowLinkable(row, col1, col2) { if (col1 > col2) { var temp = col1; col1 = col2; col2 = temp; } for (var i = col1 + 1; i < col2; i++) { if (data[row][i] !== 0) { return false; } } return true; } // 判断两个格子在同一列是否可连通 function isColLinkable(col, row1, row2) { if (row1 > row2) { var temp = row1; row1 = row2; row2 = temp; } for (var i = row1 + 1; i < row2; i++) { if (data[i][col] !== 0) { return false; } } return true; } // 判断两个格子在竖直方向是否可连通 function isVLinkable(row1, col1, row2, col2) { var dx = col2 - col1; var dy = row2 - row1; var x = col1; var y = row1; if (dx !== 0 && dy !== 0) { return false; } if (dy > 0) { for (var i = 1; i <= dy; i++) { y = row1 + i; if (data[y][x] !== 0) { return false; } } } else { for (var i = -1; i >= dy; i--) { y = row1 + i; if (data[y][x] !== 0) { return false; } } } return true; } // 移除连通的两个格子 function removeBoxes(box1, box2) { var row1 = parseInt(box1.dataset.row); var col1 = parseInt(box1.dataset.col); var row2 = parseInt(box2.dataset.row); var col2 = parseInt(box2.dataset.col); data[row1][col1] = 0; data[row2][col2] = 0; box1.remove(); box2.remove(); activeBox = null; if (isGameOver()) { alert('游戏结束!'); } } // 判断游戏是否结束 function isGameOver() { for (var i = 0; i < data.length; i++) { for (var j = 0; j < data[i].length; j++) { if (data[i][j] !== 0) { return false; } } } return true; } // 绑定事件处理程序 for (var i = 0; i < boxes.length; i++) { boxes[i].addEventListener('click', handleClick); } </script> </body> </html> ``` 注意,这只是一个简单的示例,实际上,连连看游戏的复杂度很高,需要考虑很多因素,例如不同形状的图案、不同的连通规则、提示和动画效果等等。如果您想要制作更完整、更流畅的游戏,还需要进一步研究和开发。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值