转珠游戏算法1-combo计算

  • 转珠游戏介绍
    • 智龙迷城
    • 最短路径?
    • 消珠问题简化
    • 算法实现
    • CODE (C++)
    • 结论

转珠游戏介绍

转珠游戏不同于传统三消游戏,传统三消是通过单次移动(移位)消除相连的珠子(以下简称COMBO).转珠游戏是通过移动珠子(可以理解单次操作多次移位)。在形成最终版面后一并计算结果,本系列主要探索消珠算法,最短路径算法,最优路径解等。

智龙迷城

这边用转珠游戏代表作,日本itunes app常年前三的国民游戏,智龙迷城为例

通过移动红色珠子 如箭头移动后,可以达到两次消除(combo)(可以脑里模拟一下)

最短路径?

这类游戏的算法已经非常成熟,基本是通过dfs或者djstra、抑或是floyd去求解的,(官方也有自动路径,但是只有三步,推测暴力算的)
市面上的APP用过几个都是无法求到最优解(版面最大COMBO),怀疑也是floyd或者暴力+剪枝(这一部分不确定,如果我错了先说声抱歉)
在求最短路径算法之前,我们需要一个模拟获取游戏结果的算法:

消珠问题简化

转珠游戏分两种,一种是通过移动一个珠子N次,另一种是移动”任意”珠子“N次(业界俗称CTW:即Change the world)达到版面最大COMBO

即:在N x M的二维数组中,任意交换两个相邻元素,N次交换后达到最大Combo(CTW),如果限定除开始位置外,每次移动均限制为上一次移动的对象,即转为本次问题,如下所示:
1 2 6 2 2 2
5 6 4 4 1 3
1 6 4 1 3 1
1 6 4 2 2 1
1 5 5 3 3 1
上述数组进行消珠后,返回7,并且数组变为

--------------next combo---------
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 4 0 0
0 0 0 1 1 0
1 2 6 2 2 0
注:
1.移动包括上下左右,不包括斜角,因为斜角移动可以通过:左右→上下,两次移动达到同样效果,这样可以简化问题。
2.消除条件为,同一直线(不包括斜角)有相同属性的元素>=n(n为消珠限制且默认为3),则进行消除,全部消除完毕后,剩余珠子会掉落下来,掉落的珠子如果形成消除的话会再进行消除。

算法实现

对于元素分组问题一般是用并查集或者dfs实现,因为本问题行列均不大于10,使用DFS即可。

然而本文用的bfs
大概的伪代码如下:

int 获取最大combo(matrix[][]):
for each col row:{
bfs队列.push(最后一个非0元素).
标记该位置已被访问
while(bfs不为空) {
向四个方向寻找元素相同解
if(存在相同解)则bfs.push,且标记该位置已被访问 } }
int result = 执行combo计算(标记数组[][])
执行消除(matrix[][])
执行模拟掉落(matrix[][])
执行递归(this.获取最大combo(matrix[][]))

CODE (C++)

// 点集合 包含是否存在加珠,珠子类型等
struct binary
{//珠类型int cata;//是否存在combo增加bool comboPlus = false;int i,j;binary(int x ,int i,int j) : cata(x), i(i), j(j){}
};
//单论消珠完成后进行掉落,每次迭代返回掉落后的数组
void finish(vector<vector<int>> &matrix)
{int sizeCol = matrix.size(), sizeRow = matrix[0].size();for (int i = sizeCol - 1; i >= 0; --i)for (int j = sizeRow - 1; j >= 0; --j)if(matrix[i][j]==0){int ii=i-1;while(ii>=0){if(matrix[ii][j]>0) {matrix[i][j] = matrix[ii][j];matrix[ii][j] = 0;break;}ii--;}}cout<<endl;cout<<"--------------next combo---------"<<endl;for(auto it:matrix){for(auto iit:it) cout<<iit<<" ";cout<<endl;}
}
// 联通图是否满足combo条件 返回布尔值并对原数组进行修改(修改处置为-1)
// @param res:combo数组,limit:最低消除珠数(默认3)
bool comboDFS(vector<vector<int>> &res,int limit=3){vector<vector<int>> remod(res);bool isCombo = false;//先横排扫描for(int i=0;i<remod.size();i++){for(int j=0;j<remod[0].size();j++){if(remod[i][j]>0){int count = 1 , jj = j+1;while(jj<remod[0].size() && remod[i][jj]>0){count++;jj++;}if(count>=limit){for(int k=0;k<count;k++) res[i][j+k] = -1;isCombo = true;}}}}//竖排扫描for(int j=0;j<remod[0].size();j++){for(int i=0;i<remod.size();i++){if(remod[i][j]>0){int count = 1 , ii = i+1;while(ii<remod.size() && remod[ii][j]>0){count++;ii++;}if(count>=limit){for(int k=0;k<count;k++) res[i+k][j] = -1;isCombo = true;}}}}return isCombo;
}
//消珠算法 @matrix:图像矩阵 @catag 最大种类(如 火+水,则catag=2)
//return 最大combo
int calCulate(vector<vector<int>> &matrix, int catag)
{int count = 0;int sizeCol = matrix.size(), sizeRow = matrix[0].size();//已访问记录,0=未访问vector<vector<int>> visited(sizeCol, vector<int>(sizeRow, 0));//连通集 bfs处理queue<binary> unionSet;//因为掉落原因 反向遍历for (int i = sizeCol - 1; i >= 0; --i)for (int j = sizeRow - 1; j >= 0; --j){//访问过了则跳过if(visited[i][j] || matrix[i][j] <= 0) continue;visited[i][j] = 1;// 未访问 添加到访问队列unionSet.push(binary{matrix[i][j],i,j});// 结果联通图vector<vector<int>> res(sizeCol, vector<int>(sizeRow, 0));res[i][j]=1;//bfswhile(!unionSet.empty()){auto top = unionSet.front();unionSet.pop();int ii = top.i;int jj = top.j;//向下if(ii+1<sizeCol && visited[ii+1][jj]==0)if(matrix[ii+1][jj] == top.cata){unionSet.push(binary{matrix[ii+1][jj],ii+1,jj});res[ii+1][jj]=1;visited[ii+1][jj]=1;}//向左if(jj-1>=0 && visited[ii][jj-1]==0)if(matrix[ii][jj-1] == top.cata){unionSet.push(binary{matrix[ii][jj-1],ii,jj-1});res[ii][jj-1]=1;visited[ii][jj-1]=1;}//向右if(jj+1<sizeRow && visited[ii][jj+1]==0)if(matrix[ii][jj+1] == top.cata){unionSet.push(binary{matrix[ii][jj+1],ii,jj+1});res[ii][jj+1]=1;visited[ii][jj+1]=1;}//向上if(ii-1>=0 && visited[ii-1][jj]==0)if(matrix[ii-1][jj] == top.cata){unionSet.push(binary{matrix[ii-1][jj],ii-1,jj});res[ii-1][jj]=1;visited[ii-1][jj]=1;}}//判断结果联通图是否满足combo条件,若满足修改原数组bool combo = comboDFS(res);if(combo){count++;for (int a = sizeCol - 1; a >= 0; --a)for (int b = sizeRow - 1; b >= 0; --b)if(res[a][b]<0)matrix[a][b] = 0;}}//如果发生了消除 则进行掉落处理 并且进行递归if(count>0){finish(matrix);count+=calCulate(matrix, catag);}return count;
}

结论

执行程序后返回:
--------------next combo---------
0 0 0 0 0 0
0 0 0 4 0 0
0 0 0 1 1 0
1 2 6 2 2 0
5 5 5 3 3 3

--------------next combo---------
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 4 0 0
1 2 6 2 2 0
7

通过模拟的方法我们先建立了获取模拟途径,之后我们会探讨最短步骤内获取最大COMBO、以及最大COMBO的最短路径等方法

转珠游戏-三消游戏-智龙迷城-神魔之塔-转珠算法的实现(一)-combo计算相关推荐

  1. PAD智龙迷城(puzzle and dragon)辅助转珠算法思路和python实现

    先说下效果,杂色情况下3秒之内消除20个以上圆珠. 1,首先是用安卓模拟器下载安装智龙迷城游戏. 2,固定模拟器的大小和位置,这样游戏启动的时候在屏幕上的位置就是固定的了.方便后续操作. 3,用pyt ...

  2. 《智龙迷城》新神暗的代行者解析

    卡牌数据: 名称 神魔的执行者・米达伦 属性 暗/光 类型 神/攻击 编号 643 稀有 ★7 升满级 需经 5000000 系列 大天使 基本属性 空间 60 Lv 1 HP 1346 Lv 1 攻 ...

  3. 蒸汽朋克与游戏的结合————《机械迷城》

    不说别的,先上图 <机械迷城(Machinarium)>是由捷克独立开发小组Amanita Design开发的一款冒险游戏,于2009年10月16日发行.本游戏在2009年独立游戏节上获得 ...

  4. python游戏-Python游戏

    #### 设计要点 #### 1.营造紧张的氛围. 输入大量的压力就需要在游戏过程中营造出紧张的氛围.首先,背景音乐上就要有由缓入急的感觉,并保持较强烈的节奏感.其次可以辅以时间条等要素,增加紧张的气 ...

  5. 原神迷城战线光界篇冰结试炼怎么过

    原神迷城战线光界篇冰结试炼怎么过,游戏也是上线了迷城战线的光界篇,那么本活动的冰结试炼又应该怎么过呢,相信还有些小伙伴不清楚.所以下面就为大家带来了冰结试炼的过法攻略! 原神迷城战线光界篇冰结试炼怎么 ...

  6. 《VALORANT》: 双塔迷城的诞生

    大家好!我是<VALORANT>的关卡设计总筹Chris Carney.今天,我要和传奇关卡设计师Sal Garrozzo一起来回答以下问题:双塔迷城的灵感从何而来,又是如何从松散.粗略的 ...

  7. 经典冒险游戏——机械迷城(Machinarium) 免安装简体中文版下载

    经典冒险游戏--机械迷城(Machinarium) 免安装简体中文版下载 机械迷城(Machinarium)--这是一个同事极力推荐的一个游戏,一玩之下,爱不释手啊!果然名付其实,很经典,很漂亮,非常 ...

  8. 机械迷城android分辨率,Android

    机械迷城是一款风靡PC的解谜类小游戏,现在这款游戏终于来到了Android平台上,也许此时大家正在期待像N.O.V.A.3这样的大作登陆Android平台,但机械迷城这样作品的到来绝对可以给Andro ...

  9. Game 迷城的国度 Next(类似暗黑的游戏)

    迷城的国度 Next:一款老游戏,很不错,很经典,很给力,类似暗黑的游戏. 1985年发售,日本PC游戏史上最受欢迎传说中的动作RPG<迷城的国度>.<迷城的国度>系列游戏的最 ...

最新文章

  1. BeX5报表开发中Excel格式修改的一个小问题
  2. 【实验】小型网络WLAN架构实战案例
  3. nodeMCU自动化控制实现空气质量管家
  4. 推荐算法炼丹笔记:序列化推荐算法SASRec
  5. javaweb 导出文件名乱码的问题解决方案
  6. python time用法
  7. win8打印机显示服务器脱机,打印机脱机状态 win8处理办法
  8. Cohort Analysis组群分析(1)
  9. MVP、EMC、CRM、IoT、边缘计算盒子、系统群控、数字化赋能、EMS、冷媒
  10. Android代码实现新年贺卡动画
  11. linux中的makefile文件
  12. swi prolog 和java_在Java和SWI Prolog之间连接 - java
  13. 十大高效学习方法整理
  14. Java中String,StringBuffer,StringBuilder基础知识
  15. android绘制圆角矩形
  16. 数据库期末复习题总汇
  17. Java工程师核心能力_java程序员的核心竞争力是什么?
  18. centos7装linux翻译软件
  19. Arduino Nano做NB-IoT透传项目
  20. 分布式协议与算法实战——拜占庭将军问题:有叛徒的情况下,如何才能达成共识?(笔记)

热门文章

  1. 如何用Qtdesigner删除工具栏的分隔符
  2. SQL SERVER自动备份失败的解决办法
  3. js向input的value赋值
  4. hdu1869六度分离(floyd)
  5. STM8时钟树及电源管理
  6. java连接redis不同的db,详解springboot配置多个redis连接
  7. VPS8703 微功率隔离电源驱动芯片 6.5-30V IN /30V/0.5A 功率管
  8. 焊缝标注vlx实用程序_常用焊缝符号及其标注方法
  9. Oracle内存分配中的子池(Subpool)--ORA-04031
  10. 程序猿的意义--纪念那些曾经辉煌过和即将辉煌的程序猿