开心消消乐游戏算法基础版

您所在的位置:网站首页 极品贴身兵王百度百科 开心消消乐游戏算法基础版

开心消消乐游戏算法基础版

2023-12-23 19:50| 来源: 网络整理| 查看: 265

消消乐游戏算法

我们经常看到各类的消除游戏,最近玩了两把消消乐,有想着来理解下其中的规则,市场上主流的是地图型的,几乎是无尽模式,各种消除特效,各种各样的过关方式,玩起来还是不错的,就是遇到比较难的关卡,要多试几次,运气非常好的时候就过了,不然卡死。 三消涉及到简单的算法如下所示,我会根据这个搭建一个简单的消除游戏:

随机生成地图的算法 遍历地图三个或三个以上连着的可以进行消除 除去元素,上面的元素补下来 涉及道具

由于篇幅关系,本章只会讲解生成地图的算法,后面我会附上写好的demo,希望大家能有收获。

一.随机生成地图的算法

首先游戏界面有各种各样的地图,需要满足以下几个条件:

随机生成一张地图,但是不能有三个或三个以上在横向和纵向同样。 用户在移动一步就能形成三个横向或者纵向可消除 1.1 先随机生成一个二维的数组 // 生成一个地图 9 * 9 function productMap(n) { const randomMap = [] for (let i = 0; i < n; i++) { for (let j = 0; j < n; j++) { const value = parseInt(Math.random() * 5) if (!randomMap[i]) { randomMap[i] = [] } randomMap[i].push(value) } } return randomMap } productMap(9)

上面的代码可以得到一个随机的 9*9 的二维数组 当我们生成一个二维数组后,会发现里面大概率会出现3个或3个以上在横向或者纵向连续且一样的值,这种数组是不满足消消乐的准则之一。

1.2 加入不能生成在横众方向连续3个或3个以上一样的值 1.3 最终代码 // x方向判断有没有连续两个同色 if (x > 1 && judgeSameColor(randomMap[y], value)) { value = getExceptRandom(value) } // y方向判断有没有连续两个同色 if ( y > 1 && judgeSameColor(getTwoArrColumnByIndex(randomMap, y), value) ) { value = getExceptRandom(value) } // 判断是否连续2个同色 function judgeSameColor(arr, value) { return arr.find( (item, index) => arr[index - 1] && item === value && arr[index - 1] === value ) } // 获取二维数组某一列的值 function getTwoArrColumnByIndex(arr, n) { return arr.map(item => item[n]) } 1.3 判断生成的二维数组是否是死地图

死地图条件:用户户移动相邻的一步,不能形成3个或3个以上连续的 【注意】:如果是死地图就需要重新生成地图

我们可以对相邻移动一步的情况进行穷举如下:

第一种:

注意 x 的位置,因为第二排有两个一样的连在一起,移动一步就能消除的情况有很多种方式,左右两边各有3种情况,找到一个这种,就不是死图了。

第二种:

第二种和第一种类似,只是放到了垂直方向

第三种:

根据上面这些穷举的情况,我们就可以来写判断是否是死图的代码了。

//判断是否是死图 function judgeCanRemoveByOneStep(map) { const resultStep = [] let len = map.length for (let y = 0; y < len; y++) { for (let x = 0; x < len; x++) { const currentValue = map[y][x] // 考虑横轴方向 if (x + 1 < len) { // 第一种情况 if (map[y][x] === map[y][x + 1]) { if (x - 2 >= 0) { if (map[y][x - 2] === currentValue) { resultStep.push({ y, x }) resultStep.push({ y, x: x + 1 }) resultStep.push({ y, x: x - 2 }) return resultStep } } if (x - 1 >= 0 && y - 1 >= 0 && map[y - 1][x - 1] === currentValue) { resultStep.push({ y, x }) resultStep.push({ y, x: x + 1 }) resultStep.push({ y: y - 1, x: x - 1 }) return resultStep } if (x + 2 < len && y - 1 > 0 && map[y - 1][x + 2] === currentValue) { resultStep.push({ y, x }) resultStep.push({ y, x: x + 1 }) resultStep.push({ y: y - 1, x: x + 2 }) return resultStep } if (x + 3 < len && map[y][x + 3] === currentValue) { resultStep.push({ y, x }) resultStep.push({ y, x: x + 1 }) resultStep.push({ y, x: x + 3 }) return resultStep } if (x + 2 < len && y + 1 < len && map[y + 1][x + 2] === currentValue) { resultStep.push({ y, x }) resultStep.push({ y, x: x + 1 }) resultStep.push({ y: y + 1, x: x + 2 }) return resultStep } if (x - 1 > 0 && y + 1 < len && map[y + 1][x - 1] === currentValue) { resultStep.push({ y, x }) resultStep.push({ y, x: x + 1 }) resultStep.push({ y: y + 1, x: x - 1 }) return resultStep } } if (x - 1 >= 0 && map[y][x] === map[y + 1][x - 1]) { if (y + 1 = 0 && map[y - 2][x] === currentValue) { resultStep.push({ y, x }) resultStep.push({ y: y + 1, x }) resultStep.push({ y: y - 2, x }) return resultStep } if (x + 1 < len && y - 1 > 0 && map[y - 1][x + 1] === currentValue) { resultStep.push({ y, x }) resultStep.push({ y: y - 1, x }) resultStep.push({ y: y - 1, x: x + 1 }) return resultStep } if (x + 1 < len && y + 2 < len && map[y + 2][x + 1] === currentValue) { resultStep.push({ y, x }) resultStep.push({ y: y + 1, x }) resultStep.push({ y: y + 2, x: x + 1 }) return resultStep } if (y + 3 < len && map[y + 3][x] === currentValue) { resultStep.push({ y, x }) resultStep.push({ y: y + 1, x }) resultStep.push({ y: y + 3, x: x }) return resultStep } if (x - 1 >= 0 && y + 2 < len && map[y + 2][x - 1] === currentValue) { resultStep.push({ y, x }) resultStep.push({ y: y + 1, x }) resultStep.push({ y: y + 2, x: x - 1 }) return resultStep } if (x - 1 >= 0 && y - 1 >= 0 && map[y - 1][x - 1] === currentValue) { resultStep.push({ y, x }) resultStep.push({ y: y + 1, x }) resultStep.push({ y: y - 1, x: x - 1 }) return resultStep } } } } } }

上面的代码穷举了以下情况,这个算法执行速度还是很快的,这个算法还记录了当前步骤,可以给用户提示。

总结

我们可以看下完整的代码,然后自己可以复制下面这段代码运行下,如果有问题,欢迎指出。完整代码如下:

// 生成一个地图 9 * 9 function productMap(n) { const randomMap = [] for (let y = 0; y < n; y++) { for (let x = 0; x < n; x++) { let value = parseInt(Math.random() * 5 + 1) if (!randomMap[y]) { randomMap[y] = [] } // x方向判断有没有连续两个同色 if (x > 1 && judgeSameColor(randomMap[y], value)) { value = getExceptRandom(value) } if ( y > 1 && judgeSameColor(getTwoArrColumnByIndex(randomMap, y), value) ) { value = getExceptRandom(value) } randomMap[y].push(value) } } return randomMap } function getExceptRandom(exceptNum) { let value = parseInt(Math.random() * 5 + 1) while (value === exceptNum) { value = parseInt(Math.random() * 5 + 1) } return value } /** * 获取二维数组某一列的值 * @param {Array} arr * @param {number} n */ function getTwoArrColumnByIndex(arr, n) { return arr.map(item => item[n]) } // 判断是否连续几个同色 function judgeSameColor(arr, value) { return arr.find( (item, index) => arr[index - 1] && item === value && arr[index - 1] === value ) } //判断是否是死图 function judgeCanRemoveByOneStep(map) { const resultStep = [] let len = map.length for (let y = 0; y < len; y++) { for (let x = 0; x < len; x++) { const currentValue = map[y][x] // 考虑横轴方向 if (x + 1 < len) { // 第一种情况 if (map[y][x] === map[y][x + 1]) { if (x - 2 >= 0) { if (map[y][x - 2] === currentValue) { resultStep.push({ y, x }) resultStep.push({ y, x: x + 1 }) resultStep.push({ y, x: x - 2 }) return resultStep } } if (x - 1 >= 0 && y - 1 >= 0 && map[y - 1][x - 1] === currentValue) { resultStep.push({ y, x }) resultStep.push({ y, x: x + 1 }) resultStep.push({ y: y - 1, x: x - 1 }) return resultStep } if (x + 2 < len && y - 1 > 0 && map[y - 1][x + 2] === currentValue) { resultStep.push({ y, x }) resultStep.push({ y, x: x + 1 }) resultStep.push({ y: y - 1, x: x + 2 }) return resultStep } if (x + 3 < len && map[y][x + 3] === currentValue) { resultStep.push({ y, x }) resultStep.push({ y, x: x + 1 }) resultStep.push({ y, x: x + 3 }) return resultStep } if (x + 2 < len && y + 1 < len && map[y + 1][x + 2] === currentValue) { resultStep.push({ y, x }) resultStep.push({ y, x: x + 1 }) resultStep.push({ y: y + 1, x: x + 2 }) return resultStep } if (x - 1 > 0 && y + 1 < len && map[y + 1][x - 1] === currentValue) { resultStep.push({ y, x }) resultStep.push({ y, x: x + 1 }) resultStep.push({ y: y + 1, x: x - 1 }) return resultStep } } if (x - 1 >= 0 && map[y][x] === map[y + 1][x - 1]) { if (y + 1 = 0 && map[y - 2][x] === currentValue) { resultStep.push({ y, x }) resultStep.push({ y: y + 1, x }) resultStep.push({ y: y - 2, x }) return resultStep } if (x + 1 < len && y - 1 > 0 && map[y - 1][x + 1] === currentValue) { resultStep.push({ y, x }) resultStep.push({ y: y - 1, x }) resultStep.push({ y: y - 1, x: x + 1 }) return resultStep } if (x + 1 < len && y + 2 < len && map[y + 2][x + 1] === currentValue) { resultStep.push({ y, x }) resultStep.push({ y: y + 1, x }) resultStep.push({ y: y + 2, x: x + 1 }) return resultStep } if (y + 3 < len && map[y + 3][x] === currentValue) { resultStep.push({ y, x }) resultStep.push({ y: y + 1, x }) resultStep.push({ y: y + 3, x: x }) return resultStep } if (x - 1 >= 0 && y + 2 < len && map[y + 2][x - 1] === currentValue) { resultStep.push({ y, x }) resultStep.push({ y: y + 1, x }) resultStep.push({ y: y + 2, x: x - 1 }) return resultStep } if (x - 1 >= 0 && y - 1 >= 0 && map[y - 1][x - 1] === currentValue) { resultStep.push({ y, x }) resultStep.push({ y: y + 1, x }) resultStep.push({ y: y - 1, x: x - 1 }) return resultStep } } } } } } function getRandomMap(n) { let map = productMap(n) if (!judgeCanRemoveByOneStep(map)) { map = productMap(n) } console.log(map) } getRandomMap(9)

以下是随机产生的地图

生成地图的方法我大概就将我理解的讲完了,后续有时间会具体分析其他的进行讲解,希望能给大家带来收获,以下是我的项目源码,后续会逐渐完善这个项目。谢谢观看。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3