最近无聊用java写了一个连连看,写之前看了一些资料,很多人用的递归算消除图块时候的路径,感觉很废效率,虽然比较省代码,但是递归如果用在非常大的拼图游戏那速度会慢死的。
所以我就写了N多代码实现一个分情况的比较快捷的寻路算法。
思想就是按下记录当前光标位置的方块ID,再按下先检测no corner(无拐角)是否可以消除,如果不可以消除再检测one corner,不行再two corner。而one corner和two corner也分了很多情况,这样用if-else块把检测过程分成了很多小块,一旦检测成功就跳出来,极大地提高了效率。在检测路径的过程中,同时记录下路径方便消除时画线用,如果检测失败就清除所有记录了的路径。
在绘制上,我把所有图块画在一张大图上,只在按下确定后消除了某块后才更新所有图块,这样省去了每次循环都要遍历GameArry去重绘所有图块的时间。
下面上开始的部分代码:
- public static final int row=10+2,col=12+2;
- public static final int rowL=10,colL=12;
- int Vx=0,Vy=0;//框架偏移量
- int Mx=0,My=Type.ScreenHeight-45;//Item偏移量
- int Bx=1,By=1;//光标位置
- Image gameImg[];
- int gameArry[][];
- int bufArry[];
- public void getRondomArry(){
- //得到数组○
- int rand=0;
- for(int i=0;i<bufArry.length;i+=4){
- for(int j=0;j<4;++j){
- bufArry[i+j]=rand;
- }
- ++rand;
- // rand=t.getRandomNumber(2,3);
- // if(i<bufArry.length-rand*2){
- // for (int j = 0; j < rand * 2; ++j) {
- // bufArry[i + j] = i;
- // }
- // i += rand;
- // }else if(rand==3&&i<bufArry.length-(rand-1)*2)
- // {
- // for(int j=0;j<(rand-1)*2;++j){
- // bufArry[i + j] = i;
- // }
- // i+=(rand-1);
- // }else
- // {
- // bufArry[i]=i;
- // bufArry[i+1]=i;
- // break;
- // }
- // System.out.println(i);
- }
- //打乱顺序
- int temp=0;
- int k=0;
- for(int i=0;i<bufArry.length-1;++i){
- temp=bufArry[i];
- k=t.getRandomNumber(i,bufArry.length-1);
- bufArry[i]=bufArry[k];
- bufArry[k]=temp;
- }
- //数组转换
- for(int i=0;i<gameArry.length;++i){
- for(int j=0;j<gameArry[i].length;++j){
- gameArry[i][j]=100;
- }
- }
- gameArry=t.Arry_1_to_2(bufArry,rowL,colL,gameArry);
- }
- public static int[][] Arry_1_to_2(int[] arry1,int row,int col,int arry2[][]){
- int bufrow=1,bufcol=1;
- for(int i=0;i<arry1.length;++i){
- arry2[bufrow][bufcol]=arry1[i];
- ++bufcol;
- if(bufcol==col+1){
- bufcol=1;
- ++bufrow;
- }
- }
- return arry2;
- }
- public static int [] Arry_2_to_1(int [][]arry2){
- int temparry[]=new int[(arry2.length-2)*(arry2[0].length-2)];
- int index=0;
- for(int i=1;i<arry2.length-1;++i){
- for(int j=1;j<arry2[i].length-1;++j){
- temparry[index]=arry2[i][j];
- index++;
- }
- }
- return temparry;
- }
为了方便检测路径,我将矩阵4个边全都设置为空,所以数组赋值时起始位置是1 ,1
按下确定键的逻辑处理:Bx和By是当前光标位置
- if(this.onceKeyPressed(ok)&&gameArry[Bx][By] != 100)
- {
- vv.removeAllElements();
- if(sign[0]==100){
- sign[0] = Bx;
- sign[1] = By;
- }
- if (this.isDeletAble()) { //消除 清空
- gameArry[sign[0]][sign[1]] = 100;
- gameArry[Bx][By] = 100;
- sign[0] = 100;
- sign[1] = 100;
- this.GetGameImage();//更新不变图
- delete=true;//画线
- kuai--;//减计数器
- if(timelogic<timer)//增加时间
- timelogic+=3;
- } else { //重新赋值 冲刷
- sign[0] = Bx;
- sign[1] = By;
- }
- }
检测路径:
虽然代码看上去很多,但是其实真正执行到的并不多,只是把情况细分了。
在这个游戏里,比递归算法节省了1秒左右
- //记下这个线
- public void getTT(int type,int tx,int ty){
- int tt[]=new int[3];//记录线 类型 坐标
- tt[0]=type;
- tt[1]=tx;
- tt[2]=ty;
- vv.addElement(tt);
- tt=null;
- }
- public boolean isDeletAble() {
- boolean ko=false; //完成否
- if (!(Bx == sign[0] && By == sign[1])) {//不是相同点
- if (getBB(0) == getBB(1)) {//第一条件
- //0 corner--------------------------------------------------
- // System.out.println("no corner");
- if (By == sign[1]) {
- ko = true;
- if (Bx < sign[0]) {
- this.getTT(1,Bx,By);
- for (int i = Bx + 1; i < sign[0]; ++i) {
- this.getTT(1,i,By);
- if (gameArry[i][By] != 100) {
- vv.removeAllElements();
- ko = false;
- break;
- }
- }
- } else {
- this.getTT(0,Bx,By);
- for (int i = sign[0] + 1; i < Bx; ++i) {
- this.getTT(0,i,By);
- if (gameArry[i][By] != 100) {
- vv.removeAllElements();
- ko = false;
- break;
- }
- }
- }
- } else if (Bx == sign[0]) {
- ko = true;
- if (By < sign[1]) {
- this.getTT(3,Bx,By);
- for (int i = By + 1; i < sign[1]; ++i) {
- this.getTT(3,Bx,i);
- if (gameArry[Bx][i] != 100) {
- vv.removeAllElements();
- ko = false;
- break;
- }
- }
- } else {
- this.getTT(2,Bx,By);
- for (int i = sign[1] + 1; i < By; ++i) {
- this.getTT(2,Bx,i);
- if (gameArry[Bx][i] != 100) {
- vv.removeAllElements();
- ko = false;
- break;
- }
- }
- }
- }
- //1 corner -----------------------------------------------
- if (!ko) { //如果没出来尝试one corner
- // System.out.println("one corner");
- vv.removeAllElements();//清空缓冲路径
- //分析两个点的位置关系
- //关系A
- if (Bx < sign[0] && By < sign[1]) {
- // System.out.println(" one corner A");
- if (gameArry[Bx][sign[1]] == 100) { //点1
- ko=true;
- this.getTT(1,Bx,sign[1]);
- this.getTT(2,Bx,sign[1]);
- for (int i = sign[1] - 1; i > By; --i) {
- this.getTT(2,Bx,i);
- if (gameArry[Bx][i] != 100) {
- vv.removeAllElements();
- ko = false;
- break;
- }
- }
- if (ko) {
- for (int i = Bx + 1; i < sign[0]; ++i) {
- this.getTT(1,i,sign[1]);
- if (gameArry[i][sign[1]] != 100) {
- ko = false;
- vv.removeAllElements();
- break;
- }
- }
- }
- }
- if (!ko) {
- if (gameArry[sign[0]][By] == 100) { //点2
- ko=true;
- this.getTT(3,sign[0],By);
- this.getTT(0,sign[0],By);
- for (int i = By + 1; i < sign[1]; ++i) {
- this.getTT(3,sign[0],i);
- if (gameArry[sign[0]][i] != 100) {
- ko = false;
- vv.removeAllElements();
- break;
- }
- }
- if (ko) {
- for (int i = sign[0] - 1; i > Bx; --i) {
- this.getTT(0,i,By);
- if (gameArry[i][By] != 100) {
- ko = false;
- vv.removeAllElements();
- break;
- }
- }
- }
- }
- }
- }
- //关系B
- else if(Bx>sign[0]&&By<sign[1]){
- // System.out.println(" one corner B");
- if(gameArry[Bx][sign[1]]==100){//点1
- ko=true;
- this.getTT(0,Bx,sign[1]);
- this.getTT(2,Bx,sign[1]);
- for(int i=Bx-1;i>sign[0];--i){
- this.getTT(0,i,sign[1]);
- if(gameArry[i][sign[1]]!=100){
- ko=false;
- vv.removeAllElements();
- break;
- }
- }
- if(ko){
- for(int i=sign[1]-1;i>By;--i){
- this.getTT(2,Bx,i);
- if(gameArry[Bx][i]!=100){
- ko=false;
- vv.removeAllElements();
- break;
- }
- }
- }
- }
- if(!ko){
- if(gameArry[sign[0]][By]==100){//点2
- ko=true;
- this.getTT(1,sign[0],By);
- this.getTT(3,sign[0],By);
- for(int i=sign[0]+1;i<Bx;++i){
- this.getTT(1,i,By);
- if(gameArry[i][By]!=100){
- vv.removeAllElements();
- ko=false;
- break;
- }
- }
- if(ko){
- for(int i =By+1;i<sign[1];++i){
- this.getTT(3,sign[0],i);
- if(gameArry[sign[0]][i]!=100){
- vv.removeAllElements();
- ko=false;
- break;
- }
- }
- }
- }
- }
- }
- //关系C
- else if(Bx>sign[0]&&By>sign[1]){
- // System.out.println(" one corner C");
- if(gameArry[sign[0]][By]==100){//点1
- ko=true;
- this.getTT(2,sign[0],By);
- this.getTT(1,sign[0],By);
- for(int i=By-1;i>sign[1];--i){
- this.getTT(2,sign[0],i);
- if(gameArry[sign[0]][i]!=100){
- vv.removeAllElements();
- ko=false;
- break;
- }
- }
- if(ko){
- for(int i=sign[0]+1;i<Bx;++i){
- this.getTT(1,i,By);
- if(gameArry[i][By]!=100){
- vv.removeAllElements();
- ko=false;
- break;
- }
- }
- }
- }
- if(!ko){
- if(gameArry[Bx][sign[1]]==100){//点2
- ko=true;
- this.getTT(0,Bx,sign[1]);
- this.getTT(3,Bx,sign[1]);
- for(int i=Bx-1;i>sign[0];--i){
- this.getTT(0,i,sign[1]);
- if(gameArry[i][sign[1]]!=100){
- vv.removeAllElements();
- ko=false;
- break;
- }
- }
- if(ko){
- for(int i=sign[1]+1;i<By;++i){
- this.getTT(3,Bx,i);
- if(gameArry[Bx][i]!=100){
- vv.removeAllElements();
- ko=false;
- break;
- }
- }
- }
- }
- }
- }
- //关系D
- else if(Bx<sign[0]&&By>sign[1]){
- // System.out.println(" one corner D");
- if(gameArry[sign[0]][By]==100){//点1
- ko=true;
- this.getTT(0,sign[0],By);
- this.getTT(2,sign[0],By);
- for(int i=By-1;i>sign[1];--i){
- this.getTT(2,sign[0],i);
- if(gameArry[sign[0]][i]!=100){
- vv.removeAllElements();
- ko=false;
- break;
- }
- }
- if(ko){
- for(int i=sign[0]-1;i>Bx;--i){
- this.getTT(0,i,By);
- if(gameArry[i][By]!=100){
- vv.removeAllElements();
- ko=false;
- break;
- }
- }
- }
- }
- if(!ko){
- if(gameArry[Bx][sign[1]]==100){//点2
- ko=true;
- this.getTT(1,Bx,sign[1]);
- this.getTT(3,Bx,sign[1]);
- for(int i = sign[1]+1;i<By;++i){
- this.getTT(3,Bx,i);
- if(gameArry[Bx][i]!=100){
- vv.removeAllElements();
- ko=false;
- break;
- }
- }
- if(ko){
- for(int i=Bx+1;i<sign[0];++i){
- this.getTT(1,i,sign[1]);
- if(gameArry[i][sign[1]]!=100){
- ko=false;
- vv.removeAllElements();
- break;
- }
- }
- }
- }
- }
- }
- }
- //two corner-----------------------------------------------
- //如果还是没出来再尝试two corner
- if(!ko){
- // System.out.println("two corner A");
- vv.removeAllElements();
- //先分析特殊情况 两点共线
- if(Bx==sign[0]){
- for(int i=Bx-1;i>=0;--i){//左遍历
- if(gameArry[i][By]==100&&gameArry[i][sign[1]]==100){
- this.getTT(1,i,By);
- this.getTT(1,i,sign[1]);
- this.getTT(3,i,By<sign[1]?By:sign[1]);
- this.getTT(2,i,By>sign[1]?By:sign[1]);
- ko=true;
- for(int j=(By<sign[1]?By:sign[1])+1;j<(By>sign[1]?By:sign[1]);++j){
- this.getTT(3,i,j);
- if(gameArry[i][j]!=100){
- ko=false;
- vv.removeAllElements();
- break;
- }
- }
- if(ko){
- for(int k=i+1;k<Bx;++k){
- this.getTT(1,k,By);
- this.getTT(1,k,sign[1]);
- if(gameArry[k][By]!=100||gameArry[k][sign[1]]!=100){
- vv.removeAllElements();
- ko=false;
- break;
- }
- }
- }
- if(ko){
- break;
- }
- }
- }
- if(!ko){
- for(int i=Bx+1;i<gameArry.length;++i){//右遍历
- if(gameArry[i][By]==100&&gameArry[i][sign[1]]==100){
- ko = true;
- this.getTT(0,i,By);
- this.getTT(0,i,sign[1]);
- this.getTT(3,i,By < sign[1] ? By : sign[1]);
- this.getTT(2,i,By > sign[1] ? By : sign[1]);
- for (int j = (By < sign[1] ? By : sign[1]) +1;j <(By > sign[1] ? By : sign[1]);++j) {
- this.getTT(3,i,j);
- if (gameArry[i][j] != 100) {
- vv.removeAllElements();
- ko = false;
- break;
- }
- }
- if (ko) {
- for (int k = i - 1; k > Bx; --k) {
- this.getTT(0,k,By);
- this.getTT(0,k,sign[1]);
- if (gameArry[k][By] != 100 ||gameArry[k][sign[1]] != 100) {
- ko = false;
- vv.removeAllElements();
- break;
- }
- }
- }
- if (ko) {
- break;
- }
- }
- }
- }
- }
- else if(By==sign[1]){
- for(int i=By-1;i>=0;--i){//上遍历
- if(gameArry[Bx][i]==100&&gameArry[sign[0]][i]==100){
- this.getTT(3,Bx,i);
- this.getTT(3,sign[0],i);
- this.getTT(1,Bx<sign[0]?Bx:sign[0],i);
- this.getTT(0,Bx>sign[0]?Bx:sign[0],i);
- ko=true;
- for(int j=(Bx<sign[0]?Bx:sign[0])+1;j<(Bx>sign[0]?Bx:sign[0]);++j){
- this.getTT(1,j,i);
- if(gameArry[j][i]!=100){
- vv.removeAllElements();
- ko=false;
- break;
- }
- }
- if(ko){
- for(int k=i+1;k<By;++k){
- this.getTT(3,Bx,k);
- this.getTT(3,sign[0],k);
- if(gameArry[Bx][k]!=100||gameArry[sign[0]][k]!=100){
- ko=false;
- vv.removeAllElements();
- break;
- }
- }
- }
- if(ko){
- break;
- }
- }
- }
- if(!ko){
- for(int i=By+1;i<gameArry[0].length;++i){//下遍历
- if(gameArry[Bx][i]==100&&gameArry[sign[0]][i]==100){
- ko = true;
- this.getTT(2,Bx,i);
- this.getTT(2,sign[0],i);
- this.getTT(1,Bx < sign[0] ? Bx : sign[0],i);
- this.getTT(0,Bx > sign[0] ? Bx : sign[0],i);
- for (int j = (Bx < sign[0] ? Bx : sign[0]) + 1;j < (Bx > sign[0] ? Bx : sign[0]); ++j) {
- this.getTT(1,j,i);
- if (gameArry[j][i] != 100) {
- vv.removeAllElements();
- ko = false;
- break;
- }
- }
- if (ko) {
- for (int k = i - 1; k > By; --k) {
- this.getTT(2,Bx,k);
- this.getTT(2,sign[0],k);
- if (gameArry[Bx][k] != 100 || gameArry[sign[0]][k] != 100) {
- vv.removeAllElements();
- ko = false;
- break;
- }
- }
- }
- if (ko) {
- break;
- }
- }
- }
- }
- }//特殊情况分析完毕 开始nb分析
- else {
- // System.out.println("two corner B");
- vv.removeAllElements();
- // System.out.println("you begin!");
- for (int i = Bx + 1; i < gameArry.length; ++i) { //右扫描
- if (gameArry[i][By] == 100 &&gameArry[i][sign[1]] == 100) {
- this.getTT(0,i,By);
- this.getTT(sign[0]<i?0:1,i,sign[1]);
- this.getTT(3,i,By < sign[1] ? By : sign[1]);
- this.getTT(2,i,By > sign[1] ? By : sign[1]);
- ko = true;
- for (int j = (By < sign[1] ? By : sign[1]) + 1;j < (By > sign[1] ? By : sign[1]); ++j) {
- this.getTT(3,i,j);
- if (gameArry[i][j] != 100) {
- ko = false;
- vv.removeAllElements();
- break;
- }
- }
- if (ko) {
- for (int k = i - 1; k > Bx; --k) {
- this.getTT(0,k,By);
- if (gameArry[k][By] != 100) {
- ko = false;
- vv.removeAllElements();
- break;
- }
- }
- }
- if (ko) {
- for (int k = (i > sign[0] ? i : sign[0]) -1;k > (i < sign[0] ? i : sign[0]);--k) {
- this.getTT(0,k,sign[1]);
- if (gameArry[k][sign[1]] != 100) {
- ko = false;
- vv.removeAllElements();
- break;
- }
- }
- }
- }
- if (ko)
- break;
- }
- if (!ko) {
- // System.out.println("zuo begin!");
- for (int i = Bx - 1; i >= 0; --i) { //左扫描
- if (gameArry[i][By] == 100 &&gameArry[i][sign[1]] == 100) {
- ko = true;
- this.getTT(1,i,By);
- this.getTT(sign[0]>i?1:0,i,sign[1]);
- this.getTT(3,i,By < sign[1] ? By : sign[1]);
- this.getTT(2,i,By > sign[1] ? By : sign[1]);
- for (int j = (By < sign[1] ? By : sign[1]) +1;j <(By > sign[1] ? By : sign[1]);++j) {
- this.getTT(3,i,j);
- if (gameArry[i][j] != 100) {
- ko = false;
- vv.removeAllElements();
- break;
- }
- }
- if (ko) {
- for (int k = i + 1; k < Bx; ++k) {
- this.getTT(1,k,By);
- if (gameArry[k][By] != 100) {
- ko = false;
- vv.removeAllElements();
- break;
- }
- }
- }
- if (ko) {
- for (int k = (i < sign[0] ? i : sign[0]) +1;k < (i > sign[0] ? i : sign[0]);++k) {
- this.getTT(1,k,sign[1]);
- if (gameArry[k][sign[1]] != 100) {
- ko = false;
- vv.removeAllElements();
- break;
- }
- }
- }
- }
- if (ko)
- break;
- }
- }
- if(!ko){//上扫描
- // System.out.println("shang begin!");
- for(int i = By-1;i>=0;--i){
- if(gameArry[Bx][i]==100&&gameArry[sign[0]][i]==100){
- ko=true;
- this.getTT(3,Bx,i);
- this.getTT(sign[1]>i?3:2,sign[0],i);
- this.getTT(1,Bx<sign[0]?Bx:sign[0],i);
- this.getTT(0,Bx>sign[0]?Bx:sign[0],i);
- for(int j= (Bx<sign[0]?Bx:sign[0])+1;j<(Bx>sign[0]?Bx:sign[0]);++j){
- this.getTT(1,j,i);
- if(gameArry[j][i]!=100){
- vv.removeAllElements();
- ko=false;
- break;
- }
- }
- if(ko){
- for(int k= i+1;k<By;++k){
- this.getTT(3,Bx,k);
- if(gameArry[Bx][k]!=100){
- ko=false;
- vv.removeAllElements();
- break;
- }
- }
- }
- if(ko){
- for(int k= (i<sign[1]?i:sign[1])+1;k<(i>sign[1]?i:sign[1]);++k){
- this.getTT(3,sign[0],k);
- if(gameArry[sign[0]][k]!=100){
- vv.removeAllElements();
- ko=false;
- break;
- }
- }
- }
- }
- if(ko)
- break;
- }
- }
- if(!ko){//下扫描
- // System.out.println("xia begin!");
- for(int i=By+1;i<gameArry[0].length;++i){
- if(gameArry[Bx][i]==100&&gameArry[sign[0]][i]==100){
- ko=true;
- this.getTT(2,Bx,i);
- this.getTT(sign[1]<i?2:3,sign[0],i);
- this.getTT(1,Bx<sign[0]?Bx:sign[0],i);
- this.getTT(0,Bx>sign[0]?Bx:sign[0],i);
- for(int j= (Bx<sign[0]?Bx:sign[0])+1;j<(Bx>sign[0]?Bx:sign[0]);++j){
- this.getTT(1,j,i);
- if(gameArry[j][i]!=100){
- ko=false;
- vv.removeAllElements();
- break;
- }
- }
- if(ko){
- for(int k=i-1;k>By;--k){
- this.getTT(2,Bx,k);
- if(gameArry[Bx][k]!=100){
- vv.removeAllElements();
- ko=false;
- break;
- }
- }
- }
- if(ko){
- for(int k= (i>sign[1]?i:sign[1])-1;k>(i<sign[1]?i:sign[1]);--k){
- this.getTT(2,sign[0],k);
- if(gameArry[sign[0]][k]!=100){
- ko=false;
- vv.removeAllElements();
- break;
- }
- }
- }
- }
- if(ko)
- break;
- }
- }
- }
- }
- }
- }
- //System.out.println("----------");
- return ko;
- }